VQA fixes part 2
This commit is contained in:
parent
bf44f7ef13
commit
c3e48d20f3
|
@ -13,7 +13,7 @@ android {
|
||||||
applicationId "org.joinmastodon.android"
|
applicationId "org.joinmastodon.android"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 97
|
versionCode 99
|
||||||
versionName "2.5.0"
|
versionName "2.5.0"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ public class MainActivity extends FragmentStackActivity{
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent){
|
protected void onNewIntent(Intent intent){
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
|
setIntent(intent);
|
||||||
if(intent.getBooleanExtra("fromNotification", false)){
|
if(intent.getBooleanExtra("fromNotification", false)){
|
||||||
String accountID=intent.getStringExtra("accountID");
|
String accountID=intent.getStringExtra("accountID");
|
||||||
AccountSession accountSession;
|
AccountSession accountSession;
|
||||||
|
@ -85,6 +86,8 @@ public class MainActivity extends FragmentStackActivity{
|
||||||
showCompose();
|
showCompose();
|
||||||
}else if(Intent.ACTION_VIEW.equals(intent.getAction())){
|
}else if(Intent.ACTION_VIEW.equals(intent.getAction())){
|
||||||
handleURL(intent.getData(), null);
|
handleURL(intent.getData(), null);
|
||||||
|
}else if(intent.getBooleanExtra("explore", false)){
|
||||||
|
restartHomeFragment();
|
||||||
}/*else if(intent.hasExtra(PackageInstaller.EXTRA_STATUS) && GithubSelfUpdater.needSelfUpdating()){
|
}/*else if(intent.hasExtra(PackageInstaller.EXTRA_STATUS) && GithubSelfUpdater.needSelfUpdating()){
|
||||||
GithubSelfUpdater.getInstance().handleIntentFromInstaller(intent, this);
|
GithubSelfUpdater.getInstance().handleIntentFromInstaller(intent, this);
|
||||||
}*/
|
}*/
|
||||||
|
@ -211,6 +214,8 @@ public class MainActivity extends FragmentStackActivity{
|
||||||
}
|
}
|
||||||
}else if(intent.getBooleanExtra("compose", false)){
|
}else if(intent.getBooleanExtra("compose", false)){
|
||||||
showCompose();
|
showCompose();
|
||||||
|
}else if(intent.getBooleanExtra("explore", false) && fragment instanceof HomeFragment hf){
|
||||||
|
getWindow().getDecorView().post(()->hf.setCurrentTab(R.id.tab_search));
|
||||||
}else if(Intent.ACTION_VIEW.equals(intent.getAction())){
|
}else if(Intent.ACTION_VIEW.equals(intent.getAction())){
|
||||||
handleURL(intent.getData(), null);
|
handleURL(intent.getData(), null);
|
||||||
}else{
|
}else{
|
||||||
|
@ -218,4 +223,10 @@ public class MainActivity extends FragmentStackActivity{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Fragment getTopmostFragment(){
|
||||||
|
if(fragmentContainers.isEmpty())
|
||||||
|
return null;
|
||||||
|
return getFragmentManager().findFragmentById(fragmentContainers.get(fragmentContainers.size()-1).getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,13 @@ import java.util.List;
|
||||||
public class GetCatalogInstances extends MastodonAPIRequest<List<CatalogInstance>>{
|
public class GetCatalogInstances extends MastodonAPIRequest<List<CatalogInstance>>{
|
||||||
|
|
||||||
private String lang, category;
|
private String lang, category;
|
||||||
|
private boolean includeClosedSignups;
|
||||||
|
|
||||||
public GetCatalogInstances(String lang, String category){
|
public GetCatalogInstances(String lang, String category, boolean includeClosedSignups){
|
||||||
super(HttpMethod.GET, null, new TypeToken<>(){});
|
super(HttpMethod.GET, null, new TypeToken<>(){});
|
||||||
this.lang=lang;
|
this.lang=lang;
|
||||||
this.category=category;
|
this.category=category;
|
||||||
|
this.includeClosedSignups=includeClosedSignups;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,6 +32,8 @@ public class GetCatalogInstances extends MastodonAPIRequest<List<CatalogInstance
|
||||||
builder.appendQueryParameter("language", lang);
|
builder.appendQueryParameter("language", lang);
|
||||||
if(!TextUtils.isEmpty(category))
|
if(!TextUtils.isEmpty(category))
|
||||||
builder.appendQueryParameter("category", category);
|
builder.appendQueryParameter("category", category);
|
||||||
|
if(includeClosedSignups)
|
||||||
|
builder.appendQueryParameter("registrations", "all");
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,7 +425,7 @@ public class AccountSessionManager{
|
||||||
ShortcutManager sm=MastodonApp.context.getSystemService(ShortcutManager.class);
|
ShortcutManager sm=MastodonApp.context.getSystemService(ShortcutManager.class);
|
||||||
if((sm.getDynamicShortcuts().isEmpty() || BuildConfig.DEBUG) && !sessions.isEmpty()){
|
if((sm.getDynamicShortcuts().isEmpty() || BuildConfig.DEBUG) && !sessions.isEmpty()){
|
||||||
// There are no shortcuts, but there are accounts. Add a compose shortcut.
|
// There are no shortcuts, but there are accounts. Add a compose shortcut.
|
||||||
ShortcutInfo info=new ShortcutInfo.Builder(MastodonApp.context, "compose")
|
ShortcutInfo compose=new ShortcutInfo.Builder(MastodonApp.context, "compose")
|
||||||
.setActivity(ComponentName.createRelative(MastodonApp.context, MainActivity.class.getName()))
|
.setActivity(ComponentName.createRelative(MastodonApp.context, MainActivity.class.getName()))
|
||||||
.setShortLabel(MastodonApp.context.getString(R.string.new_post))
|
.setShortLabel(MastodonApp.context.getString(R.string.new_post))
|
||||||
.setIcon(Icon.createWithResource(MastodonApp.context, R.mipmap.ic_shortcut_compose))
|
.setIcon(Icon.createWithResource(MastodonApp.context, R.mipmap.ic_shortcut_compose))
|
||||||
|
@ -433,12 +433,20 @@ public class AccountSessionManager{
|
||||||
.setAction(Intent.ACTION_MAIN)
|
.setAction(Intent.ACTION_MAIN)
|
||||||
.putExtra("compose", true))
|
.putExtra("compose", true))
|
||||||
.build();
|
.build();
|
||||||
sm.setDynamicShortcuts(Collections.singletonList(info));
|
ShortcutInfo explore=new ShortcutInfo.Builder(MastodonApp.context, "explore")
|
||||||
|
.setActivity(ComponentName.createRelative(MastodonApp.context, MainActivity.class.getName()))
|
||||||
|
.setShortLabel(MastodonApp.context.getString(R.string.tab_search))
|
||||||
|
.setIcon(Icon.createWithResource(MastodonApp.context, R.mipmap.ic_shortcut_explore))
|
||||||
|
.setIntent(new Intent(MastodonApp.context, MainActivity.class)
|
||||||
|
.setAction(Intent.ACTION_MAIN)
|
||||||
|
.putExtra("explore", true))
|
||||||
|
.build();
|
||||||
|
sm.setDynamicShortcuts(List.of(compose, explore));
|
||||||
}else if(sessions.isEmpty()){
|
}else if(sessions.isEmpty()){
|
||||||
// There are shortcuts, but no accounts. Disable existing shortcuts.
|
// There are shortcuts, but no accounts. Disable existing shortcuts.
|
||||||
sm.disableShortcuts(Collections.singletonList("compose"), MastodonApp.context.getString(R.string.err_not_logged_in));
|
sm.disableShortcuts(List.of("compose", "explore"), MastodonApp.context.getString(R.string.err_not_logged_in));
|
||||||
}else{
|
}else{
|
||||||
sm.enableShortcuts(Collections.singletonList("compose"));
|
sm.enableShortcuts(List.of("compose", "explore"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||||
|
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||||
|
import androidx.dynamicanimation.animation.SpringForce;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
@ -79,6 +82,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
protected HashMap<String, Relationship> relationships=new HashMap<>();
|
protected HashMap<String, Relationship> relationships=new HashMap<>();
|
||||||
protected Rect tmpRect=new Rect();
|
protected Rect tmpRect=new Rect();
|
||||||
protected TypedObjectPool<MediaGridStatusDisplayItem.GridItemType, MediaAttachmentViewController> attachmentViewsPool=new TypedObjectPool<>(this::makeNewMediaAttachmentView);
|
protected TypedObjectPool<MediaGridStatusDisplayItem.GridItemType, MediaAttachmentViewController> attachmentViewsPool=new TypedObjectPool<>(this::makeNewMediaAttachmentView);
|
||||||
|
private SpringAnimation listShakeAnimation;
|
||||||
|
|
||||||
public BaseStatusListFragment(){
|
public BaseStatusListFragment(){
|
||||||
super(20);
|
super(20);
|
||||||
|
@ -675,6 +679,17 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||||
|
|
||||||
protected void onModifyItemViewHolder(BindableViewHolder<StatusDisplayItem> holder){}
|
protected void onModifyItemViewHolder(BindableViewHolder<StatusDisplayItem> holder){}
|
||||||
|
|
||||||
|
public void shakeListView(){
|
||||||
|
if(listShakeAnimation!=null)
|
||||||
|
listShakeAnimation.cancel();
|
||||||
|
SpringAnimation anim=new SpringAnimation(list, DynamicAnimation.TRANSLATION_X, 0);
|
||||||
|
anim.setStartVelocity(V.dp(-500));
|
||||||
|
anim.getSpring().setStiffness(500).setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);
|
||||||
|
listShakeAnimation=anim;
|
||||||
|
anim.addEndListener((animation, canceled, value, velocity)->listShakeAnimation=null);
|
||||||
|
anim.start();
|
||||||
|
}
|
||||||
|
|
||||||
protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter<BindableViewHolder<StatusDisplayItem>> implements ImageLoaderRecyclerAdapter{
|
protected class DisplayItemsAdapter extends UsableRecyclerView.Adapter<BindableViewHolder<StatusDisplayItem>> implements ImageLoaderRecyclerAdapter{
|
||||||
|
|
||||||
public DisplayItemsAdapter(){
|
public DisplayItemsAdapter(){
|
||||||
|
|
|
@ -275,4 +275,8 @@ public class HashtagTimelineFragment extends StatusListFragment{
|
||||||
})
|
})
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHashtagName(){
|
||||||
|
return hashtagName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1149,7 +1149,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||||
startImagePicker(COVER_RESULT);
|
startImagePicker(COVER_RESULT);
|
||||||
}else{
|
}else{
|
||||||
Drawable drawable=cover.getDrawable();
|
Drawable drawable=cover.getDrawable();
|
||||||
if(drawable==null || drawable instanceof ColorDrawable)
|
if(drawable==null || drawable instanceof ColorDrawable || account.headerStatic.endsWith("/missing.png"))
|
||||||
return;
|
return;
|
||||||
currentPhotoViewer=new PhotoViewer(getActivity(), createFakeAttachments(account.header, drawable), 0,
|
currentPhotoViewer=new PhotoViewer(getActivity(), createFakeAttachments(account.header, drawable), 0,
|
||||||
null, accountID, new SingleImagePhotoViewerListener(cover, cover, null, this, ()->currentPhotoViewer=null, ()->drawable, ()->avatarBorder.setTranslationZ(2), ()->avatarBorder.setTranslationZ(0)));
|
null, accountID, new SingleImagePhotoViewerListener(cover, cover, null, this, ()->currentPhotoViewer=null, ()->drawable, ()->avatarBorder.setTranslationZ(2), ()->avatarBorder.setTranslationZ(0)));
|
||||||
|
|
|
@ -37,7 +37,6 @@ import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
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.SimpleTextWatcher;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.ui.views.FilterChipView;
|
import org.joinmastodon.android.ui.views.FilterChipView;
|
||||||
|
@ -61,8 +60,6 @@ import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.fragments.OnBackPressedListener;
|
import me.grishka.appkit.fragments.OnBackPressedListener;
|
||||||
import me.grishka.appkit.utils.BindableViewHolder;
|
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.utils.V;
|
||||||
import me.grishka.appkit.views.UsableRecyclerView;
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
|
@ -106,7 +103,7 @@ public class InstanceCatalogSignupFragment extends InstanceCatalogFragment imple
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLoadData(int offset, int count){
|
protected void doLoadData(int offset, int count){
|
||||||
currentRequest=new GetCatalogInstances(null, null)
|
currentRequest=new GetCatalogInstances(null, null, false)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<CatalogInstance> result){
|
public void onSuccess(List<CatalogInstance> result){
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
||||||
|
|
||||||
private void loadAutocompleteServers(){
|
private void loadAutocompleteServers(){
|
||||||
loadedAutocomplete=true;
|
loadedAutocomplete=true;
|
||||||
new GetCatalogInstances(null, null)
|
new GetCatalogInstances(null, null, true)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<CatalogInstance> result){
|
public void onSuccess(List<CatalogInstance> result){
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
import org.joinmastodon.android.model.BaseModel;
|
import org.joinmastodon.android.model.BaseModel;
|
||||||
|
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
|
@ -15,14 +16,18 @@ import java.util.List;
|
||||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
@AllFieldsAreRequired
|
|
||||||
public class CatalogInstance extends BaseModel{
|
public class CatalogInstance extends BaseModel{
|
||||||
|
@RequiredField
|
||||||
public String domain;
|
public String domain;
|
||||||
|
@RequiredField
|
||||||
public String version;
|
public String version;
|
||||||
|
@RequiredField
|
||||||
public String description;
|
public String description;
|
||||||
|
@RequiredField
|
||||||
public List<String> languages;
|
public List<String> languages;
|
||||||
@SerializedName("region")
|
@SerializedName("region")
|
||||||
private String _region;
|
private String _region;
|
||||||
|
@RequiredField
|
||||||
public List<String> categories;
|
public List<String> categories;
|
||||||
public String proxiedThumbnail;
|
public String proxiedThumbnail;
|
||||||
public int totalUsers;
|
public int totalUsers;
|
||||||
|
|
|
@ -52,6 +52,7 @@ import android.widget.Toast;
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.FileProvider;
|
import org.joinmastodon.android.FileProvider;
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
|
import org.joinmastodon.android.MainActivity;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.accounts.SetAccountBlocked;
|
import org.joinmastodon.android.api.requests.accounts.SetAccountBlocked;
|
||||||
|
@ -368,6 +369,8 @@ public class UiUtils{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openHashtagTimeline(Context context, String accountID, Hashtag hashtag){
|
public static void openHashtagTimeline(Context context, String accountID, Hashtag hashtag){
|
||||||
|
if(checkIfAlreadyDisplayingSameHashtag(context, hashtag.name))
|
||||||
|
return;
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putParcelable("hashtag", Parcels.wrap(hashtag));
|
args.putParcelable("hashtag", Parcels.wrap(hashtag));
|
||||||
|
@ -375,12 +378,22 @@ public class UiUtils{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openHashtagTimeline(Context context, String accountID, String hashtag){
|
public static void openHashtagTimeline(Context context, String accountID, String hashtag){
|
||||||
|
if(checkIfAlreadyDisplayingSameHashtag(context, hashtag))
|
||||||
|
return;
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putString("hashtagName", hashtag);
|
args.putString("hashtagName", hashtag);
|
||||||
Nav.go((Activity)context, HashtagTimelineFragment.class, args);
|
Nav.go((Activity)context, HashtagTimelineFragment.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean checkIfAlreadyDisplayingSameHashtag(Context context, String hashtag){
|
||||||
|
if(context instanceof MainActivity ma && ma.getTopmostFragment() instanceof HashtagTimelineFragment htf && htf.getHashtagName().equalsIgnoreCase(hashtag)){
|
||||||
|
htf.shakeListView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static void showConfirmationAlert(Context context, @StringRes int title, @StringRes int message, @StringRes int confirmButton, Runnable onConfirmed){
|
public static void showConfirmationAlert(Context context, @StringRes int title, @StringRes int message, @StringRes int confirmButton, Runnable onConfirmed){
|
||||||
showConfirmationAlert(context, context.getString(title), message==0 ? null : context.getString(message), context.getString(confirmButton), onConfirmed);
|
showConfirmationAlert(context, context.getString(title), message==0 ? null : context.getString(message), context.getString(confirmButton), onConfirmed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<vector android:height="108dp"
|
||||||
|
android:viewportHeight="56" android:viewportWidth="56"
|
||||||
|
android:width="108dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<group android:translateX="16" android:translateY="16">
|
||||||
|
<path android:fillColor="@color/shortcut_icon_foreground" android:pathData="M19.6,21 L13.3,14.7Q12.55,15.3 11.575,15.65Q10.6,16 9.5,16Q6.775,16 4.888,14.113Q3,12.225 3,9.5Q3,6.775 4.888,4.887Q6.775,3 9.5,3Q12.225,3 14.113,4.887Q16,6.775 16,9.5Q16,10.6 15.65,11.575Q15.3,12.55 14.7,13.3L21,19.6ZM9.5,14Q11.375,14 12.688,12.688Q14,11.375 14,9.5Q14,7.625 12.688,6.312Q11.375,5 9.5,5Q7.625,5 6.312,6.312Q5,7.625 5,9.5Q5,11.375 6.312,12.688Q7.625,14 9.5,14Z"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="@color/shortcut_icon_background"/>
|
||||||
|
<size android:width="108dp" android:height="108dp"/>
|
||||||
|
</shape>
|
||||||
|
</background>
|
||||||
|
<foreground android:drawable="@drawable/ic_explore_foreground"/>
|
||||||
|
</adaptive-icon>
|
Loading…
Reference in New Issue