diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java new file mode 100644 index 000000000..f00bdd2fb --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -0,0 +1,415 @@ +package org.joinmastodon.android.fragments.settings; + +import android.annotation.SuppressLint; +import android.graphics.Rect; +import android.os.Build; +import android.os.Bundle; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowInsets; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Switch; +import android.widget.TextView; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import org.joinmastodon.android.DomainManager; +import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountSession; +import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.fragments.DomainDisplay; +import org.joinmastodon.android.fragments.MastodonToolbarFragment; +import org.joinmastodon.android.ui.utils.UiUtils; + +import java.util.ArrayList; +import java.util.function.Consumer; + +import me.grishka.appkit.utils.BindableViewHolder; +import me.grishka.appkit.utils.V; +import me.grishka.appkit.views.UsableRecyclerView; + +public abstract class SettingsBaseFragment extends MastodonToolbarFragment implements DomainDisplay { + protected View view; + private UsableRecyclerView list; + private ArrayList items=new ArrayList<>(); + private String accountID; + + public abstract void addItems(ArrayList items); + + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) + setRetainInstance(true); + setTitle(R.string.settings); + + accountID=getArguments().getString("account"); + AccountSession session = AccountSessionManager.getInstance().getAccount(accountID); + DomainManager.getInstance().setCurrentDomain(session.domain + "/settings"); + + addItems(items); + } + + @Override + public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ + list=new UsableRecyclerView(getActivity()); + list.setLayoutManager(new LinearLayoutManager(getActivity())); + list.setAdapter(new SettingsAdapter()); + list.setBackgroundColor(UiUtils.getThemeColor(getActivity(), android.R.attr.colorBackground)); + list.setPadding(0, V.dp(16), 0, V.dp(12)); + list.setClipToPadding(false); + list.addItemDecoration(new RecyclerView.ItemDecoration(){ + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){ + // Add 32dp gaps between sections + RecyclerView.ViewHolder holder=parent.getChildViewHolder(view); + if((holder instanceof HeaderViewHolder || holder instanceof FooterViewHolder) && holder.getAbsoluteAdapterPosition()>1) + outRect.top=V.dp(32); + } + }); + return list; + } + + @Override + public void onApplyWindowInsets(WindowInsets insets){ + if(Build.VERSION.SDK_INT>=29 && insets.getTappableElementInsets().bottom==0){ + list.setPadding(0, V.dp(16), 0, V.dp(12)+insets.getSystemWindowInsetBottom()); + insets=insets.inset(0, 0, 0, insets.getSystemWindowInsetBottom()); + } + super.onApplyWindowInsets(insets); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState){ + super.onViewCreated(view, savedInstanceState); + this.view = view; + } + + + private static abstract class Item{ + public abstract int getViewType(); + } + + private class HeaderItem extends Item{ + private String text; + + public HeaderItem(@StringRes int text){ + this.text=getString(text); + } + + public HeaderItem(String text){ + this.text=text; + } + + @Override + public int getViewType(){ + return Type.HEADER.ordinal(); + } + } + + private class SwitchItem extends Item{ + private String text; + private int icon; + private boolean checked; + private Consumer onChanged; + private boolean enabled=true; + + public SwitchItem(@StringRes int text, @DrawableRes int icon, boolean checked, Consumer onChanged){ + this.text=getString(text); + this.icon=icon; + this.checked=checked; + this.onChanged=onChanged; + } + + public SwitchItem(@StringRes int text, @DrawableRes int icon, boolean checked, Consumer onChanged, boolean enabled){ + this.text=getString(text); + this.icon=icon; + this.checked=checked; + this.onChanged=onChanged; + this.enabled=enabled; + } + + @Override + public int getViewType(){ + return Type.SWITCH.ordinal(); + } + } + + public class ButtonItem extends Item{ + private int text; + private int icon; + private Consumer