Group settings by account (AND-170)
This commit is contained in:
parent
c60d06950f
commit
1b17600835
28 changed files with 505 additions and 205 deletions
|
@ -3,6 +3,7 @@ package org.joinmastodon.android;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
|
||||
|
@ -12,6 +13,10 @@ public class GlobalUserPreferences{
|
|||
public static boolean altTextReminders, confirmUnfollow, confirmBoost, confirmDeletePost;
|
||||
public static ThemePreference theme=ThemePreference.AUTO;
|
||||
public static boolean useDynamicColors;
|
||||
public static boolean showInteractionCounts;
|
||||
public static boolean customEmojiInNames;
|
||||
public static boolean showCWs;
|
||||
public static boolean hideSensitiveMedia;
|
||||
|
||||
private static SharedPreferences getPrefs(){
|
||||
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
|
||||
|
@ -31,6 +36,19 @@ public class GlobalUserPreferences{
|
|||
confirmDeletePost=prefs.getBoolean("confirmDeletePost", true);
|
||||
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
||||
useDynamicColors=prefs.getBoolean("useDynamicColors", true);
|
||||
if(!prefs.getBoolean("perAccountMigrationDone", false)){
|
||||
AccountSession account=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
if(account!=null){
|
||||
SharedPreferences accPrefs=account.getRawLocalPreferences();
|
||||
showInteractionCounts=accPrefs.getBoolean("interactionCounts", true);
|
||||
customEmojiInNames=accPrefs.getBoolean("emojiInNames", true);
|
||||
showCWs=accPrefs.getBoolean("showCWs", true);
|
||||
hideSensitiveMedia=accPrefs.getBoolean("hideSensitive", true);
|
||||
save();
|
||||
}
|
||||
// Also applies to new app installs
|
||||
prefs.edit().putBoolean("perAccountMigrationDone", true).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public static void save(){
|
||||
|
@ -43,6 +61,10 @@ public class GlobalUserPreferences{
|
|||
.putBoolean("confirmBoost", confirmBoost)
|
||||
.putBoolean("confirmDeletePost", confirmDeletePost)
|
||||
.putBoolean("useDynamicColors", useDynamicColors)
|
||||
.putBoolean("interactionCounts", showInteractionCounts)
|
||||
.putBoolean("emojiInNames", customEmojiInNames)
|
||||
.putBoolean("showCWs", showCWs)
|
||||
.putBoolean("hideSensitive", hideSensitiveMedia)
|
||||
.apply();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,18 +5,10 @@ import android.content.SharedPreferences;
|
|||
public class AccountLocalPreferences{
|
||||
private final SharedPreferences prefs;
|
||||
|
||||
public boolean showInteractionCounts;
|
||||
public boolean customEmojiInNames;
|
||||
public boolean showCWs;
|
||||
public boolean hideSensitiveMedia;
|
||||
public boolean serverSideFiltersSupported;
|
||||
|
||||
public AccountLocalPreferences(SharedPreferences prefs){
|
||||
this.prefs=prefs;
|
||||
showInteractionCounts=prefs.getBoolean("interactionCounts", true);
|
||||
customEmojiInNames=prefs.getBoolean("emojiInNames", true);
|
||||
showCWs=prefs.getBoolean("showCWs", true);
|
||||
hideSensitiveMedia=prefs.getBoolean("hideSensitive", true);
|
||||
serverSideFiltersSupported=prefs.getBoolean("serverSideFilters", false);
|
||||
}
|
||||
|
||||
|
@ -30,10 +22,6 @@ public class AccountLocalPreferences{
|
|||
|
||||
public void save(){
|
||||
prefs.edit()
|
||||
.putBoolean("interactionCounts", showInteractionCounts)
|
||||
.putBoolean("emojiInNames", customEmojiInNames)
|
||||
.putBoolean("showCWs", showCWs)
|
||||
.putBoolean("hideSensitive", hideSensitiveMedia)
|
||||
.putBoolean("serverSideFilters", serverSideFiltersSupported)
|
||||
.apply();
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||
int itemCount=spoilerItem.contentItems.size();
|
||||
displayItems.addAll(index+1, spoilerItem.contentItems);
|
||||
if(spoilerItem.spoilerType==Status.SpoilerType.FILTER && spoilerItem.contentItems.get(0) instanceof SpoilerStatusDisplayItem nestedSpoiler
|
||||
&& nestedSpoiler.spoilerType==Status.SpoilerType.CONTENT_WARNING && !AccountSessionManager.get(accountID).getLocalPreferences().showCWs){
|
||||
&& nestedSpoiler.spoilerType==Status.SpoilerType.CONTENT_WARNING && !GlobalUserPreferences.showCWs){
|
||||
status.revealedSpoilers.add(Status.SpoilerType.CONTENT_WARNING);
|
||||
displayItems.addAll(index+1+itemCount, nestedSpoiler.contentItems);
|
||||
itemCount+=nestedSpoiler.contentItems.size();
|
||||
|
|
|
@ -560,7 +560,7 @@ public class ProfileFragment extends LoaderFragment implements ScrollableToTop,
|
|||
ViewImageLoader.loadWithoutAnimation(avatar, avatar.getDrawable(), new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(100), V.dp(100)));
|
||||
ViewImageLoader.loadWithoutAnimation(cover, cover.getDrawable(), new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.header : account.headerStatic, 1000, 1000));
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(account.displayName);
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(ssb, account.emojis);
|
||||
name.setText(ssb);
|
||||
setTitle(ssb);
|
||||
|
|
|
@ -68,7 +68,7 @@ public class ThreadFragment extends StatusListFragment implements AssistContentP
|
|||
knownAccounts.put(inReplyToAccount.id, inReplyToAccount);
|
||||
data.add(mainStatus);
|
||||
onAppendItems(Collections.singletonList(mainStatus));
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
setTitle(HtmlParser.parseCustomEmoji(getString(R.string.post_from_user, mainStatus.account.displayName), mainStatus.account.emojis));
|
||||
else
|
||||
setTitle(getString(R.string.post_from_user, mainStatus.account.displayName));
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.joinmastodon.android.BuildConfig;
|
||||
import org.joinmastodon.android.MainActivity;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.catalog.GetDonationCampaigns;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Preferences;
|
||||
import org.joinmastodon.android.model.donations.DonationCampaign;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.SectionHeaderListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.sheets.DonationSheet;
|
||||
import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.viewcontrollers.ComposeLanguageAlertViewController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class SettingsAccountFragment extends BaseSettingsFragment<Void>{
|
||||
private static final int DONATION_RESULT=433;
|
||||
private DonationSheet donationSheet;
|
||||
private boolean loggedOut;
|
||||
private ListItem<Void> languageItem;
|
||||
private Locale postLanguage;
|
||||
private ComposeLanguageAlertViewController.SelectedOption newPostLanguage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
AccountSession account=AccountSessionManager.get(accountID);
|
||||
setTitle(account.getFullUsername());
|
||||
if(account.preferences!=null && account.preferences.postingDefaultLanguage!=null){
|
||||
postLanguage=Locale.forLanguageTag(account.preferences.postingDefaultLanguage);
|
||||
}
|
||||
|
||||
ArrayList<ListItem<Void>> items=new ArrayList<>();
|
||||
items.add(new SectionHeaderListItem(R.string.account_settings));
|
||||
|
||||
items.add(new ListItem<>(R.string.settings_privacy, 0, R.drawable.ic_privacy_tip_24px, this::onPrivacyClick));
|
||||
items.add(new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_filter_alt_24px, this::onFiltersClick));
|
||||
items.add(new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_notifications_24px, this::onNotificationsClick));
|
||||
items.add(languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(Locale.getDefault()) : null, R.drawable.ic_language_24px, this::onDefaultLanguageClick));
|
||||
|
||||
items.add(new SectionHeaderListItem(account.domain));
|
||||
items.add(new ListItem<>(getString(R.string.settings_about_this_server), getString(R.string.settings_server_explanation), R.drawable.ic_dns_24px, this::onServerClick));
|
||||
if(account.isEligibleForDonations()){
|
||||
items.add(new ListItem<>(R.string.settings_donate, 0, R.drawable.ic_volunteer_activism_24px, this::onDonateClick));
|
||||
}
|
||||
|
||||
items.add(new SectionHeaderListItem(R.string.manage_account));
|
||||
items.add(new ListItem<>(R.string.switch_to_this_account, 0, R.drawable.ic_switch_account_24px, AccountSessionManager.getInstance().getLastActiveAccountID().equals(accountID) ? null : this::onSwitchAccountClick));
|
||||
items.add(new ListItem<>(R.string.delete_account, 0, R.drawable.ic_delete_forever_24px, this::onDeleteAccountClick, R.attr.colorM3Error, false));
|
||||
items.add(new ListItem<>(R.string.log_out, 0, R.drawable.ic_logout_24px, this::onLogOutClick, R.attr.colorM3Error, false));
|
||||
|
||||
onDataLoaded(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||
if(requestCode==DONATION_RESULT){
|
||||
if(donationSheet!=null)
|
||||
donationSheet.dismissWithoutAnimation();
|
||||
if(resultCode==Activity.RESULT_OK){
|
||||
new DonationSuccessfulSheet(getActivity(), accountID, data.getStringExtra("postText")).showWithoutAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
if(!loggedOut){
|
||||
if(newPostLanguage!=null){
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
if(s.preferences==null)
|
||||
s.preferences=new Preferences();
|
||||
s.preferences.postingDefaultLanguage=newPostLanguage.locale.toLanguageTag();
|
||||
s.savePreferencesLater();
|
||||
}
|
||||
AccountSessionManager.get(accountID).savePreferencesIfPending();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdateToolbar(){
|
||||
super.onUpdateToolbar();
|
||||
toolbarTitleView.setAlpha(list.getChildCount()==0 || list.getChildAdapterPosition(list.getChildAt(0))==0 ? 0 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter<?> getAdapter(){
|
||||
TextView largeTitle=(TextView) getToolbarLayoutInflater().inflate(R.layout.large_title, list, false);
|
||||
largeTitle.setText(getTitle());
|
||||
largeTitle.setPadding(largeTitle.getPaddingLeft(), largeTitle.getPaddingTop(), largeTitle.getPaddingRight(), 0);
|
||||
|
||||
MergeRecyclerAdapter adapter=new MergeRecyclerAdapter();
|
||||
adapter.addAdapter(new SingleViewRecyclerAdapter(largeTitle));
|
||||
adapter.addAdapter(super.getAdapter());
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
|
||||
private boolean titleVisible=true;
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
||||
boolean newTitleVisible=list.getChildAdapterPosition(list.getChildAt(0))==0;
|
||||
if(newTitleVisible!=titleVisible){
|
||||
titleVisible=newTitleVisible;
|
||||
toolbarTitleView.animate().alpha(titleVisible ? 0 : 1).setDuration(250).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Bundle makeFragmentArgs(){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
return args;
|
||||
}
|
||||
|
||||
private void onPrivacyClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsPrivacyFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onFiltersClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsFiltersFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onNotificationsClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsNotificationsFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onDefaultLanguageClick(ListItem<?> item){
|
||||
ComposeLanguageAlertViewController vc=new ComposeLanguageAlertViewController(getActivity(), null, newPostLanguage==null ? new ComposeLanguageAlertViewController.SelectedOption(-1, postLanguage, null) : newPostLanguage, null);
|
||||
AlertDialog dlg=new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.default_post_language)
|
||||
.setView(vc.getView())
|
||||
.setPositiveButton(R.string.cancel, null)
|
||||
.show();
|
||||
vc.setSelectionListener(opt->{
|
||||
if(!opt.locale.equals(postLanguage)){
|
||||
newPostLanguage=opt;
|
||||
languageItem.subtitle=newPostLanguage.locale.getDisplayLanguage(Locale.getDefault());
|
||||
rebindItem(languageItem);
|
||||
}
|
||||
dlg.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private void onServerClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsServerFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private boolean useStagingEnvironmentForDonations(){
|
||||
return (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")) && getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false);
|
||||
}
|
||||
|
||||
private void onDonateClick(ListItem<?> item){
|
||||
GetDonationCampaigns req=new GetDonationCampaigns(Locale.getDefault().toLanguageTag().replace('-', '_'), String.valueOf(AccountSessionManager.get(accountID).getDonationSeed()), "menu");
|
||||
if(useStagingEnvironmentForDonations()){
|
||||
req.setStaging(true);
|
||||
}
|
||||
req.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(DonationCampaign result){
|
||||
Activity activity=getActivity();
|
||||
if(activity==null)
|
||||
return;
|
||||
if(result==null){
|
||||
Toast.makeText(activity, "No campaign available (server misconfiguration?)", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
donationSheet=new DonationSheet(getActivity(), result, accountID, intent->startActivityForResult(intent, DONATION_RESULT));
|
||||
donationSheet.setOnDismissListener(dialog->donationSheet=null);
|
||||
donationSheet.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, true)
|
||||
.execNoAuth("");
|
||||
}
|
||||
|
||||
private void onSwitchAccountClick(ListItem<?> item){
|
||||
if(AccountSessionManager.getInstance().tryGetAccount(accountID)!=null){
|
||||
AccountSessionManager.getInstance().setLastActiveAccountID(accountID);
|
||||
((MainActivity)getActivity()).restartHomeFragment();
|
||||
}
|
||||
}
|
||||
|
||||
private void onDeleteAccountClick(ListItem<?> item){
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/delete");
|
||||
}
|
||||
|
||||
private void onLogOutClick(ListItem<?> item_){
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setMessage(getString(R.string.confirm_log_out, session.getFullUsername()))
|
||||
.setPositiveButton(R.string.log_out, (dialog, which)->AccountSessionManager.get(accountID).logOut(getActivity(), ()->{
|
||||
loggedOut=true;
|
||||
((MainActivity)getActivity()).restartHomeFragment();
|
||||
}))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
@ -13,38 +12,25 @@ import android.widget.TextView;
|
|||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Preferences;
|
||||
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.viewcontrollers.ComposeLanguageAlertViewController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SettingsBehaviorFragment extends BaseSettingsFragment<Void>{
|
||||
private ListItem<Void> languageItem, customTabsItem;
|
||||
private ListItem<Void> customTabsItem;
|
||||
private CheckableListItem<Void> altTextItem, playGifsItem, confirmUnfollowItem, confirmBoostItem, confirmDeleteItem;
|
||||
private Locale postLanguage;
|
||||
private ComposeLanguageAlertViewController.SelectedOption newPostLanguage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.settings_behavior);
|
||||
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
if(s.preferences!=null && s.preferences.postingDefaultLanguage!=null){
|
||||
postLanguage=Locale.forLanguageTag(s.preferences.postingDefaultLanguage);
|
||||
}
|
||||
|
||||
onDataLoaded(List.of(
|
||||
languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(Locale.getDefault()) : null, R.drawable.ic_language_24px, this::onDefaultLanguageClick),
|
||||
customTabsItem=new ListItem<>(R.string.settings_custom_tabs, GlobalUserPreferences.useCustomTabs ? R.string.in_app_browser : R.string.system_browser, R.drawable.ic_open_in_browser_24px, this::onCustomTabsClick),
|
||||
altTextItem=new CheckableListItem<>(R.string.settings_alt_text_reminders, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.altTextReminders, R.drawable.ic_alt_24px, this::toggleCheckableItem),
|
||||
playGifsItem=new CheckableListItem<>(R.string.settings_gif, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.playGifs, R.drawable.ic_animation_24px, this::toggleCheckableItem),
|
||||
|
@ -57,25 +43,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void>{
|
|||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
private void onDefaultLanguageClick(ListItem<?> item){
|
||||
ComposeLanguageAlertViewController vc=new ComposeLanguageAlertViewController(getActivity(), null, newPostLanguage==null ? new ComposeLanguageAlertViewController.SelectedOption(-1, postLanguage, null) : newPostLanguage, null);
|
||||
AlertDialog dlg=new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.default_post_language)
|
||||
.setView(vc.getView())
|
||||
.setPositiveButton(R.string.cancel, null)
|
||||
.show();
|
||||
vc.setSelectionListener(opt->{
|
||||
if(!opt.locale.equals(postLanguage)){
|
||||
newPostLanguage=opt;
|
||||
languageItem.subtitle=newPostLanguage.locale.getDisplayLanguage(Locale.getDefault());
|
||||
rebindItem(languageItem);
|
||||
}
|
||||
dlg.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private void onCustomTabsClick(ListItem<?> item){
|
||||
// GlobalUserPreferences.useCustomTabs=customTabsItem.checked;
|
||||
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse("http://example.com"));
|
||||
ResolveInfo info=getActivity().getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
final String browserName;
|
||||
|
@ -125,12 +93,5 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void>{
|
|||
GlobalUserPreferences.confirmBoost=confirmBoostItem.checked;
|
||||
GlobalUserPreferences.confirmDeletePost=confirmDeleteItem.checked;
|
||||
GlobalUserPreferences.save();
|
||||
if(newPostLanguage!=null){
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
if(s.preferences==null)
|
||||
s.preferences=new Preferences();
|
||||
s.preferences.postingDefaultLanguage=newPostLanguage.locale.toLanguageTag();
|
||||
s.savePreferencesLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@ import org.joinmastodon.android.E;
|
|||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.MastodonApp;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountLocalPreferences;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent;
|
||||
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
|
@ -36,8 +33,6 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
|||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.settings_display);
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
AccountLocalPreferences lp=s.getLocalPreferences();
|
||||
List<ListItem<Void>> items=new ArrayList<>();
|
||||
items.add(themeItem=new ListItem<>(R.string.settings_theme, getAppearanceValue(), R.drawable.ic_dark_mode_24px, this::onAppearanceClick));
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){
|
||||
|
@ -47,10 +42,10 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
|||
}));
|
||||
dynamicColorsItem.checkedChangeListener=this::setUseDynamicColors;
|
||||
}
|
||||
items.add(showCWsItem=new CheckableListItem<>(R.string.settings_show_cws, 0, CheckableListItem.Style.SWITCH, lp.showCWs, R.drawable.ic_warning_24px, this::toggleCheckableItem));
|
||||
items.add(hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_no_adult_content_24px, this::toggleCheckableItem));
|
||||
items.add(interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, 0, CheckableListItem.Style.SWITCH, lp.showInteractionCounts, R.drawable.ic_social_leaderboard_24px, this::toggleCheckableItem));
|
||||
items.add(emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, lp.customEmojiInNames, R.drawable.ic_emoticon_24px, this::toggleCheckableItem));
|
||||
items.add(showCWsItem=new CheckableListItem<>(R.string.settings_show_cws, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showCWs, R.drawable.ic_warning_24px, this::toggleCheckableItem));
|
||||
items.add(hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.hideSensitiveMedia, R.drawable.ic_no_adult_content_24px, this::toggleCheckableItem));
|
||||
items.add(interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showInteractionCounts, R.drawable.ic_social_leaderboard_24px, this::toggleCheckableItem));
|
||||
items.add(emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.customEmojiInNames, R.drawable.ic_emoticon_24px, this::toggleCheckableItem));
|
||||
onDataLoaded(items);
|
||||
}
|
||||
|
||||
|
@ -70,13 +65,11 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
|||
@Override
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
AccountLocalPreferences lp=s.getLocalPreferences();
|
||||
lp.showCWs=showCWsItem.checked;
|
||||
lp.hideSensitiveMedia=hideSensitiveMediaItem.checked;
|
||||
lp.showInteractionCounts=interactionCountsItem.checked;
|
||||
lp.customEmojiInNames=emojiInNamesItem.checked;
|
||||
lp.save();
|
||||
GlobalUserPreferences.showCWs=showCWsItem.checked;
|
||||
GlobalUserPreferences.hideSensitiveMedia=hideSensitiveMediaItem.checked;
|
||||
GlobalUserPreferences.showInteractionCounts=interactionCountsItem.checked;
|
||||
GlobalUserPreferences.customEmojiInNames=emojiInNamesItem.checked;
|
||||
GlobalUserPreferences.save();
|
||||
E.post(new StatusDisplaySettingsChangedEvent(accountID));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,53 +1,44 @@
|
|||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.joinmastodon.android.BuildConfig;
|
||||
import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.MainActivity;
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.catalog.GetDonationCampaigns;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||
import org.joinmastodon.android.model.donations.DonationCampaign;
|
||||
import org.joinmastodon.android.fragments.SplashFragment;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.sheets.AccountSwitcherSheet;
|
||||
import org.joinmastodon.android.ui.sheets.DonationSheet;
|
||||
import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet;
|
||||
import org.joinmastodon.android.model.viewmodel.SectionHeaderListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.SettingsAccountListItem;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
private static final int DONATION_RESULT=433;
|
||||
public class SettingsMainFragment extends BaseSettingsFragment<Object>{
|
||||
|
||||
private boolean loggedOut;
|
||||
private HideableSingleViewRecyclerAdapter bannerAdapter;
|
||||
private Button updateButton1, updateButton2;
|
||||
private TextView updateText;
|
||||
private DonationSheet donationSheet;
|
||||
private Runnable updateDownloadProgressUpdater=new Runnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
|
@ -63,27 +54,35 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
|||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.settings);
|
||||
setSubtitle(AccountSessionManager.get(accountID).getFullUsername());
|
||||
ArrayList<ListItem<Void>> items=new ArrayList<>();
|
||||
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
||||
items.add(new ListItem<>("Debug settings", null, R.drawable.ic_settings_24px, i->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||
ArrayList<ListItem<?>> items=new ArrayList<>();
|
||||
items.add(new SectionHeaderListItem(R.string.settings_accounts));
|
||||
for(AccountSession session:AccountSessionManager.getInstance().getLoggedInAccounts()){
|
||||
ImageLoaderRequest req;
|
||||
if(session.self.avatar!=null)
|
||||
req=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? session.self.avatar : session.self.avatarStatic, V.dp(50), V.dp(50));
|
||||
else
|
||||
req=null;
|
||||
items.add(new SettingsAccountListItem<>(session.getFullUsername(), null, req, this::onAccountClick, session, false));
|
||||
}
|
||||
|
||||
items.addAll(List.of(
|
||||
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_settings_24px, this::onBehaviorClick),
|
||||
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_style_24px, this::onDisplayClick),
|
||||
new ListItem<>(R.string.settings_privacy, 0, R.drawable.ic_privacy_tip_24px, this::onPrivacyClick),
|
||||
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_filter_alt_24px, this::onFiltersClick),
|
||||
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_notifications_24px, this::onNotificationsClick),
|
||||
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_dns_24px, this::onServerClick),
|
||||
new ListItem<>(getString(R.string.about_app, getString(R.string.app_name)), null, R.drawable.ic_info_24px, this::onAboutClick, null, 0, true)
|
||||
new ListItem<>(R.string.settings_add_account, 0, R.drawable.ic_add_24px, this::onAddAccountClick),
|
||||
|
||||
new SectionHeaderListItem(R.string.settings_app_settings),
|
||||
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_tune_24px, this::onBehaviorClick),
|
||||
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_style_24px, this::onDisplayClick)
|
||||
|
||||
));
|
||||
if(AccountSessionManager.get(accountID).isEligibleForDonations()){
|
||||
items.add(new ListItem<>(R.string.settings_donate, 0, R.drawable.ic_volunteer_activism_24px, this::onDonateClick));
|
||||
items.add(new ListItem<>(R.string.settings_manage_donations, 0, R.drawable.ic_settings_heart_24px, this::onManageDonationClick, 0, true));
|
||||
items.add(new ListItem<>(R.string.settings_manage_donations, 0, R.drawable.ic_settings_heart_24px, this::onManageDonationClick));
|
||||
}
|
||||
items.add(new ListItem<>(R.string.manage_accounts, 0, R.drawable.ic_switch_account_24px, this::onManageAccountsClick));
|
||||
items.add(new ListItem<>(R.string.log_out, 0, R.drawable.ic_logout_24px, this::onLogOutClick, R.attr.colorM3Error, false));
|
||||
onDataLoaded(items);
|
||||
items.add(new ListItem<>(getString(R.string.about_app, getString(R.string.app_name)), null, R.drawable.ic_info_24px, this::onAboutClick, null));
|
||||
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
||||
items.add(new ListItem<>("Debug settings", null, R.drawable.ic_bug_report_24px, i->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null));
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
onDataLoaded((List<ListItem<Object>>)(Object)items);
|
||||
|
||||
AccountSession session=AccountSessionManager.get(accountID);
|
||||
session.reloadPreferences(null);
|
||||
|
@ -100,13 +99,6 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
|||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
@Override
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
if(!loggedOut)
|
||||
AccountSessionManager.get(accountID).savePreferencesIfPending();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter<?> getAdapter(){
|
||||
View banner=getActivity().getLayoutInflater().inflate(R.layout.item_settings_banner, list, false);
|
||||
|
@ -137,23 +129,22 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||
if(requestCode==DONATION_RESULT){
|
||||
if(donationSheet!=null)
|
||||
donationSheet.dismissWithoutAnimation();
|
||||
if(resultCode==Activity.RESULT_OK){
|
||||
new DonationSuccessfulSheet(getActivity(), accountID, data.getStringExtra("postText")).showWithoutAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bundle makeFragmentArgs(){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
return args;
|
||||
}
|
||||
|
||||
private void onAccountClick(SettingsAccountListItem<AccountSession> item){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.parentObject.getID());
|
||||
Nav.go(getActivity(), SettingsAccountFragment.class, args);
|
||||
}
|
||||
|
||||
private void onAddAccountClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SplashFragment.class, null);
|
||||
}
|
||||
|
||||
private void onBehaviorClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsBehaviorFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
@ -162,73 +153,16 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
|||
Nav.go(getActivity(), SettingsDisplayFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onPrivacyClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsPrivacyFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onFiltersClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsFiltersFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onNotificationsClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsNotificationsFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onServerClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsServerFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onAboutClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsAboutAppFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onManageAccountsClick(ListItem<?> item){
|
||||
new AccountSwitcherSheet(getActivity(), null).setOnLoggedOutCallback(()->loggedOut=true).show();
|
||||
}
|
||||
|
||||
private void onLogOutClick(ListItem<?> item_){
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setMessage(getString(R.string.confirm_log_out, session.getFullUsername()))
|
||||
.setPositiveButton(R.string.log_out, (dialog, which)->AccountSessionManager.get(accountID).logOut(getActivity(), ()->{
|
||||
loggedOut=true;
|
||||
((MainActivity)getActivity()).restartHomeFragment();
|
||||
}))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onDonateClick(ListItem<?> item){
|
||||
GetDonationCampaigns req=new GetDonationCampaigns(Locale.getDefault().toLanguageTag().replace('-', '_'), String.valueOf(AccountSessionManager.get(accountID).getDonationSeed()), "menu");
|
||||
if(getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false)){
|
||||
req.setStaging(true);
|
||||
}
|
||||
req.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(DonationCampaign result){
|
||||
Activity activity=getActivity();
|
||||
if(activity==null)
|
||||
return;
|
||||
if(result==null){
|
||||
Toast.makeText(activity, "No campaign available (server misconfiguration?)", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
donationSheet=new DonationSheet(getActivity(), result, accountID, intent->startActivityForResult(intent, DONATION_RESULT));
|
||||
donationSheet.setOnDismissListener(dialog->donationSheet=null);
|
||||
donationSheet.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, true)
|
||||
.execNoAuth("");
|
||||
private boolean useStagingEnvironmentForDonations(){
|
||||
return (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")) && getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false);
|
||||
}
|
||||
|
||||
private void onManageDonationClick(ListItem<?> item){
|
||||
UiUtils.launchWebBrowser(getActivity(), "https://sponsor.staging.joinmastodon.org/donate/manage");
|
||||
UiUtils.launchWebBrowser(getActivity(), useStagingEnvironmentForDonations() ? "https://sponsor.staging.joinmastodon.org/donate/manage" : "https://sponsor.joinmastodon.org/donate/manage");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.text.Spannable;
|
|||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.AccountField;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
|
@ -33,7 +32,7 @@ public class AccountViewModel{
|
|||
this.account=account;
|
||||
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(50), V.dp(50));
|
||||
emojiHelper=new CustomEmojiHelper();
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
else
|
||||
parsedName=account.displayName;
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.text.SpannableStringBuilder;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Card;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
|
@ -31,7 +30,7 @@ public class CardViewModel{
|
|||
|
||||
if(authorAccount!=null){
|
||||
parsedAuthorName=new SpannableStringBuilder(authorAccount.displayName);
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(parsedAuthorName, authorAccount.emojis);
|
||||
authorNameEmojiHelper.setText(parsedAuthorName);
|
||||
authorAvaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? authorAccount.avatar : authorAccount.avatarStatic, V.dp(50), V.dp(50));
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
public class SectionHeaderListItem extends ListItem<Void>{
|
||||
public SectionHeaderListItem(String title){
|
||||
super(title, null, null);
|
||||
}
|
||||
|
||||
public SectionHeaderListItem(@StringRes int title){
|
||||
super(title, 0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(){
|
||||
return R.id.list_item_section_header;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
|
||||
public class SettingsAccountListItem<T> extends ListItem<T>{
|
||||
public ImageLoaderRequest avatar;
|
||||
|
||||
public SettingsAccountListItem(String title, String subtitle, ImageLoaderRequest avatar, Consumer<SettingsAccountListItem<T>> onClick, T parentObject, boolean dividerAfter){
|
||||
super(title, subtitle, 0, (Consumer<ListItem<T>>)(Object)onClick, parentObject, 0, dividerAfter);
|
||||
this.avatar=avatar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(){
|
||||
return R.id.list_item_settings_account;
|
||||
}
|
||||
}
|
|
@ -5,17 +5,19 @@ import android.view.ViewGroup;
|
|||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.viewmodel.AvatarPileListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.SettingsAccountListItem;
|
||||
import org.joinmastodon.android.ui.viewholders.AvatarPileListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.CheckboxOrRadioListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.ListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.OptionsListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.SectionHeaderListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.SettingsAccountListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.SimpleListItemViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.SwitchListItemViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter;
|
||||
import me.grishka.appkit.imageloader.ListImageLoaderWrapper;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
|
@ -49,6 +51,10 @@ public class GenericListItemsAdapter<T> extends UsableRecyclerView.Adapter<ListI
|
|||
return new OptionsListItemViewHolder(parent.getContext(), parent);
|
||||
if(viewType==R.id.list_item_avatar_pile)
|
||||
return new AvatarPileListItemViewHolder(parent.getContext(), parent);
|
||||
if(viewType==R.id.list_item_settings_account)
|
||||
return new SettingsAccountListItemViewHolder(parent.getContext(), parent);
|
||||
if(viewType==R.id.list_item_section_header)
|
||||
return new SectionHeaderListItemViewHolder(parent.getContext(), parent);
|
||||
|
||||
throw new IllegalArgumentException("Unexpected view type "+viewType);
|
||||
}
|
||||
|
@ -74,6 +80,8 @@ public class GenericListItemsAdapter<T> extends UsableRecyclerView.Adapter<ListI
|
|||
ListItem<?> item=items.get(position);
|
||||
if(item instanceof AvatarPileListItem<?> avatarPileListItem)
|
||||
return avatarPileListItem.avatars.size();
|
||||
if(item instanceof SettingsAccountListItem<?>)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,6 +90,8 @@ public class GenericListItemsAdapter<T> extends UsableRecyclerView.Adapter<ListI
|
|||
ListItem<?> item=items.get(position);
|
||||
if(item instanceof AvatarPileListItem<?> avatarPileListItem)
|
||||
return avatarPileListItem.avatars.get(image);
|
||||
if(item instanceof SettingsAccountListItem<?> accountItem)
|
||||
return accountItem.avatar;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||
this.accountID=accountID;
|
||||
parsedName=new SpannableStringBuilder(user.displayName);
|
||||
this.status=status;
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
|
||||
emojiHelper.setText(parsedName);
|
||||
if(status!=null){
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.widget.TextView;
|
|||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
|
@ -36,7 +35,7 @@ public class InlineStatusStatusDisplayItem extends StatusDisplayItem{
|
|||
this.status=status;
|
||||
|
||||
parsedName=new SpannableStringBuilder(status.account.displayName);
|
||||
if(AccountSessionManager.get(parentFragment.getAccountID()).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(parsedName, status.account.emojis);
|
||||
|
||||
parsedPostText=HtmlParser.parse(status.content, status.emojis, status.mentions, status.tags, parentFragment.getAccountID(), status.getContentStatus(), parentFragment.getActivity());
|
||||
|
|
|
@ -7,8 +7,8 @@ import android.text.SpannableStringBuilder;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
|
@ -31,7 +31,7 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon){
|
||||
super(parentID, parentFragment);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
||||
if(AccountSessionManager.get(parentFragment.getAccountID()).getLocalPreferences().customEmojiInNames)
|
||||
if(GlobalUserPreferences.customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(ssb, emojis);
|
||||
this.text=ssb;
|
||||
emojiHelper.setText(ssb);
|
||||
|
|
|
@ -8,8 +8,8 @@ import android.text.TextUtils;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
|
@ -97,7 +97,7 @@ public abstract class StatusDisplayItem{
|
|||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||
Status statusForContent=status.getContentStatus();
|
||||
HeaderStatusDisplayItem header=null;
|
||||
boolean hideCounts=!AccountSessionManager.get(accountID).getLocalPreferences().showInteractionCounts;
|
||||
boolean hideCounts=!GlobalUserPreferences.showInteractionCounts;
|
||||
if((flags & FLAG_NO_HEADER)==0){
|
||||
if(status.reblog!=null){
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_repeat_wght700_20px));
|
||||
|
@ -134,7 +134,7 @@ public abstract class StatusDisplayItem{
|
|||
SpoilerStatusDisplayItem spoilerItem=new SpoilerStatusDisplayItem(parentID, fragment, null, status, statusForContent, Type.SPOILER, Status.SpoilerType.CONTENT_WARNING);
|
||||
contentItems.add(spoilerItem);
|
||||
contentItems=spoilerItem.contentItems;
|
||||
if(!AccountSessionManager.get(accountID).getLocalPreferences().showCWs && !filtered){
|
||||
if(!GlobalUserPreferences.showCWs && !filtered){
|
||||
status.revealedSpoilers.add(Status.SpoilerType.CONTENT_WARNING);
|
||||
needAddCWItems=true;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ public abstract class StatusDisplayItem{
|
|||
if((flags & FLAG_MEDIA_FORCE_HIDDEN)!=0){
|
||||
mediaGrid.sensitiveTitle=fragment.getString(R.string.media_hidden);
|
||||
mediaGrid.sensitiveRevealed=false;
|
||||
}else if(statusForContent.sensitive && !AccountSessionManager.get(accountID).getLocalPreferences().hideSensitiveMedia){
|
||||
}else if(statusForContent.sensitive && !GlobalUserPreferences.hideSensitiveMedia){
|
||||
mediaGrid.sensitiveRevealed=true;
|
||||
}
|
||||
contentItems.add(mediaGrid);
|
||||
|
|
|
@ -11,8 +11,8 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
|
@ -57,7 +57,7 @@ public class NonMutualPreReplySheet extends PreReplySheet{
|
|||
name.setEllipsize(TextUtils.TruncateAt.END);
|
||||
name.setTextAppearance(R.style.m3_title_medium);
|
||||
name.setTextColor(UiUtils.getThemeColor(context, R.attr.colorM3OnSurface));
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames){
|
||||
if(GlobalUserPreferences.customEmojiInNames){
|
||||
name.setText(HtmlParser.parseCustomEmoji(account.displayName, account.emojis));
|
||||
UiUtils.loadCustomEmojiInTextView(name);
|
||||
}else{
|
||||
|
|
|
@ -28,7 +28,7 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
|
|||
title=findViewById(R.id.title);
|
||||
subtitle=findViewById(R.id.subtitle);
|
||||
icon=findViewById(R.id.icon);
|
||||
view=(LinearLayout) itemView;
|
||||
view=itemView instanceof LinearLayout ll ? ll : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,12 +52,7 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
|
|||
subtitle.setText(item.subtitle);
|
||||
}
|
||||
|
||||
if(item.iconRes!=0){
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
icon.setImageResource(item.iconRes);
|
||||
}else{
|
||||
icon.setVisibility(View.GONE);
|
||||
}
|
||||
bindIcon(item);
|
||||
|
||||
if(item.colorOverrideAttr!=0){
|
||||
int color=UiUtils.getThemeColor(view.getContext(), item.colorOverrideAttr);
|
||||
|
@ -68,6 +63,15 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
|
|||
view.setAlpha(item.isEnabled ? 1 : .4f);
|
||||
}
|
||||
|
||||
protected void bindIcon(T item){
|
||||
if(item.iconRes!=0){
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
icon.setImageResource(item.iconRes);
|
||||
}else{
|
||||
icon.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(){
|
||||
return item.isEnabled;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package org.joinmastodon.android.ui.viewholders;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.viewmodel.SectionHeaderListItem;
|
||||
|
||||
public class SectionHeaderListItemViewHolder extends ListItemViewHolder<SectionHeaderListItem>{
|
||||
public SectionHeaderListItemViewHolder(Context context, ViewGroup parent){
|
||||
super(context, R.layout.item_generic_list_header, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(SectionHeaderListItem item){
|
||||
if(TextUtils.isEmpty(item.title))
|
||||
title.setText(item.titleRes);
|
||||
else
|
||||
title.setText(item.title);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.joinmastodon.android.ui.viewholders;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.viewmodel.SettingsAccountListItem;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
|
||||
public class SettingsAccountListItemViewHolder extends ListItemViewHolder<SettingsAccountListItem<?>> implements ImageLoaderViewHolder{
|
||||
|
||||
public SettingsAccountListItemViewHolder(Context context, ViewGroup parent){
|
||||
super(context, R.layout.item_generic_list, parent);
|
||||
icon.setOutlineProvider(OutlineProviders.OVAL);
|
||||
icon.setClipToOutline(true);
|
||||
icon.setImageTintList(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindIcon(SettingsAccountListItem<?> item){}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable image){
|
||||
icon.setImageDrawable(image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
icon.setImageResource(R.drawable.image_placeholder);
|
||||
}
|
||||
}
|
9
mastodon/src/main/res/drawable/ic_bug_report_24px.xml
Normal file
9
mastodon/src/main/res/drawable/ic_bug_report_24px.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,760Q546,760 593,713Q640,666 640,600L640,440Q640,374 593,327Q546,280 480,280Q414,280 367,327Q320,374 320,440L320,600Q320,666 367,713Q414,760 480,760ZM400,640L560,640L560,560L400,560L400,640ZM400,480L560,480L560,400L400,400L400,480ZM480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520ZM480,840Q415,840 359.5,808Q304,776 272,720L160,720L160,640L244,640Q241,620 240.5,600Q240,580 240,560L160,560L160,480L240,480Q240,460 240.5,440Q241,420 244,400L160,400L160,320L272,320Q286,297 303.5,277Q321,257 344,242L280,176L336,120L422,206Q450,197 479,197Q508,197 536,206L624,120L680,176L614,242Q637,257 655.5,276.5Q674,296 688,320L800,320L800,400L716,400Q719,420 719.5,440Q720,460 720,480L800,480L800,560L720,560Q720,580 719.5,600Q719,620 716,640L800,640L800,720L688,720Q656,776 600.5,808Q545,840 480,840Z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M376,660L480,556L584,660L640,604L536,500L640,396L584,340L480,444L376,340L320,396L424,500L320,604L376,660ZM280,840Q247,840 223.5,816.5Q200,793 200,760L200,240L160,240L160,160L360,160L360,120L600,120L600,160L800,160L800,240L760,240L760,760Q760,793 736.5,816.5Q713,840 680,840L280,840ZM680,240L280,240L280,760Q280,760 280,760Q280,760 280,760L680,760Q680,760 680,760Q680,760 680,760L680,240ZM280,240L280,240L280,760Q280,760 280,760Q280,760 280,760L280,760Q280,760 280,760Q280,760 280,760L280,240Z"/>
|
||||
</vector>
|
15
mastodon/src/main/res/layout/item_generic_list_header.xml
Normal file
15
mastodon/src/main/res/layout/item_generic_list_header.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView 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="36dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
android:textColor="?colorM3OnSurfaceVariant"
|
||||
tools:text="Section header"/>
|
12
mastodon/src/main/res/layout/large_title.xml
Normal file
12
mastodon/src/main/res/layout/large_title.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/real_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="24dp"
|
||||
android:textAppearance="@style/m3_headline_small"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
tools:text="mastodon.social" />
|
|
@ -27,6 +27,8 @@
|
|||
<item name="list_item_account" type="id"/>
|
||||
<item name="list_item_options" type="id"/>
|
||||
<item name="list_item_avatar_pile" type="id"/>
|
||||
<item name="list_item_settings_account" type="id"/>
|
||||
<item name="list_item_section_header" type="id"/>
|
||||
|
||||
<item name="server_about" type="id"/>
|
||||
<item name="server_rules" type="id"/>
|
||||
|
|
|
@ -814,6 +814,14 @@
|
|||
<string name="avatar_move_and_scale">Move and scale</string>
|
||||
<string name="confirm_avatar_crop">Choose</string>
|
||||
<string name="settings_use_dynamic_colors">Use system dynamic color</string>
|
||||
<string name="settings_accounts">Accounts</string>
|
||||
<string name="settings_add_account">Add account...</string>
|
||||
<string name="settings_app_settings">App settings</string>
|
||||
<string name="account_settings">Account settings</string>
|
||||
<string name="settings_about_this_server">About this server</string>
|
||||
<string name="manage_account">Manage account</string>
|
||||
<string name="switch_to_this_account">Switch to this account</string>
|
||||
<string name="delete_account">Delete account</string>
|
||||
<plurals name="user_and_x_more_followed">
|
||||
<item quantity="one">%1$s and %2$,d other followed you</item>
|
||||
<item quantity="other">%1$s and %2$,d others followed you</item>
|
||||
|
|
Loading…
Add table
Reference in a new issue