diff --git a/mastodon/src/main/AndroidManifest.xml b/mastodon/src/main/AndroidManifest.xml index 69e170179..d7c114c33 100644 --- a/mastodon/src/main/AndroidManifest.xml +++ b/mastodon/src/main/AndroidManifest.xml @@ -62,7 +62,8 @@ - + diff --git a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java index 38893027f..a862c61bd 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java @@ -3,7 +3,6 @@ package org.joinmastodon.android; import android.app.Fragment; import android.content.ClipData; import android.content.Intent; -import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; @@ -12,6 +11,7 @@ import android.widget.Toast; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.ComposeFragment; +import org.joinmastodon.android.ui.AccountSwitcherSheet; import org.joinmastodon.android.ui.utils.UiUtils; import org.jsoup.internal.StringUtil; @@ -28,18 +28,25 @@ public class ExternalShareActivity extends FragmentStackActivity{ UiUtils.setUserPreferredTheme(this); super.onCreate(savedInstanceState); if(savedInstanceState==null){ + + String text = getIntent().getStringExtra(Intent.EXTRA_TEXT); + boolean isMastodonURL = UiUtils.looksLikeMastodonUrl(text); + List sessions=AccountSessionManager.getInstance().getLoggedInAccounts(); if(sessions.isEmpty()){ Toast.makeText(this, R.string.err_not_logged_in, Toast.LENGTH_SHORT).show(); finish(); - }else if(sessions.size()==1){ + }else if(sessions.size()==1 && !isMastodonURL){ openComposeFragment(sessions.get(0).getID()); }else{ - getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000)); - UiUtils.pickAccount(this, null, R.string.choose_account, 0, - session -> openComposeFragment(session.getID()), - b -> b.setOnCancelListener(d -> finish()) - ); + new AccountSwitcherSheet(this, null, true, isMastodonURL, (accountId, open) -> { + AccountSessionManager.getInstance().setLastActiveAccountID(accountId); + if (open) { + UiUtils.openURL(this, AccountSessionManager.getInstance().getLastActiveAccountID(), text, false); + } else { + openComposeFragment(accountId); + } + }).show(); } } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeFragment.java index a260c2111..ae436b4a3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeFragment.java @@ -2,6 +2,7 @@ package org.joinmastodon.android.fragments; import android.app.Fragment; import android.app.NotificationManager; +import android.content.Intent; import android.graphics.Outline; import android.os.Build; import android.os.Bundle; @@ -16,7 +17,13 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; +import androidx.annotation.IdRes; +import androidx.annotation.Nullable; + +import com.squareup.otto.Subscribe; + import org.joinmastodon.android.E; +import org.joinmastodon.android.MainActivity; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.notifications.GetNotifications; import org.joinmastodon.android.api.session.AccountSession; @@ -37,11 +44,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; -import androidx.annotation.IdRes; -import androidx.annotation.Nullable; - -import com.squareup.otto.Subscribe; - import me.grishka.appkit.FragmentStackActivity; import me.grishka.appkit.api.Callback; import me.grishka.appkit.api.ErrorResponse; @@ -224,6 +226,13 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene throw new IllegalArgumentException(); } + public void setCurrentTab(@IdRes int tab){ + if(tab==currentTab) + return; + tabBar.selectTab(tab); + onTabSelected(tab); + } + private void onTabSelected(@IdRes int tab){ Fragment newFragment=fragmentForTab(tab); if(tab==currentTab){ @@ -265,7 +274,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene for(AccountSession session:AccountSessionManager.getInstance().getLoggedInAccounts()){ options.add(session.self.displayName+"\n("+session.self.username+"@"+session.domain+")"); } - new AccountSwitcherSheet(getActivity()).show(); + new AccountSwitcherSheet(getActivity(), this).show(); return true; } return false; @@ -338,4 +347,8 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene public void onAllNotificationsSeen(AllNotificationsSeenEvent allNotificationsSeenEvent) { setNotificationBadge(false); } + + public String getAccountID() { + return accountID; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java index 6e1d81a99..780052ec3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java @@ -92,6 +92,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.viewpager2.widget.ViewPager2; + import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; import me.grishka.appkit.api.ErrorResponse; diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/AccountActivationFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/AccountActivationFragment.java index 92eb026ad..b1a77e9c0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/AccountActivationFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/AccountActivationFragment.java @@ -89,13 +89,6 @@ public class AccountActivationFragment extends ToolbarFragment{ return !UiUtils.isDarkTheme(); } - @Override - public void onViewCreated(View view, Bundle savedInstanceState){ - super.onViewCreated(view, savedInstanceState); - setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background)); - view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background)); - } - @Override protected void onUpdateToolbar(){ super.onUpdateToolbar(); @@ -110,7 +103,7 @@ public class AccountActivationFragment extends ToolbarFragment{ @Override public void onToolbarNavigationClick(){ - new AccountSwitcherSheet(getActivity()).show(); + new AccountSwitcherSheet(getActivity(), null).show(); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java b/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java index 42e373f61..04f44dc9b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/AccountSwitcherSheet.java @@ -2,8 +2,8 @@ package org.joinmastodon.android.ui; import android.annotation.SuppressLint; import android.app.Activity; +import android.app.ProgressDialog; import android.content.Intent; -import android.content.res.ColorStateList; import android.graphics.drawable.Animatable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -14,7 +14,7 @@ import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.PopupMenu; +import android.widget.RadioButton; import android.widget.TextView; import org.joinmastodon.android.GlobalUserPreferences; @@ -23,13 +23,21 @@ import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.fragments.HomeFragment; +import org.joinmastodon.android.fragments.SplashFragment; import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment; import org.joinmastodon.android.ui.utils.UiUtils; +import org.joinmastodon.android.ui.views.CheckableRelativeLayout; +import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; import java.util.stream.Collectors; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.recyclerview.widget.LinearLayoutManager; import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; @@ -49,14 +57,25 @@ import me.grishka.appkit.views.UsableRecyclerView; public class AccountSwitcherSheet extends BottomSheet{ private final Activity activity; + private final HomeFragment fragment; + private final BiConsumer onClick; + private final boolean externalShare, openInApp; private UsableRecyclerView list; private List accounts; private ListImageLoaderWrapper imgLoader; - public AccountSwitcherSheet(@NonNull Activity activity){ + public AccountSwitcherSheet(@NonNull Activity activity, @Nullable HomeFragment fragment){ + this(activity, fragment, false, false, null); + } + + public AccountSwitcherSheet(@NonNull Activity activity, @Nullable HomeFragment fragment, boolean externalShare, boolean openInApp, BiConsumer onClick){ super(activity); this.activity=activity; - + this.fragment=fragment; + this.externalShare = externalShare; + this.openInApp = openInApp; + this.onClick = onClick; + accounts=AccountSessionManager.getInstance().getLoggedInAccounts().stream().map(WrappedAccount::new).collect(Collectors.toList()); list=new UsableRecyclerView(activity); @@ -67,41 +86,59 @@ public class AccountSwitcherSheet extends BottomSheet{ MergeRecyclerAdapter adapter=new MergeRecyclerAdapter(); View handle=new View(activity); handle.setBackgroundResource(R.drawable.bg_bottom_sheet_handle); + handle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(36))); + adapter.addAdapter(new SingleViewRecyclerAdapter(handle)); + + if (externalShare) { + FrameLayout shareHeading = new FrameLayout(activity); + activity.getLayoutInflater().inflate(R.layout.item_external_share_heading, shareHeading); + ((TextView) shareHeading.findViewById(R.id.title)).setText(openInApp + ? R.string.sk_external_share_or_open_title + : R.string.sk_external_share_title); + adapter.addAdapter(new SingleViewRecyclerAdapter(shareHeading)); + + setOnDismissListener((d) -> activity.finish()); + } + adapter.addAdapter(new AccountsAdapter()); - AccountViewHolder holder=new AccountViewHolder(); - holder.more.setVisibility(View.GONE); - holder.currentIcon.setVisibility(View.GONE); - holder.name.setText(R.string.add_account); - holder.avatar.setScaleType(ImageView.ScaleType.CENTER); - holder.avatar.setImageResource(R.drawable.ic_fluent_add_circle_24_filled); - holder.avatar.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(activity, android.R.attr.textColorPrimary))); - adapter.addAdapter(new ClickableSingleViewRecyclerAdapter(holder.itemView, ()->{ - Nav.go(activity, CustomWelcomeFragment.class, null); - dismiss(); - })); + + if (!externalShare) { + adapter.addAdapter(new ClickableSingleViewRecyclerAdapter(makeSimpleListItem(R.string.add_account, R.drawable.ic_add_24px), () -> { + Nav.go(activity, CustomWelcomeFragment.class, null); + dismiss(); + })); + // disabled in megalodon +// adapter.addAdapter(new ClickableSingleViewRecyclerAdapter(makeSimpleListItem(R.string.log_out_all_accounts, R.drawable.ic_fluent_person_arrow_right_24_filled), this::confirmLogOutAll)); + } list.setAdapter(adapter); - DividerItemDecoration divider=new DividerItemDecoration(activity, R.attr.colorPollVoted, .5f, 72, 16, DividerItemDecoration.NOT_FIRST); - divider.setDrawBelowLastItem(true); - list.addItemDecoration(divider); FrameLayout content=new FrameLayout(activity); content.setBackgroundResource(R.drawable.bg_bottom_sheet); content.addView(list); setContentView(content); - setNavigationBarBackground(new ColorDrawable(UiUtils.getThemeColor(activity, R.attr.colorWindowBackground)), !UiUtils.isDarkTheme()); + setNavigationBarBackground(new ColorDrawable(UiUtils.alphaBlendColors(UiUtils.getThemeColor(activity, R.attr.colorM3Surface), + UiUtils.getThemeColor(activity, R.attr.colorM3Primary), 0.05f)), !UiUtils.isDarkTheme()); } private void confirmLogOut(String accountID){ + AccountSession session=AccountSessionManager.getInstance().getAccount(accountID); new M3AlertDialogBuilder(activity) - .setTitle(R.string.log_out) - .setMessage(R.string.confirm_log_out) + .setMessage(activity.getString(R.string.confirm_log_out, session.getFullUsername())) .setPositiveButton(R.string.log_out, (dialog, which) -> logOut(accountID)) .setNegativeButton(R.string.cancel, null) .show(); } + private void confirmLogOutAll(){ + new M3AlertDialogBuilder(activity) + .setMessage(R.string.confirm_log_out_all_accounts) + .setPositiveButton(R.string.log_out, (dialog, which) -> logOutAll()) + .setNegativeButton(R.string.cancel, null) + .show(); + } + private void logOut(String accountID){ AccountSession session=AccountSessionManager.getInstance().getAccount(accountID); new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken) @@ -120,6 +157,41 @@ public class AccountSwitcherSheet extends BottomSheet{ .exec(accountID); } + private void logOutAll(){ + final ProgressDialog progress=new ProgressDialog(activity); + progress.setMessage(activity.getString(R.string.loading)); + progress.setCancelable(false); + progress.show(); + ArrayList sessions=new ArrayList<>(AccountSessionManager.getInstance().getLoggedInAccounts()); + for(AccountSession session:sessions){ + new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken) + .setCallback(new Callback<>(){ + @Override + public void onSuccess(Object result){ + AccountSessionManager.getInstance().removeAccount(session.getID()); + sessions.remove(session); + if(sessions.isEmpty()){ + progress.dismiss(); + Nav.goClearingStack(activity, SplashFragment.class, null); + dismiss(); + } + } + + @Override + public void onError(ErrorResponse error){ + AccountSessionManager.getInstance().removeAccount(session.getID()); + sessions.remove(session); + if(sessions.isEmpty()){ + progress.dismiss(); + Nav.goClearingStack(activity, SplashFragment.class, null); + dismiss(); + } + } + }) + .exec(session.getID()); + } + } + private void onLoggedOut(String accountID){ AccountSessionManager.getInstance().removeAccount(accountID); dismiss(); @@ -140,6 +212,13 @@ public class AccountSwitcherSheet extends BottomSheet{ } } + private View makeSimpleListItem(@StringRes int title, @DrawableRes int icon){ + TextView tv=(TextView) activity.getLayoutInflater().inflate(R.layout.item_text_with_icon, list, false); + tv.setText(title); + tv.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, 0, 0, 0); + return tv; + } + private class AccountsAdapter extends UsableRecyclerView.Adapter implements ImageLoaderRecyclerAdapter{ public AccountsAdapter(){ super(imgLoader); @@ -173,45 +252,37 @@ public class AccountSwitcherSheet extends BottomSheet{ } } - private class AccountViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{ - private final TextView name; + private class AccountViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable, UsableRecyclerView.LongClickable{ + private final TextView name, username; private final ImageView avatar; - private final ImageButton more; - private final View currentIcon; - private final PopupMenu menu; + private final CheckableRelativeLayout view; + private final View radioButton, extraBtnWrap; + private final ImageButton extraBtn; public AccountViewHolder(){ super(activity, R.layout.item_account_switcher, list); name=findViewById(R.id.name); + username=findViewById(R.id.username); + radioButton=findViewById(R.id.radiobtn); + radioButton.setBackground(new RadioButton(activity).getButtonDrawable()); avatar=findViewById(R.id.avatar); - more=findViewById(R.id.more); - currentIcon=findViewById(R.id.current); - - avatar.setOutlineProvider(OutlineProviders.roundedRect(12)); + avatar.setOutlineProvider(OutlineProviders.roundedRect(OutlineProviders.RADIUS_MEDIUM)); avatar.setClipToOutline(true); - - menu=new PopupMenu(activity, more); - menu.inflate(R.menu.account_switcher); - menu.setOnMenuItemClickListener(item1 -> { - confirmLogOut(item.getID()); - return true; - }); - more.setOnClickListener(v->menu.show()); + view=(CheckableRelativeLayout) itemView; + extraBtnWrap = findViewById(R.id.extra_btn_wrap); + extraBtn = findViewById(R.id.extra_btn); + extraBtn.setOnClickListener(this::onExtraBtnClick); } @SuppressLint("SetTextI18n") @Override public void onBind(AccountSession item){ - name.setText("@"+item.self.username+"@"+item.domain); - if(AccountSessionManager.getInstance().getLastActiveAccountID().equals(item.getID())){ - more.setVisibility(View.GONE); - currentIcon.setVisibility(View.VISIBLE); - }else{ - more.setVisibility(View.VISIBLE); - currentIcon.setVisibility(View.GONE); - } - menu.getMenu().findItem(R.id.log_out).setTitle(activity.getString(R.string.log_out_account, "@"+item.self.username)); - UiUtils.enablePopupMenuIcons(activity, menu); + name.setText(item.self.displayName); + username.setText(item.getFullUsername()); + view.setChecked(AccountSessionManager.getInstance().getLastActiveAccountID().equals(item.getID())); + radioButton.setVisibility(externalShare ? View.GONE : View.VISIBLE); + extraBtnWrap.setVisibility(externalShare && openInApp ? View.VISIBLE : View.GONE); + if (externalShare) view.setCheckable(false); } @Override @@ -226,12 +297,32 @@ public class AccountSwitcherSheet extends BottomSheet{ setImage(index, null); } + private void onExtraBtnClick(View view) { + setOnDismissListener(null); + dismiss(); + onClick.accept(item.getID(), true); + } + @Override public void onClick(){ + setOnDismissListener(null); + if (onClick != null) { + dismiss(); + onClick.accept(item.getID(), false); + return; + } + AccountSessionManager.getInstance().setLastActiveAccountID(item.getID()); activity.finish(); activity.startActivity(new Intent(activity, MainActivity.class)); } + + @Override + public boolean onLongClick(){ + if (externalShare) return false; + confirmLogOut(item.getID()); + return true; + } } private static class WrappedAccount{ diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/OutlineProviders.java b/mastodon/src/main/java/org/joinmastodon/android/ui/OutlineProviders.java index 921598225..81f05df36 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/OutlineProviders.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/OutlineProviders.java @@ -8,7 +8,15 @@ import android.view.ViewOutlineProvider; import me.grishka.appkit.utils.V; public class OutlineProviders{ - private static SparseArray roundedRects=new SparseArray<>(); + private static final SparseArray roundedRects=new SparseArray<>(); + private static final SparseArray topRoundedRects=new SparseArray<>(); + private static final SparseArray endRoundedRects=new SparseArray<>(); + + public static final int RADIUS_XSMALL=4; + public static final int RADIUS_SMALL=8; + public static final int RADIUS_MEDIUM=12; + public static final int RADIUS_LARGE=16; + public static final int RADIUS_XLARGE=28; private OutlineProviders(){ //no instance @@ -21,6 +29,12 @@ public class OutlineProviders{ outline.setAlpha(view.getAlpha()); } }; + public static final ViewOutlineProvider OVAL=new ViewOutlineProvider(){ + @Override + public void getOutline(View view, Outline outline){ + outline.setOval(0, 0, view.getWidth(), view.getHeight()); + } + }; public static ViewOutlineProvider roundedRect(int dp){ ViewOutlineProvider provider=roundedRects.get(dp); @@ -31,6 +45,24 @@ public class OutlineProviders{ return provider; } + public static ViewOutlineProvider topRoundedRect(int dp){ + ViewOutlineProvider provider=topRoundedRects.get(dp); + if(provider!=null) + return provider; + provider=new TopRoundRectOutlineProvider(V.dp(dp)); + topRoundedRects.put(dp, provider); + return provider; + } + + public static ViewOutlineProvider endRoundedRect(int dp){ + ViewOutlineProvider provider=endRoundedRects.get(dp); + if(provider!=null) + return provider; + provider=new EndRoundRectOutlineProvider(V.dp(dp)); + endRoundedRects.put(dp, provider); + return provider; + } + private static class RoundRectOutlineProvider extends ViewOutlineProvider{ private final int radius; @@ -43,4 +75,34 @@ public class OutlineProviders{ outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius); } } + + private static class TopRoundRectOutlineProvider extends ViewOutlineProvider{ + private final int radius; + + private TopRoundRectOutlineProvider(int radius){ + this.radius=radius; + } + + @Override + public void getOutline(View view, Outline outline){ + outline.setRoundRect(0, 0, view.getWidth(), view.getHeight()+radius, radius); + } + } + + private static class EndRoundRectOutlineProvider extends ViewOutlineProvider{ + private final int radius; + + private EndRoundRectOutlineProvider(int radius){ + this.radius=radius; + } + + @Override + public void getOutline(View view, Outline outline){ + if(view.getLayoutDirection()==View.LAYOUT_DIRECTION_RTL){ + outline.setRoundRect(-radius, 0, view.getWidth(), view.getHeight(), radius); + }else{ + outline.setRoundRect(0, 0, view.getWidth()+radius, view.getHeight(), radius); + } + } + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/views/CheckableRelativeLayout.java b/mastodon/src/main/java/org/joinmastodon/android/ui/views/CheckableRelativeLayout.java new file mode 100644 index 000000000..b5f4d5b36 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/views/CheckableRelativeLayout.java @@ -0,0 +1,62 @@ +package org.joinmastodon.android.ui.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.Checkable; +import android.widget.RelativeLayout; + +public class CheckableRelativeLayout extends RelativeLayout implements Checkable{ + private boolean checked, checkable = true; + private static final int[] CHECKED_STATE_SET = { + android.R.attr.state_checked + }; + + public CheckableRelativeLayout(Context context){ + this(context, null); + } + + public CheckableRelativeLayout(Context context, AttributeSet attrs){ + this(context, attrs, 0); + } + + public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle){ + super(context, attrs, defStyle); + } + + @Override + public void setChecked(boolean checked){ + this.checked=checked; + refreshDrawableState(); + } + + public void setCheckable(boolean checkable) { + this.checkable = checkable; + } + + @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; + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info){ + super.onInitializeAccessibilityNodeInfo(info); + info.setCheckable(checkable); + info.setChecked(checked); + } +} diff --git a/mastodon/src/main/res/drawable/ic_fluent_share_28_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_share_28_regular.xml new file mode 100644 index 000000000..6fa0d5917 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_share_28_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/layout/item_account_switcher.xml b/mastodon/src/main/res/layout/item_account_switcher.xml index 1cffbf7af..f4e5134b6 100644 --- a/mastodon/src/main/res/layout/item_account_switcher.xml +++ b/mastodon/src/main/res/layout/item_account_switcher.xml @@ -1,44 +1,81 @@ - - - + android:id="@+id/radiobtn" + android:layout_width="32dp" + android:layout_height="32dp" + android:layout_centerInParent="true" + android:layout_toStartOf="@+id/extra_btn_wrap" + android:layout_alignWithParentIfMissing="true" + android:layout_marginEnd="20dp" + android:layout_marginStart="12dp" + android:duplicateParentState="true" /> - + + + + - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/item_external_share_heading.xml b/mastodon/src/main/res/layout/item_external_share_heading.xml new file mode 100644 index 000000000..b5d4a5a15 --- /dev/null +++ b/mastodon/src/main/res/layout/item_external_share_heading.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/item_text_with_icon.xml b/mastodon/src/main/res/layout/item_text_with_icon.xml new file mode 100644 index 000000000..01c27abab --- /dev/null +++ b/mastodon/src/main/res/layout/item_text_with_icon.xml @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/mastodon/src/main/res/values/strings.xml b/mastodon/src/main/res/values/strings.xml index 725c0b350..997d3014c 100644 --- a/mastodon/src/main/res/values/strings.xml +++ b/mastodon/src/main/res/values/strings.xml @@ -452,4 +452,6 @@ Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together. What are servers? + Log out of all accounts + Log out of all accounts? diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 228a276c9..d8900891b 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -289,4 +289,7 @@ Default content type This lets you have a content type be pre-selected when creating new posts, overriding the value set in “Posting preferences”. Instance info temporarily unavailable + Open in app + Share with account + Share or open with account \ No newline at end of file diff --git a/mastodon/src/main/res/values/styles.xml b/mastodon/src/main/res/values/styles.xml index 2657ebc75..d44c60df1 100644 --- a/mastodon/src/main/res/values/styles.xml +++ b/mastodon/src/main/res/values/styles.xml @@ -1,5 +1,15 @@ + + +