Merge remote-tracking branch 'megalodon_main/main'
# Conflicts: # mastodon/build.gradle # mastodon/src/main/java/org/joinmastodon/android/fragments/HomeFragment.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAboutAppFragment.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBehaviorFragment.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsNotificationsFragment.java # mastodon/src/main/java/org/joinmastodon/android/model/Status.java # mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java # mastodon/src/main/res/menu/profile_own.xml
This commit is contained in:
@@ -266,7 +266,7 @@ public class AudioPlayerService extends Service{
|
||||
private void updateNotification(boolean dismissable, boolean removeNotification){
|
||||
Notification.Builder bldr=new Notification.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_ntf_logo)
|
||||
.setContentTitle(status.account.displayName)
|
||||
.setContentTitle(status.account.getDisplayName())
|
||||
.setContentText(HtmlParser.strip(status.content))
|
||||
.setOngoing(!dismissable)
|
||||
.setShowWhen(false)
|
||||
|
||||
@@ -120,6 +120,8 @@ public class CacheController{
|
||||
values.put("time", s.createdAt.getEpochSecond());
|
||||
db.insertWithOnConflict("home_timeline", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
if(!clear)
|
||||
db.delete("home_timeline", "`id` NOT IN (SELECT `id` FROM `home_timeline` ORDER BY `time` DESC LIMIT ?)", new String[]{"1000"});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ public class AccountSession{
|
||||
|
||||
public void savePreferencesIfPending(){
|
||||
if(preferencesNeedSaving){
|
||||
new UpdateAccountCredentialsPreferences(preferences, null, self.discoverable, self.source.indexable)
|
||||
new UpdateAccountCredentialsPreferences(preferences, self.locked, self.discoverable, self.source.indexable)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Account result){
|
||||
|
||||
@@ -9,5 +9,6 @@ public class StatusCreatedEvent{
|
||||
public StatusCreatedEvent(Status status, String accountID){
|
||||
this.status=status;
|
||||
this.accountID=accountID;
|
||||
status.fromStatusCreated=true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
selfUsername=view.findViewById(R.id.self_username);
|
||||
selfAvatar=view.findViewById(R.id.self_avatar);
|
||||
selfExtraText=view.findViewById(R.id.self_extra_text);
|
||||
HtmlParser.setTextWithCustomEmoji(selfName, self.displayName, self.emojis);
|
||||
HtmlParser.setTextWithCustomEmoji(selfName, self.getDisplayName(), self.emojis);
|
||||
selfUsername.setText('@'+self.username+'@'+instanceDomain);
|
||||
if(self.avatar!=null)
|
||||
ViewImageLoader.load(selfAvatar, null, new UrlImageLoaderRequest(self.avatar));
|
||||
@@ -724,7 +724,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
moreBtn.setBackground(null);
|
||||
|
||||
TextView name = view.findViewById(R.id.name);
|
||||
name.setText(HtmlParser.parseCustomEmoji(status.account.displayName, status.account.emojis));
|
||||
name.setText(HtmlParser.parseCustomEmoji(status.account.getDisplayName(), status.account.emojis));
|
||||
UiUtils.loadCustomEmojiInTextView(name);
|
||||
|
||||
String time = status==null || status.editedAt==null
|
||||
@@ -758,7 +758,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(16)));
|
||||
}
|
||||
|
||||
replyText.setText(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.displayName));
|
||||
replyText.setText(getString(quote!=null? R.string.sk_quoting_user : R.string.in_reply_to, status.account.getDisplayName()));
|
||||
int visibilityNameRes = switch (status.visibility) {
|
||||
case PUBLIC -> R.string.visibility_public;
|
||||
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||
@@ -766,7 +766,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
case DIRECT -> R.string.visibility_private;
|
||||
case LOCAL -> R.string.sk_local_only;
|
||||
};
|
||||
replyText.setContentDescription(getString(R.string.in_reply_to, status.account.displayName) + ", " + getString(visibilityNameRes));
|
||||
replyText.setContentDescription(getString(R.string.in_reply_to, status.account.getDisplayName()) + ", " + getString(visibilityNameRes));
|
||||
replyText.setOnClickListener(v->{
|
||||
scrollView.smoothScrollTo(0, 0);
|
||||
});
|
||||
@@ -1591,7 +1591,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
}
|
||||
|
||||
private void updateHeaders() {
|
||||
UiUtils.setExtraTextInfo(getContext(), selfExtraText, false, false, localOnly || statusVisibility==StatusPrivacy.LOCAL, null);
|
||||
UiUtils.setExtraTextInfo(getContext(), selfExtraText, false, false, localOnly, null);
|
||||
if (replyTo != null) UiUtils.setExtraTextInfo(getContext(), extraText, true, false, replyTo.localOnly || replyTo.visibility==StatusPrivacy.LOCAL, replyTo.account);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.joinmastodon.android.api.requests.accounts.GetFollowRequests;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -366,9 +365,9 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment<FollowR
|
||||
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
if(account.emojis.isEmpty()){
|
||||
parsedName=account.displayName;
|
||||
parsedName= account.getDisplayName();
|
||||
}else{
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.getDisplayName(), account.emojis);
|
||||
emojiHelper.setText(new SpannableStringBuilder(parsedName).append(parsedBio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent;
|
||||
import org.joinmastodon.android.fragments.discover.DiscoverFragment;
|
||||
import org.joinmastodon.android.fragments.onboarding.OnboardingFollowSuggestionsFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.PaginatedResponse;
|
||||
import org.joinmastodon.android.ui.AccountSwitcherSheet;
|
||||
@@ -75,7 +74,6 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
private TextView notificationsBadge;
|
||||
|
||||
private String accountID;
|
||||
private boolean isAkkoma;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
@@ -83,8 +81,6 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
accountID=getArguments().getString("account");
|
||||
setTitle(R.string.mo_app_name);
|
||||
|
||||
isAkkoma = getInstance().map(Instance::isAkkoma).orElse(false);
|
||||
|
||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
|
||||
setRetainInstance(true);
|
||||
|
||||
@@ -94,7 +90,6 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
homeTabFragment=new HomeTabFragment();
|
||||
homeTabFragment.setArguments(args);
|
||||
args=new Bundle(args);
|
||||
args.putBoolean("disableDiscover", isAkkoma);
|
||||
args.putBoolean("noAutoLoad", true);
|
||||
discoverFragment=new DiscoverFragment();
|
||||
discoverFragment.setArguments(args);
|
||||
@@ -304,7 +299,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
if(tab==R.id.tab_profile){
|
||||
ArrayList<String> options=new ArrayList<>();
|
||||
for(AccountSession session:AccountSessionManager.getInstance().getLoggedInAccounts()){
|
||||
options.add(session.self.displayName+"\n("+session.self.username+"@"+session.domain+")");
|
||||
options.add(session.self.getDisplayName()+"\n("+session.self.username+"@"+session.domain+")");
|
||||
}
|
||||
new AccountSwitcherSheet(getActivity(), this).show();
|
||||
return true;
|
||||
|
||||
@@ -61,7 +61,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
maxID=result.maxID;
|
||||
AccountSessionManager.get(accountID).filterStatuses(result.items, getFilterContext());
|
||||
onDataLoaded(result.items, !empty);
|
||||
if(result.isFromCache())
|
||||
if(result.isFromCache() && GlobalUserPreferences.loadNewPosts)
|
||||
loadNewPosts();
|
||||
}
|
||||
});
|
||||
@@ -74,7 +74,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
||||
if(parent != null && parent.isNewPostsBtnShown() && list.getChildAdapterPosition(list.getChildAt(0))<=getMainAdapterOffset()){
|
||||
if(parent!=null && parent.isNewPostsBtnShown() && list.getChildAdapterPosition(list.getChildAt(0))<=getMainAdapterOffset()){
|
||||
parent.hideNewPostsButton();
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
if(!getArguments().getBoolean("noAutoLoad")){
|
||||
if(!loaded && !dataLoading){
|
||||
loadData();
|
||||
}else if(!dataLoading){
|
||||
}else if(!dataLoading && GlobalUserPreferences.loadNewPosts){
|
||||
loadNewPosts();
|
||||
}
|
||||
}
|
||||
@@ -117,16 +117,19 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
}
|
||||
|
||||
public void onStatusCreated(Status status){
|
||||
if(status.reblog!=null) return;
|
||||
prependItems(Collections.singletonList(status), true);
|
||||
}
|
||||
|
||||
private void loadNewPosts(){
|
||||
if (!GlobalUserPreferences.loadNewPosts) return;
|
||||
dataLoading=true;
|
||||
// we only care about the data that was actually retrieved from the timeline api since
|
||||
// user-created statuses are probably in the wrong position
|
||||
List<Status> dataFromTimeline=data.stream().filter(s->!s.fromStatusCreated).collect(Collectors.toList());
|
||||
// The idea here is that we request the timeline such that if there are fewer than `limit` posts,
|
||||
// we'll get the currently topmost post as last in the response. This way we know there's no gap
|
||||
// between the existing and newly loaded parts of the timeline.
|
||||
String sinceID=data.size()>1 ? data.get(1).id : "1";
|
||||
String sinceID=dataFromTimeline.size()>1 ? dataFromTimeline.get(1).id : "1";
|
||||
currentRequest=new GetHomeTimeline(null, null, 20, sinceID, getLocalPrefs().timelineReplyVisibility)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
@@ -137,28 +140,31 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
return;
|
||||
Status last=result.get(result.size()-1);
|
||||
List<Status> toAdd;
|
||||
if(!data.isEmpty() && last.id.equals(data.get(0).id)){ // This part intersects with the existing one
|
||||
if(!dataFromTimeline.isEmpty() && last.id.equals(dataFromTimeline.get(0).id)){ // This part intersects with the existing one
|
||||
toAdd=new ArrayList<>(result.subList(0, result.size()-1)); // Remove the already known last post
|
||||
}else{
|
||||
last.hasGapAfter=last.id;
|
||||
toAdd=result;
|
||||
}
|
||||
if(!toAdd.isEmpty())
|
||||
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(new ArrayList<>(toAdd), false);
|
||||
// removing statuses that come up as duplicates (hopefully only posts and boosts that were locally created
|
||||
// and thus were already prepended to the timeline earlier)
|
||||
List<String> existingIds=data.stream().map(Status::getID).collect(Collectors.toList());
|
||||
toAdd.removeIf(s->existingIds.contains(s.getID()));
|
||||
List<Status> toAddUnfiltered=new ArrayList<>(toAdd);
|
||||
AccountSessionManager.get(accountID).filterStatuses(toAdd, getFilterContext());
|
||||
if(!toAdd.isEmpty()){
|
||||
prependItems(toAdd, true);
|
||||
if(parent != null && GlobalUserPreferences.showNewPostsButton) parent.showNewPostsButton();
|
||||
}
|
||||
if(toAddUnfiltered.isEmpty())
|
||||
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(toAddUnfiltered, false);
|
||||
refreshDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
currentRequest=null;
|
||||
dataLoading=false;
|
||||
refreshDone();
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
@@ -325,8 +331,8 @@ public class HomeTimelineFragment extends StatusListFragment {
|
||||
currentRequest=null;
|
||||
dataLoading=false;
|
||||
}
|
||||
if (parent != null) parent.hideNewPostsButton();
|
||||
super.onRefresh();
|
||||
if(parent!=null) parent.hideNewPostsButton();
|
||||
loadNewPosts();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -708,14 +708,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void bindHeaderView(){
|
||||
setTitle(account.displayName);
|
||||
setTitle(account.getDisplayName());
|
||||
setSubtitle(getResources().getQuantityString(R.plurals.x_posts, (int)(account.statusesCount%1000), account.statusesCount));
|
||||
ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(
|
||||
TextUtils.isEmpty(account.avatar) ? getSession().getDefaultAvatarUrl() :
|
||||
GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic,
|
||||
V.dp(100), V.dp(100)));
|
||||
ViewImageLoader.load(cover, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.header : account.headerStatic, 1000, 1000));
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(account.displayName);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(account.getDisplayName());
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(ssb, account.emojis);
|
||||
name.setText(ssb);
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
|
||||
knownAccounts.put(inReplyToAccount.id, inReplyToAccount);
|
||||
data.add(mainStatus);
|
||||
onAppendItems(Collections.singletonList(mainStatus));
|
||||
setTitle(HtmlParser.parseCustomEmoji(getString(R.string.post_from_user, mainStatus.account.displayName), mainStatus.account.emojis));
|
||||
setTitle(HtmlParser.parseCustomEmoji(getString(R.string.post_from_user, mainStatus.account.getDisplayName()), mainStatus.account.emojis));
|
||||
transitionFinished = getArguments().getBoolean("noTransition", false);
|
||||
|
||||
E.register(this);
|
||||
|
||||
@@ -332,9 +332,9 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment<DiscoverA
|
||||
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
if(account.emojis.isEmpty()){
|
||||
parsedName=account.displayName;
|
||||
parsedName= account.getDisplayName();
|
||||
}else{
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.getDisplayName(), account.emojis);
|
||||
emojiHelper.setText(new SpannableStringBuilder(parsedName).append(parsedBio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ 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.IsOnTop;
|
||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.SearchResult;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.SimpleViewHolder;
|
||||
@@ -156,7 +158,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||
}
|
||||
});
|
||||
|
||||
disableDiscover=getArguments().getBoolean("disableDiscover");
|
||||
disableDiscover=AccountSessionManager.get(accountID).getInstance().map(Instance::isAkkoma).orElse(false);
|
||||
searchView=view.findViewById(R.id.search_fragment);
|
||||
if(searchFragment==null){
|
||||
searchFragment=new SearchFragment();
|
||||
|
||||
@@ -115,7 +115,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
onDataLoaded(results.stream().map(sr->{
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, true);
|
||||
if(sr.type==SearchResult.Type.HASHTAG){
|
||||
vm.hashtagItem.onClick=()->openHashtag(sr);
|
||||
vm.hashtagItem.setOnClick(i->openHashtag(sr));
|
||||
}
|
||||
return vm;
|
||||
}).collect(Collectors.toList()), false);
|
||||
@@ -136,7 +136,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
.map(sr->{
|
||||
SearchResultViewModel vm=new SearchResultViewModel(sr, accountID, false);
|
||||
if(sr.type==SearchResult.Type.HASHTAG){
|
||||
vm.hashtagItem.onClick=()->openHashtag(sr);
|
||||
vm.hashtagItem.setOnClick(i->openHashtag(sr));
|
||||
}
|
||||
return vm;
|
||||
})
|
||||
@@ -433,11 +433,11 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
wrapSuicideDialog(()->deliverResult(currentQuery, null));
|
||||
}
|
||||
|
||||
private void onOpenURLClick(){
|
||||
private void onOpenURLClick(ListItem<?> item_){
|
||||
UiUtils.openURL(getContext(), accountID, searchViewHelper.getQuery(), false);
|
||||
}
|
||||
|
||||
private void onGoToHashtagClick(){
|
||||
private void onGoToHashtagClick(ListItem<?> item_){
|
||||
wrapSuicideDialog(()->{
|
||||
String q=searchViewHelper.getQuery();
|
||||
if(q.startsWith("#"))
|
||||
@@ -446,7 +446,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
});
|
||||
}
|
||||
|
||||
private void onGoToAccountClick(){
|
||||
private void onGoToAccountClick(ListItem<?> item_){
|
||||
String q=searchViewHelper.getQuery();
|
||||
if(!q.startsWith("@")){
|
||||
q="@"+q;
|
||||
@@ -463,11 +463,11 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
}).ifPresent(progress -> progress.wrapProgress((Activity) getContext(), R.string.loading, true));
|
||||
}
|
||||
|
||||
private void onGoToStatusSearchClick(){
|
||||
private void onGoToStatusSearchClick(ListItem<?> item_){
|
||||
wrapSuicideDialog(()->deliverResult(searchViewHelper.getQuery(), SearchResult.Type.STATUS));
|
||||
}
|
||||
|
||||
private void onGoToAccountSearchClick(){
|
||||
private void onGoToAccountSearchClick(ListItem<?> item_){
|
||||
wrapSuicideDialog(()->deliverResult(searchViewHelper.getQuery(), SearchResult.Type.ACCOUNT));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.joinmastodon.android.fragments.onboarding;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class EditFilterFragment extends BaseSettingsFragment<Void> implements On
|
||||
durationItem=new ListItem<>(R.string.settings_filter_duration, 0, this::onDurationClick),
|
||||
wordsItem=new ListItem<>(R.string.settings_filter_muted_words, 0, this::onWordsClick),
|
||||
contextItem=new ListItem<>(R.string.settings_filter_context, 0, this::onContextClick),
|
||||
cwItem=new CheckableListItem<>(R.string.settings_filter_show_cw, R.string.settings_filter_show_cw_explanation, CheckableListItem.Style.SWITCH, filter==null || filter.filterAction==FilterAction.WARN, ()->toggleCheckableItem(cwItem))
|
||||
cwItem=new CheckableListItem<>(R.string.settings_filter_show_cw, R.string.settings_filter_show_cw_explanation, CheckableListItem.Style.SWITCH, filter==null || filter.filterAction==FilterAction.WARN, this::toggleCheckableItem)
|
||||
));
|
||||
|
||||
if(filter!=null){
|
||||
@@ -117,7 +117,7 @@ public class EditFilterFragment extends BaseSettingsFragment<Void> implements On
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void onDurationClick(){
|
||||
private void onDurationClick(ListItem<Void> item_){
|
||||
int[] durationOptions={
|
||||
1800,
|
||||
3600,
|
||||
@@ -186,21 +186,21 @@ public class EditFilterFragment extends BaseSettingsFragment<Void> implements On
|
||||
alert.setOnDismissListener(dialog->callback.accept(null));
|
||||
}
|
||||
|
||||
private void onWordsClick(){
|
||||
private void onWordsClick(ListItem<Void> item){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelableArrayList("words", (ArrayList<? extends Parcelable>) keywords.stream().map(Parcels::wrap).collect(Collectors.toCollection(ArrayList::new)));
|
||||
Nav.goForResult(getActivity(), FilterWordsFragment.class, args, WORDS_RESULT, this);
|
||||
}
|
||||
|
||||
private void onContextClick(){
|
||||
private void onContextClick(ListItem<Void> item){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putSerializable("context", context);
|
||||
Nav.goForResult(getActivity(), FilterContextFragment.class, args, CONTEXT_RESULT, this);
|
||||
}
|
||||
|
||||
private void onDeleteClick(){
|
||||
private void onDeleteClick(ListItem<Void> item_){
|
||||
AlertDialog alert=new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(getString(R.string.settings_delete_filter_title, filter.title))
|
||||
.setMessage(R.string.settings_delete_filter_confirmation)
|
||||
|
||||
@@ -22,10 +22,9 @@ public class FilterContextFragment extends BaseSettingsFragment<FilterContext> i
|
||||
setTitle(R.string.settings_filter_context);
|
||||
context=(EnumSet<FilterContext>) getArguments().getSerializable("context");
|
||||
onDataLoaded(Arrays.stream(FilterContext.values()).map(c->{
|
||||
CheckableListItem<FilterContext> item=new CheckableListItem<>(c.getDisplayNameRes(), 0, CheckableListItem.Style.CHECKBOX, context.contains(c), null);
|
||||
CheckableListItem<FilterContext> item=new CheckableListItem<>(c.getDisplayNameRes(), 0, CheckableListItem.Style.CHECKBOX, context.contains(c), this::toggleCheckableItem);
|
||||
item.parentObject=c;
|
||||
item.isEnabled=true;
|
||||
item.onClick=()->toggleCheckableItem(item);
|
||||
return item;
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.IntEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.AlertDialog;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
@@ -27,6 +22,7 @@ import org.joinmastodon.android.model.FilterKeyword;
|
||||
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.utils.ActionModeHelper;
|
||||
import org.joinmastodon.android.ui.utils.SimpleTextWatcher;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.FloatingHintEditTextLayout;
|
||||
@@ -37,7 +33,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.grishka.appkit.FragmentStackActivity;
|
||||
import me.grishka.appkit.fragments.OnBackPressedListener;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
@@ -60,7 +55,7 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
FilterKeyword word=Parcels.unwrap(p);
|
||||
ListItem<FilterKeyword> item=new ListItem<>(word.keyword, null, null, word);
|
||||
item.isEnabled=true;
|
||||
item.onClick=()->onWordClick(item);
|
||||
item.setOnClick(this::onWordClick);
|
||||
return item;
|
||||
}).collect(Collectors.toList()));
|
||||
setHasOptionsMenu(true);
|
||||
@@ -114,7 +109,7 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||
inflater.inflate(R.menu.settings_filter_words, menu);
|
||||
inflater.inflate(R.menu.selectable_list, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,7 +169,7 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
w.keyword=input;
|
||||
ListItem<FilterKeyword> item=new ListItem<>(w.keyword, null, null, w);
|
||||
item.isEnabled=true;
|
||||
item.onClick=()->onWordClick(item);
|
||||
item.setOnClick(this::onWordClick);
|
||||
data.add(item);
|
||||
itemsAdapter.notifyItemInserted(data.size()-1);
|
||||
}else{
|
||||
@@ -228,29 +223,15 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
return;
|
||||
V.setVisibilityAnimated(fab, View.GONE);
|
||||
|
||||
actionMode=getActivity().startActionMode(new ActionMode.Callback(){
|
||||
actionMode=ActionModeHelper.startActionMode(this, ()->elevationOnScrollListener.getCurrentStatusBarColor(), new ActionMode.Callback(){
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu){
|
||||
ObjectAnimator anim=ObjectAnimator.ofInt(getActivity().getWindow(), "statusBarColor", elevationOnScrollListener.getCurrentStatusBarColor(), UiUtils.getThemeColor(getActivity(), R.attr.colorM3Primary));
|
||||
anim.setEvaluator(new IntEvaluator(){
|
||||
@Override
|
||||
public Integer evaluate(float fraction, Integer startValue, Integer endValue){
|
||||
return UiUtils.alphaBlendColors(startValue, endValue, fraction);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
((FragmentStackActivity) getActivity()).invalidateSystemBarColors(FilterWordsFragment.this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu){
|
||||
mode.getMenuInflater().inflate(R.menu.settings_filter_words_action_mode, menu);
|
||||
for(int i=0;i<menu.size();i++){
|
||||
Drawable icon=menu.getItem(i).getIcon().mutate();
|
||||
icon.setTint(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OnPrimary));
|
||||
menu.getItem(i).setIcon(icon);
|
||||
}
|
||||
deleteItem=menu.findItem(R.id.delete);
|
||||
return true;
|
||||
}
|
||||
@@ -266,21 +247,6 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode){
|
||||
leaveSelectionMode(true);
|
||||
ObjectAnimator anim=ObjectAnimator.ofInt(getActivity().getWindow(), "statusBarColor", UiUtils.getThemeColor(getActivity(), R.attr.colorM3Primary), elevationOnScrollListener.getCurrentStatusBarColor());
|
||||
anim.setEvaluator(new IntEvaluator(){
|
||||
@Override
|
||||
public Integer evaluate(float fraction, Integer startValue, Integer endValue){
|
||||
return UiUtils.alphaBlendColors(startValue, endValue, fraction);
|
||||
}
|
||||
});
|
||||
anim.addListener(new AnimatorListenerAdapter(){
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation){
|
||||
getActivity().getWindow().setStatusBarColor(0);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
((FragmentStackActivity) getActivity()).invalidateSystemBarColors(FilterWordsFragment.this);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -289,7 +255,7 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
ListItem<FilterKeyword> item=data.get(i);
|
||||
CheckableListItem<FilterKeyword> newItem=new CheckableListItem<>(item.title, null, CheckableListItem.Style.CHECKBOX, selectAll, null);
|
||||
newItem.isEnabled=true;
|
||||
newItem.onClick=()->onSelectionModeWordClick(newItem);
|
||||
newItem.setOnClick(this::onSelectionModeWordClick);
|
||||
newItem.parentObject=item.parentObject;
|
||||
if(selectAll)
|
||||
selectedItems.add(newItem);
|
||||
@@ -313,7 +279,7 @@ public class FilterWordsFragment extends BaseSettingsFragment<FilterKeyword> imp
|
||||
ListItem<FilterKeyword> item=data.get(i);
|
||||
ListItem<FilterKeyword> newItem=new ListItem<>(item.title, null, null);
|
||||
newItem.isEnabled=true;
|
||||
newItem.onClick=()->onWordClick(newItem);
|
||||
newItem.setOnClick(this::onWordClick);
|
||||
newItem.parentObject=item.parentObject;
|
||||
data.set(i, newItem);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.imageloader.ImageCache;
|
||||
@@ -29,6 +28,8 @@ import me.grishka.appkit.utils.V;
|
||||
|
||||
public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> implements HasAccountID{
|
||||
private ListItem<Void> mediaCacheItem;
|
||||
private AccountSession session;
|
||||
private boolean timelineCacheCleared=false;
|
||||
|
||||
// MOSHIDON
|
||||
private ListItem<Void> clearRecentEmojisItem;
|
||||
@@ -36,19 +37,26 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(getString(R.string.about_app, getString(R.string.mo_app_name)));
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
session=AccountSessionManager.get(accountID);
|
||||
onDataLoaded(List.of(
|
||||
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_donate_url))),
|
||||
new ListItem<>(R.string.mo_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_repo_url))),
|
||||
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/terms")),
|
||||
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),
|
||||
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_donate_url))),
|
||||
new ListItem<>(R.string.mo_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_repo_url))),
|
||||
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")),
|
||||
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),
|
||||
clearRecentEmojisItem=new ListItem<>(R.string.mo_clear_recent_emoji, 0, this::onClearRecentEmojisClick),
|
||||
mediaCacheItem=new ListItem<>(R.string.settings_clear_cache, 0, this::onClearMediaCacheClick)
|
||||
mediaCacheItem=new ListItem<>(R.string.settings_clear_cache, 0, this::onClearMediaCacheClick),
|
||||
new ListItem<>(getString(R.string.sk_settings_clear_timeline_cache), session.domain, this::onClearTimelineCacheClick)
|
||||
));
|
||||
|
||||
updateMediaCacheItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHidden(){
|
||||
super.onHidden();
|
||||
if(timelineCacheCleared) getActivity().recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
@@ -68,7 +76,7 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private void onClearMediaCacheClick(){
|
||||
private void onClearMediaCacheClick(ListItem<?> item){
|
||||
MastodonAPIController.runInBackground(()->{
|
||||
Activity activity=getActivity();
|
||||
ImageCache.getInstance(getActivity()).clear();
|
||||
@@ -79,6 +87,12 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||
});
|
||||
}
|
||||
|
||||
private void onClearTimelineCacheClick(ListItem<?> item){
|
||||
session.getCacheController().putHomeTimeline(List.of(), true);
|
||||
Toast.makeText(getContext(), R.string.sk_timeline_cache_cleared, Toast.LENGTH_SHORT).show();
|
||||
timelineCacheCleared=true;
|
||||
}
|
||||
|
||||
private void onClearRecentEmojisClick(){
|
||||
getLocalPrefs().recentCustomEmoji=new ArrayList<>();
|
||||
getLocalPrefs().save();
|
||||
|
||||
@@ -49,24 +49,24 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
|
||||
List<ListItem<Void>> items = new ArrayList<>(List.of(
|
||||
languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(getContext()) : null, R.drawable.ic_fluent_local_language_24_regular, this::onDefaultLanguageClick),
|
||||
altTextItem=new CheckableListItem<>(R.string.settings_alt_text_reminders, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.altTextReminders, R.drawable.ic_fluent_image_alt_text_24_regular, ()->toggleCheckableItem(altTextItem)),
|
||||
altTextItem=new CheckableListItem<>(R.string.settings_alt_text_reminders, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.altTextReminders, R.drawable.ic_fluent_image_alt_text_24_regular, i->toggleCheckableItem(altTextItem)),
|
||||
showPostsWithoutAltItem=new CheckableListItem<>(R.string.mo_settings_show_posts_without_alt, R.string.mo_settings_show_posts_without_alt_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showPostsWithoutAlt, R.drawable.ic_fluent_eye_tracking_on_24_regular, ()->toggleCheckableItem(showPostsWithoutAltItem)),
|
||||
playGifsItem=new CheckableListItem<>(R.string.settings_gif, R.string.mo_setting_play_gif_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.playGifs, R.drawable.ic_fluent_gif_24_regular, ()->toggleCheckableItem(playGifsItem)),
|
||||
playGifsItem=new CheckableListItem<>(R.string.settings_gif, R.string.mo_setting_play_gif_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.playGifs, R.drawable.ic_fluent_gif_24_regular, i->toggleCheckableItem(playGifsItem)),
|
||||
unlistedRepliesItem=new CheckableListItem<>(R.string.mo_change_default_reply_visibility_to_unlisted, R.string.mo_setting_default_reply_privacy_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.defaultToUnlistedReplies, R.drawable.ic_fluent_lock_open_24_regular, ()->toggleCheckableItem(unlistedRepliesItem)),
|
||||
overlayMediaItem=new CheckableListItem<>(R.string.sk_settings_continues_playback, R.string.sk_settings_continues_playback_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.overlayMedia, R.drawable.ic_fluent_play_circle_hint_24_regular, ()->toggleCheckableItem(overlayMediaItem)),
|
||||
customTabsItem=new CheckableListItem<>(R.string.settings_custom_tabs, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.useCustomTabs, R.drawable.ic_fluent_link_24_regular, ()->toggleCheckableItem(customTabsItem)),
|
||||
confirmUnfollowItem=new CheckableListItem<>(R.string.settings_confirm_unfollow, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmUnfollow, R.drawable.ic_fluent_person_delete_24_regular, ()->toggleCheckableItem(confirmUnfollowItem)),
|
||||
confirmBoostItem=new CheckableListItem<>(R.string.settings_confirm_boost, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmBoost, R.drawable.ic_fluent_arrow_repeat_all_24_regular, ()->toggleCheckableItem(confirmBoostItem)),
|
||||
confirmDeleteItem=new CheckableListItem<>(R.string.settings_confirm_delete_post, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmDeletePost, R.drawable.ic_fluent_delete_24_regular, ()->toggleCheckableItem(confirmDeleteItem)),
|
||||
overlayMediaItem=new CheckableListItem<>(R.string.sk_settings_continues_playback, R.string.sk_settings_continues_playback_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.overlayMedia, R.drawable.ic_fluent_play_circle_hint_24_regular, i->toggleCheckableItem(overlayMediaItem)),
|
||||
customTabsItem=new CheckableListItem<>(R.string.settings_custom_tabs, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.useCustomTabs, R.drawable.ic_fluent_link_24_regular, i->toggleCheckableItem(customTabsItem)),
|
||||
confirmUnfollowItem=new CheckableListItem<>(R.string.settings_confirm_unfollow, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmUnfollow, R.drawable.ic_fluent_person_delete_24_regular, i->toggleCheckableItem(confirmUnfollowItem)),
|
||||
confirmBoostItem=new CheckableListItem<>(R.string.settings_confirm_boost, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmBoost, R.drawable.ic_fluent_arrow_repeat_all_24_regular, i->toggleCheckableItem(confirmBoostItem)),
|
||||
confirmDeleteItem=new CheckableListItem<>(R.string.settings_confirm_delete_post, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.confirmDeletePost, R.drawable.ic_fluent_delete_24_regular, i->toggleCheckableItem(confirmDeleteItem)),
|
||||
prefixRepliesItem=new ListItem<>(R.string.sk_settings_prefix_reply_cw_with_re, getPrefixWithRepliesString(), R.drawable.ic_fluent_arrow_reply_24_regular, this::onPrefixRepliesClick),
|
||||
forwardReportsItem=new CheckableListItem<>(R.string.sk_settings_forward_report_default, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.forwardReportDefault, R.drawable.ic_fluent_arrow_forward_24_regular, ()->toggleCheckableItem(forwardReportsItem)),
|
||||
loadNewPostsItem=new CheckableListItem<>(R.string.sk_settings_load_new_posts, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.loadNewPosts, R.drawable.ic_fluent_arrow_sync_24_regular, this::onLoadNewPostsClick),
|
||||
seeNewPostsBtnItem=new CheckableListItem<>(R.string.sk_settings_see_new_posts_button, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNewPostsButton, R.drawable.ic_fluent_arrow_up_24_regular, ()->toggleCheckableItem(seeNewPostsBtnItem)),
|
||||
remoteLoadingItem=new CheckableListItem<>(R.string.sk_settings_allow_remote_loading, R.string.sk_settings_allow_remote_loading_explanation, CheckableListItem.Style.SWITCH, GlobalUserPreferences.allowRemoteLoading, R.drawable.ic_fluent_communication_24_regular, ()->toggleCheckableItem(remoteLoadingItem)),
|
||||
forwardReportsItem=new CheckableListItem<>(R.string.sk_settings_forward_report_default, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.forwardReportDefault, R.drawable.ic_fluent_arrow_forward_24_regular, i->toggleCheckableItem(forwardReportsItem)),
|
||||
loadNewPostsItem=new CheckableListItem<>(R.string.sk_settings_load_new_posts, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.loadNewPosts, R.drawable.ic_fluent_arrow_sync_24_regular, i->onLoadNewPostsClick()),
|
||||
seeNewPostsBtnItem=new CheckableListItem<>(R.string.sk_settings_see_new_posts_button, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNewPostsButton, R.drawable.ic_fluent_arrow_up_24_regular, i->toggleCheckableItem(seeNewPostsBtnItem)),
|
||||
remoteLoadingItem=new CheckableListItem<>(R.string.sk_settings_allow_remote_loading, R.string.sk_settings_allow_remote_loading_explanation, CheckableListItem.Style.SWITCH, GlobalUserPreferences.allowRemoteLoading, R.drawable.ic_fluent_communication_24_regular, i->toggleCheckableItem(remoteLoadingItem)),
|
||||
mentionRebloggerAutomaticallyItem=new CheckableListItem<>(R.string.mo_mention_reblogger_automatically, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.mentionRebloggerAutomatically, R.drawable.ic_fluent_comment_mention_24_regular, ()->toggleCheckableItem(mentionRebloggerAutomaticallyItem)),
|
||||
hapticFeedbackItem=new CheckableListItem<>(R.string.mo_haptic_feedback, R.string.mo_setting_haptic_feedback_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.hapticFeedback, R.drawable.ic_fluent_phone_vibrate_24_regular,()->toggleCheckableItem(hapticFeedbackItem), true),
|
||||
showBoostsItem=new CheckableListItem<>(R.string.sk_settings_show_boosts, 0, CheckableListItem.Style.SWITCH, lp.showBoosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, ()->toggleCheckableItem(showBoostsItem)),
|
||||
showRepliesItem=new CheckableListItem<>(R.string.sk_settings_show_replies, 0, CheckableListItem.Style.SWITCH, lp.showReplies, R.drawable.ic_fluent_arrow_reply_24_regular, ()->toggleCheckableItem(showRepliesItem))
|
||||
showBoostsItem=new CheckableListItem<>(R.string.sk_settings_show_boosts, 0, CheckableListItem.Style.SWITCH, lp.showBoosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, i->toggleCheckableItem(showBoostsItem)),
|
||||
showRepliesItem=new CheckableListItem<>(R.string.sk_settings_show_replies, 0, CheckableListItem.Style.SWITCH, lp.showReplies, R.drawable.ic_fluent_arrow_reply_24_regular, i->toggleCheckableItem(showRepliesItem))
|
||||
));
|
||||
|
||||
if(isInstanceAkkoma()) items.add(
|
||||
@@ -100,7 +100,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
private void onDefaultLanguageClick(){
|
||||
private void onDefaultLanguageClick(ListItem<?> item){
|
||||
if (languageResolver == null) return;
|
||||
ComposeLanguageAlertViewController vc=new ComposeLanguageAlertViewController(getActivity(), null, new ComposeLanguageAlertViewController.SelectedOption(postLanguage), null, languageResolver);
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
@@ -119,14 +119,14 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onPrefixRepliesClick(){
|
||||
private void onPrefixRepliesClick(ListItem<?> item){
|
||||
int selected=GlobalUserPreferences.prefixReplies.ordinal();
|
||||
int[] newSelected={selected};
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.sk_settings_prefix_reply_cw_with_re)
|
||||
.setSingleChoiceItems((String[]) IntStream.of(R.string.sk_settings_prefix_replies_never, R.string.sk_settings_prefix_replies_always, R.string.sk_settings_prefix_replies_to_others).mapToObj(this::getString).toArray(String[]::new),
|
||||
selected, (dlg, item)->newSelected[0]=item)
|
||||
.setPositiveButton(R.string.ok, (dlg, item)->{
|
||||
selected, (dlg, which)->newSelected[0]=which)
|
||||
.setPositiveButton(R.string.ok, (dlg, which)->{
|
||||
GlobalUserPreferences.prefixReplies=GlobalUserPreferences.PrefixRepliesMode.values()[newSelected[0]];
|
||||
prefixRepliesItem.subtitleRes=getPrefixWithRepliesString();
|
||||
rebindItem(prefixRepliesItem);
|
||||
@@ -135,7 +135,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onReplyVisibilityClick(){
|
||||
private void onReplyVisibilityClick(ListItem<?> item){
|
||||
AccountLocalPreferences lp=getLocalPrefs();
|
||||
int selected=lp.timelineReplyVisibility==null ? 2 : switch(lp.timelineReplyVisibility){
|
||||
case "following" -> 0;
|
||||
@@ -146,8 +146,8 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.sk_settings_prefix_reply_cw_with_re)
|
||||
.setSingleChoiceItems((String[]) IntStream.of(R.string.sk_settings_reply_visibility_following, R.string.sk_settings_reply_visibility_self, R.string.sk_settings_reply_visibility_all).mapToObj(this::getString).toArray(String[]::new),
|
||||
selected, (dlg, item)->newSelected[0]=item)
|
||||
.setPositiveButton(R.string.ok, (dlg, item)->{
|
||||
selected, (dlg, which)->newSelected[0]=which)
|
||||
.setPositiveButton(R.string.ok, (dlg, which)->{
|
||||
lp.timelineReplyVisibility=switch(newSelected[0]){
|
||||
case 0 -> "following";
|
||||
case 1 -> "self";
|
||||
@@ -187,6 +187,8 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
GlobalUserPreferences.showPostsWithoutAlt=showPostsWithoutAltItem.checked;
|
||||
GlobalUserPreferences.save();
|
||||
AccountLocalPreferences lp=getLocalPrefs();
|
||||
boolean restartPlease=lp.showBoosts!=showBoostsItem.checked
|
||||
|| lp.showReplies!=showRepliesItem.checked;
|
||||
lp.showBoosts=showBoostsItem.checked;
|
||||
lp.showReplies=showRepliesItem.checked;
|
||||
lp.save();
|
||||
@@ -197,6 +199,7 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
|
||||
s.preferences.postingDefaultLanguage=newPostLanguage.language.getLanguage();
|
||||
s.savePreferencesLater();
|
||||
}
|
||||
if(restartPlease) getActivity().recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,7 +39,7 @@ public class SettingsDebugFragment extends BaseSettingsFragment<Void>{
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
private void onTestEmailConfirmClick(){
|
||||
private void onTestEmailConfirmClick(ListItem<?> item){
|
||||
AccountSession sess=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
sess.activated=false;
|
||||
sess.activationInfo=new AccountActivationInfo("test@email", System.currentTimeMillis());
|
||||
@@ -49,18 +49,18 @@ public class SettingsDebugFragment extends BaseSettingsFragment<Void>{
|
||||
Nav.goClearingStack(getActivity(), AccountActivationFragment.class, args);
|
||||
}
|
||||
|
||||
private void onForceSelfUpdateClick(){
|
||||
private void onForceSelfUpdateClick(ListItem<?> item){
|
||||
GithubSelfUpdater.forceUpdate=true;
|
||||
GithubSelfUpdater.getInstance().maybeCheckForUpdates();
|
||||
restartUI();
|
||||
}
|
||||
|
||||
private void onResetUpdaterClick(){
|
||||
private void onResetUpdaterClick(ListItem<?> item){
|
||||
GithubSelfUpdater.getInstance().reset();
|
||||
restartUI();
|
||||
}
|
||||
|
||||
private void onResetDiscoverBannersClick(){
|
||||
private void onResetDiscoverBannersClick(ListItem<?> item){
|
||||
DiscoverInfoBannerHelper.reset();
|
||||
restartUI();
|
||||
}
|
||||
|
||||
@@ -60,34 +60,34 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
onDataLoaded(List.of(
|
||||
themeItem=new ListItem<>(R.string.settings_theme, getAppearanceValue(), R.drawable.ic_fluent_weather_moon_24_regular, this::onAppearanceClick),
|
||||
colorItem=new ListItem<>(getString(R.string.sk_settings_color_palette), getColorPaletteValue(), R.drawable.ic_fluent_color_24_regular, this::onColorClick),
|
||||
trueBlackModeItem=new CheckableListItem<>(R.string.sk_settings_true_black, R.string.mo_setting_true_black_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.trueBlackTheme, R.drawable.ic_fluent_dark_theme_24_regular, this::onTrueBlackModeClick, true),
|
||||
trueBlackModeItem=new CheckableListItem<>(R.string.sk_settings_true_black, R.string.mo_setting_true_black_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.trueBlackTheme, R.drawable.ic_fluent_dark_theme_24_regular, i->onTrueBlackModeClick(), true),
|
||||
publishTextItem=new ListItem<>(getString(R.string.sk_settings_publish_button_text), getPublishButtonText(), R.drawable.ic_fluent_send_24_regular, this::onPublishTextClick),
|
||||
autoRevealCWsItem=new ListItem<>(R.string.sk_settings_auto_reveal_equal_spoilers, getAutoRevealSpoilersText(), R.drawable.ic_fluent_eye_24_regular, this::onAutoRevealSpoilersClick),
|
||||
relocatePublishButtonItem=new CheckableListItem<>(R.string.mo_relocate_publish_button, R.string.mo_setting_relocate_publish_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.relocatePublishButton, R.drawable.ic_fluent_arrow_autofit_down_24_regular, ()->toggleCheckableItem(relocatePublishButtonItem)),
|
||||
revealCWsItem=new CheckableListItem<>(R.string.sk_settings_always_reveal_content_warnings, 0, CheckableListItem.Style.SWITCH, lp.revealCWs, R.drawable.ic_fluent_chat_warning_24_regular, ()->toggleCheckableItem(revealCWsItem)),
|
||||
hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_fluent_flag_24_regular, ()->toggleCheckableItem(hideSensitiveMediaItem)),
|
||||
revealCWsItem=new CheckableListItem<>(R.string.sk_settings_always_reveal_content_warnings, 0, CheckableListItem.Style.SWITCH, lp.revealCWs, R.drawable.ic_fluent_chat_warning_24_regular, i->toggleCheckableItem(revealCWsItem)),
|
||||
hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_fluent_flag_24_regular, i->toggleCheckableItem(hideSensitiveMediaItem)),
|
||||
showMediaPreviewItem=new CheckableListItem<>(R.string.mo_show_media_preview, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showMediaPreview, R.drawable.ic_fluent_image_24_regular, ()->toggleCheckableItem(showMediaPreviewItem)),
|
||||
interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, R.string.mo_setting_interaction_count_summary, CheckableListItem.Style.SWITCH, lp.showInteractionCounts, R.drawable.ic_fluent_number_row_24_regular, ()->toggleCheckableItem(interactionCountsItem)),
|
||||
emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, lp.customEmojiInNames, R.drawable.ic_fluent_emoji_24_regular, ()->toggleCheckableItem(emojiInNamesItem)),
|
||||
marqueeItem=new CheckableListItem<>(R.string.sk_settings_enable_marquee, R.string.mo_setting_marquee_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.toolbarMarquee, R.drawable.ic_fluent_text_more_24_regular, ()->toggleCheckableItem(marqueeItem)),
|
||||
reduceMotionItem=new CheckableListItem<>(R.string.sk_settings_reduce_motion, R.string.mo_setting_reduced_motion_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.reduceMotion, R.drawable.ic_fluent_star_emphasis_24_regular, ()->toggleCheckableItem(reduceMotionItem)),
|
||||
interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, R.string.mo_setting_interaction_count_summary, CheckableListItem.Style.SWITCH, lp.showInteractionCounts, R.drawable.ic_fluent_number_row_24_regular, i->toggleCheckableItem(interactionCountsItem)),
|
||||
emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, lp.customEmojiInNames, R.drawable.ic_fluent_emoji_24_regular, i->toggleCheckableItem(emojiInNamesItem)),
|
||||
marqueeItem=new CheckableListItem<>(R.string.sk_settings_enable_marquee, R.string.mo_setting_marquee_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.toolbarMarquee, R.drawable.ic_fluent_text_more_24_regular, i->toggleCheckableItem(marqueeItem)),
|
||||
reduceMotionItem=new CheckableListItem<>(R.string.sk_settings_reduce_motion, R.string.mo_setting_reduced_motion_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.reduceMotion, R.drawable.ic_fluent_star_emphasis_24_regular, i->toggleCheckableItem(reduceMotionItem)),
|
||||
enableDoubleTapToSearchItem=new CheckableListItem<>(R.string.mo_double_tap_to_search, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.doubleTapToSearch, R.drawable.ic_fluent_search_24_regular, ()->toggleCheckableItem(enableDoubleTapToSearchItem)),
|
||||
disableSwipeItem=new CheckableListItem<>(R.string.sk_settings_tabs_disable_swipe, R.string.mo_setting_disable_swipe_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableSwipe, R.drawable.ic_fluent_swipe_right_24_regular, ()->toggleCheckableItem(disableSwipeItem)),
|
||||
disableSwipeItem=new CheckableListItem<>(R.string.sk_settings_tabs_disable_swipe, R.string.mo_setting_disable_swipe_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableSwipe, R.drawable.ic_fluent_swipe_right_24_regular, i->toggleCheckableItem(disableSwipeItem)),
|
||||
enableDoubleTapToSwipeItem=new CheckableListItem<>(R.string.mo_double_tap_to_swipe_between_tabs, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.doubleTapToSwipe, R.drawable.ic_fluent_double_tap_swipe_right_24_regular, ()->toggleCheckableItem(enableDoubleTapToSwipeItem)),
|
||||
altIndicatorItem=new CheckableListItem<>(R.string.sk_settings_show_alt_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showAltIndicator, R.drawable.ic_fluent_scan_text_24_regular, ()->toggleCheckableItem(altIndicatorItem)),
|
||||
noAltIndicatorItem=new CheckableListItem<>(R.string.sk_settings_show_no_alt_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNoAltIndicator, R.drawable.ic_fluent_important_24_regular, ()->toggleCheckableItem(noAltIndicatorItem)),
|
||||
collapsePostsItem=new CheckableListItem<>(R.string.sk_settings_collapse_long_posts, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.collapseLongPosts, R.drawable.ic_fluent_chevron_down_24_regular, ()->toggleCheckableItem(collapsePostsItem)),
|
||||
spectatorModeItem=new CheckableListItem<>(R.string.sk_settings_hide_interaction, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.spectatorMode, R.drawable.ic_fluent_star_off_24_regular, ()->toggleCheckableItem(spectatorModeItem)),
|
||||
hideFabItem=new CheckableListItem<>(R.string.sk_settings_hide_fab, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.autoHideFab, R.drawable.ic_fluent_edit_24_regular, ()->toggleCheckableItem(hideFabItem)),
|
||||
translateOpenedItem=new CheckableListItem<>(R.string.sk_settings_translate_only_opened, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.translateButtonOpenedOnly, R.drawable.ic_fluent_translate_24_regular, ()->toggleCheckableItem(translateOpenedItem)),
|
||||
likeIconItem=new CheckableListItem<>(R.string.sk_settings_like_icon, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.likeIcon, R.drawable.ic_fluent_heart_24_regular, ()->toggleCheckableItem(likeIconItem)),
|
||||
underlinedLinksItem=new CheckableListItem<>(R.string.sk_settings_underlined_links, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.underlinedLinks, R.drawable.ic_fluent_text_underline_24_regular, ()->toggleCheckableItem(underlinedLinksItem)),
|
||||
altIndicatorItem=new CheckableListItem<>(R.string.sk_settings_show_alt_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showAltIndicator, R.drawable.ic_fluent_scan_text_24_regular, i->toggleCheckableItem(altIndicatorItem)),
|
||||
noAltIndicatorItem=new CheckableListItem<>(R.string.sk_settings_show_no_alt_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNoAltIndicator, R.drawable.ic_fluent_important_24_regular, i->toggleCheckableItem(noAltIndicatorItem)),
|
||||
collapsePostsItem=new CheckableListItem<>(R.string.sk_settings_collapse_long_posts, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.collapseLongPosts, R.drawable.ic_fluent_chevron_down_24_regular, i->toggleCheckableItem(collapsePostsItem)),
|
||||
spectatorModeItem=new CheckableListItem<>(R.string.sk_settings_hide_interaction, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.spectatorMode, R.drawable.ic_fluent_star_off_24_regular, i->toggleCheckableItem(spectatorModeItem)),
|
||||
hideFabItem=new CheckableListItem<>(R.string.sk_settings_hide_fab, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.autoHideFab, R.drawable.ic_fluent_edit_24_regular, i->toggleCheckableItem(hideFabItem)),
|
||||
translateOpenedItem=new CheckableListItem<>(R.string.sk_settings_translate_only_opened, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.translateButtonOpenedOnly, R.drawable.ic_fluent_translate_24_regular, i->toggleCheckableItem(translateOpenedItem)),
|
||||
likeIconItem=new CheckableListItem<>(R.string.sk_settings_like_icon, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.likeIcon, R.drawable.ic_fluent_heart_24_regular, i->toggleCheckableItem(likeIconItem)),
|
||||
underlinedLinksItem=new CheckableListItem<>(R.string.sk_settings_underlined_links, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.underlinedLinks, R.drawable.ic_fluent_text_underline_24_regular, i->toggleCheckableItem(underlinedLinksItem)),
|
||||
showPostDividersItem=new CheckableListItem<>(R.string.mo_enable_dividers, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showDividers, R.drawable.ic_fluent_timeline_24_regular, ()->toggleCheckableItem(showPostDividersItem)),
|
||||
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, ()->toggleCheckableItem(disablePillItem)),
|
||||
showNavigationLabelsItem=new CheckableListItem<>(R.string.sk_settings_show_labels_in_navigation_bar, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNavigationLabels, R.drawable.ic_fluent_tag_24_regular, ()->toggleCheckableItem(showNavigationLabelsItem), true),
|
||||
pronounsInTimelinesItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_timelines, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInTimelines, 0, ()->toggleCheckableItem(pronounsInTimelinesItem)),
|
||||
pronounsInThreadsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_threads, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInThreads, 0, ()->toggleCheckableItem(pronounsInThreadsItem)),
|
||||
pronounsInUserListingsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_user_listings, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInUserListings, 0, ()->toggleCheckableItem(pronounsInUserListingsItem))
|
||||
disablePillItem=new CheckableListItem<>(R.string.sk_disable_pill_shaped_active_indicator, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.disableM3PillActiveIndicator, R.drawable.ic_fluent_pill_24_regular, i->toggleCheckableItem(disablePillItem)),
|
||||
showNavigationLabelsItem=new CheckableListItem<>(R.string.sk_settings_show_labels_in_navigation_bar, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showNavigationLabels, R.drawable.ic_fluent_tag_24_regular, i->toggleCheckableItem(showNavigationLabelsItem), true),
|
||||
pronounsInTimelinesItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_timelines, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInTimelines, 0, i->toggleCheckableItem(pronounsInTimelinesItem)),
|
||||
pronounsInThreadsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_threads, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInThreads, 0, i->toggleCheckableItem(pronounsInThreadsItem)),
|
||||
pronounsInUserListingsItem=new CheckableListItem<>(R.string.sk_settings_display_pronouns_in_user_listings, 0, CheckableListItem.Style.CHECKBOX, GlobalUserPreferences.displayPronounsInUserListings, 0, i->toggleCheckableItem(pronounsInUserListingsItem))
|
||||
));
|
||||
trueBlackModeItem.checkedChangeListener=checked->onTrueBlackModeClick();
|
||||
}
|
||||
@@ -114,7 +114,6 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
|| GlobalUserPreferences.showMediaPreview!=showMediaPreviewItem.checked
|
||||
|| GlobalUserPreferences.showDividers!=showPostDividersItem.checked
|
||||
|| GlobalUserPreferences.likeIcon!=likeIconItem.checked;
|
||||
;
|
||||
|
||||
lp.revealCWs=revealCWsItem.checked;
|
||||
lp.hideSensitiveMedia=hideSensitiveMediaItem.checked;
|
||||
@@ -183,7 +182,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
maybeApplyNewThemeRightNow(null, null, prev);
|
||||
}
|
||||
|
||||
private void onAppearanceClick(){
|
||||
private void onAppearanceClick(ListItem<?> item_){
|
||||
int selected=switch(GlobalUserPreferences.theme){
|
||||
case LIGHT -> 0;
|
||||
case DARK -> 1;
|
||||
@@ -214,7 +213,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onColorClick(){
|
||||
private void onColorClick(ListItem<?> item_){
|
||||
boolean multiple=AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1;
|
||||
int indexOffset=multiple ? 1 : 0;
|
||||
int selected=lp.color==null ? 0 : lp.color.ordinal() + indexOffset;
|
||||
@@ -251,7 +250,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void onPublishTextClick(){
|
||||
private void onPublishTextClick(ListItem<?> item_){
|
||||
TextInputFrameLayout input = new TextInputFrameLayout(
|
||||
getContext(),
|
||||
getString(R.string.publish),
|
||||
@@ -274,7 +273,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onAutoRevealSpoilersClick(){
|
||||
private void onAutoRevealSpoilersClick(ListItem<?> item_){
|
||||
int selected=GlobalUserPreferences.autoRevealEqualSpoilers.ordinal();
|
||||
int[] newSelected={selected};
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
|
||||
@@ -67,16 +67,14 @@ public class SettingsFiltersFragment extends BaseSettingsFragment<Filter>{
|
||||
Nav.go(getActivity(), EditFilterFragment.class, args);
|
||||
}
|
||||
|
||||
private void onAddFilterClick(){
|
||||
private void onAddFilterClick(ListItem<?> item){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), EditFilterFragment.class, args);
|
||||
}
|
||||
|
||||
private ListItem<Filter> makeListItem(Filter f){
|
||||
ListItem<Filter> item=new ListItem<>(f.title, getString(f.isActive() ? R.string.filter_active : R.string.filter_inactive), null, f);
|
||||
item.onClick=()->onFilterClick(item);
|
||||
item.isEnabled=true;
|
||||
ListItem<Filter> item=new ListItem<>(f.title, getString(f.isActive() ? R.string.filter_active : R.string.filter_inactive), this::onFilterClick, f);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
@@ -36,15 +37,15 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
lp=s.getLocalPreferences();
|
||||
onDataLoaded(List.of(
|
||||
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_fluent_server_24_regular, this::onServerClick),
|
||||
new ListItem<>(R.string.sk_settings_profile, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/profile")),
|
||||
new ListItem<>(R.string.sk_settings_posting, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/preferences/other")),
|
||||
new ListItem<>(R.string.sk_settings_auth, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/auth/edit"), 0, true),
|
||||
contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, this::onContentTypeClick),
|
||||
new ListItem<>(R.string.sk_settings_profile, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/profile")),
|
||||
new ListItem<>(R.string.sk_settings_posting, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/preferences/other")),
|
||||
new ListItem<>(R.string.sk_settings_auth, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/auth/edit"), 0, true),
|
||||
contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, i->onContentTypeClick()),
|
||||
defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick, 0, true),
|
||||
emojiReactionsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions, R.string.sk_settings_emoji_reactions_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsEnabled, R.drawable.ic_fluent_emoji_laugh_24_regular, this::onEmojiReactionsClick),
|
||||
emojiReactionsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions, R.string.sk_settings_emoji_reactions_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsEnabled, R.drawable.ic_fluent_emoji_laugh_24_regular, i->onEmojiReactionsClick()),
|
||||
showEmojiReactionsItem=new ListItem<>(R.string.sk_settings_show_emoji_reactions, getShowEmojiReactionsString(), R.drawable.ic_fluent_emoji_24_regular, this::onShowEmojiReactionsClick, 0, true),
|
||||
localOnlyItem=new CheckableListItem<>(R.string.sk_settings_support_local_only, R.string.sk_settings_local_only_explanation, CheckableListItem.Style.SWITCH, lp.localOnlySupported, R.drawable.ic_fluent_eye_24_regular, this::onLocalOnlyClick),
|
||||
glitchModeItem=new CheckableListItem<>(R.string.sk_settings_glitch_instance, R.string.sk_settings_glitch_mode_explanation, CheckableListItem.Style.SWITCH, lp.glitchInstance, R.drawable.ic_fluent_eye_24_filled, ()->toggleCheckableItem(glitchModeItem))
|
||||
localOnlyItem=new CheckableListItem<>(R.string.sk_settings_support_local_only, R.string.sk_settings_local_only_explanation, CheckableListItem.Style.SWITCH, lp.localOnlySupported, R.drawable.ic_fluent_eye_24_regular, i->onLocalOnlyClick()),
|
||||
glitchModeItem=new CheckableListItem<>(R.string.sk_settings_glitch_instance, R.string.sk_settings_glitch_mode_explanation, CheckableListItem.Style.SWITCH, lp.glitchInstance, R.drawable.ic_fluent_eye_24_filled, i->toggleCheckableItem(glitchModeItem))
|
||||
));
|
||||
contentTypesItem.checkedChangeListener=checked->onContentTypeClick();
|
||||
defaultContentTypeItem.isEnabled=contentTypesItem.checked;
|
||||
@@ -68,7 +69,7 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
E.post(new StatusDisplaySettingsChangedEvent(accountID));
|
||||
}
|
||||
|
||||
private void onServerClick(){
|
||||
private void onServerClick(ListItem<?> item){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
Nav.go(getActivity(), SettingsServerFragment.class, args);
|
||||
@@ -87,23 +88,23 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
defaultContentTypeItem.subtitleRes=lp.defaultContentType.getName();
|
||||
}
|
||||
|
||||
private void onDefaultContentTypeClick(){
|
||||
int selected=lp.defaultContentType.ordinal();
|
||||
int[] newSelected={selected};
|
||||
ContentType[] supportedContentTypes=Arrays.stream(ContentType.values())
|
||||
private void onDefaultContentTypeClick(ListItem<?> item_){
|
||||
List<ContentType> supportedContentTypes=Arrays.stream(ContentType.values())
|
||||
.filter(t->t.supportedByInstance(getInstance().orElse(null)))
|
||||
.toArray(ContentType[]::new);
|
||||
String[] names=Arrays.stream(supportedContentTypes)
|
||||
.collect(Collectors.toList());
|
||||
int selected=supportedContentTypes.indexOf(lp.defaultContentType);
|
||||
int[] newSelected={selected};
|
||||
String[] names=supportedContentTypes.stream()
|
||||
.map(ContentType::getName)
|
||||
.map(this::getString)
|
||||
.toArray(String[]::new);
|
||||
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.settings_theme)
|
||||
.setTitle(R.string.sk_settings_default_content_type)
|
||||
.setSingleChoiceItems(names,
|
||||
selected, (dlg, item)->newSelected[0]=item)
|
||||
.setPositiveButton(R.string.ok, (dlg, item)->{
|
||||
ContentType type=supportedContentTypes[newSelected[0]];
|
||||
ContentType type=supportedContentTypes.get(newSelected[0]);
|
||||
lp.defaultContentType=type;
|
||||
defaultContentTypeItem.subtitleRes=type.getName();
|
||||
rebindItem(defaultContentTypeItem);
|
||||
@@ -112,7 +113,7 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onShowEmojiReactionsClick(){
|
||||
private void onShowEmojiReactionsClick(ListItem<?> item_){
|
||||
int selected=lp.showEmojiReactions.ordinal();
|
||||
int[] newSelected={selected};
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.AccountSwitcherSheet;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
@@ -49,7 +50,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
account = AccountSessionManager.get(accountID);
|
||||
account=AccountSessionManager.get(accountID);
|
||||
setTitle(R.string.settings);
|
||||
setSubtitle(account.getFullUsername());
|
||||
onDataLoaded(List.of(
|
||||
@@ -59,15 +60,17 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_fluent_alert_24_regular, this::onNotificationsClick),
|
||||
new ListItem<>(R.string.sk_settings_instance, 0, R.drawable.ic_fluent_server_24_regular, this::onInstanceClick),
|
||||
new ListItem<>(getString(R.string.about_app, getString(R.string.mo_app_name)), null, R.drawable.ic_fluent_info_24_regular, this::onAboutClick, null, 0, true),
|
||||
new ListItem<>(R.string.manage_accounts, 0, R.drawable.ic_fluent_person_swap_24_regular, this::onManageAccountsClick),
|
||||
new ListItem<>(R.string.log_out, 0, R.drawable.ic_fluent_sign_out_24_regular, this::onLogOutClick, R.attr.colorM3Error, false)
|
||||
));
|
||||
|
||||
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(account.domain);
|
||||
if (!instance.isAkkoma())
|
||||
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(account.domain);
|
||||
if(!instance.isAkkoma()){
|
||||
data.add(3, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick));
|
||||
}
|
||||
|
||||
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
||||
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_fluent_wrench_screwdriver_24_regular, ()->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_fluent_wrench_screwdriver_24_regular, i->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||
}
|
||||
|
||||
AccountSession session=AccountSessionManager.get(accountID);
|
||||
@@ -128,35 +131,39 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
return args;
|
||||
}
|
||||
|
||||
private void onBehaviorClick(){
|
||||
private void onBehaviorClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsBehaviorFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onDisplayClick(){
|
||||
private void onDisplayClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsDisplayFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onPrivacyClick(){
|
||||
private void onPrivacyClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsPrivacyFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onFiltersClick(){
|
||||
private void onFiltersClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsFiltersFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onNotificationsClick(){
|
||||
private void onNotificationsClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsNotificationsFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onInstanceClick(){
|
||||
private void onInstanceClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsInstanceFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onAboutClick(){
|
||||
private void onAboutClick(ListItem<?> item_){
|
||||
Nav.go(getActivity(), SettingsAboutAppFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onLogOutClick(){
|
||||
private void onManageAccountsClick(ListItem<?> item){
|
||||
new AccountSwitcherSheet(getActivity(), null).show();
|
||||
}
|
||||
|
||||
private void onLogOutClick(ListItem<?> item_){
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.log_out)
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.unifiedpush.android.connector.RegistrationDialogContent;
|
||||
import org.unifiedpush.android.connector.UnifiedPush;
|
||||
|
||||
import java.time.Instant;
|
||||
@@ -76,22 +75,22 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
useUnifiedPush=!getDistributor(getContext()).isEmpty();
|
||||
|
||||
onDataLoaded(List.of(
|
||||
pauseItem=new CheckableListItem<>(getString(R.string.pause_all_notifications), getPauseItemSubtitle(), CheckableListItem.Style.SWITCH, false, R.drawable.ic_fluent_alert_snooze_24_regular, ()->onPauseNotificationsClick(false)),
|
||||
pauseItem=new CheckableListItem<>(getString(R.string.pause_all_notifications), getPauseItemSubtitle(), CheckableListItem.Style.SWITCH, false, R.drawable.ic_fluent_alert_snooze_24_regular, i->onPauseNotificationsClick(false)),
|
||||
policyItem=new ListItem<>(R.string.settings_notifications_policy, 0, R.drawable.ic_fluent_people_24_regular, this::onNotificationsPolicyClick, 0, true),
|
||||
|
||||
mentionsItem=new CheckableListItem<>(R.string.notification_type_mentions_and_replies, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.mention, R.drawable.ic_fluent_mention_24_regular, ()->toggleCheckableItem(mentionsItem)),
|
||||
boostsItem=new CheckableListItem<>(R.string.notification_type_reblog, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, ()->toggleCheckableItem(boostsItem)),
|
||||
favoritesItem=new CheckableListItem<>(R.string.notification_type_favorite, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.favourite, R.drawable.ic_fluent_star_24_regular, ()->toggleCheckableItem(favoritesItem)),
|
||||
followersItem=new CheckableListItem<>(R.string.notification_type_follow, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.follow, R.drawable.ic_fluent_person_add_24_regular, ()->toggleCheckableItem(followersItem)),
|
||||
pollsItem=new CheckableListItem<>(R.string.notification_type_poll, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.poll, R.drawable.ic_fluent_poll_24_regular, ()->toggleCheckableItem(pollsItem)),
|
||||
updateItem=new CheckableListItem<>(R.string.sk_notification_type_update, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.update, R.drawable.ic_fluent_history_24_regular, ()->toggleCheckableItem(updateItem)),
|
||||
postsItem=new CheckableListItem<>(R.string.sk_notification_type_posts, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.status, R.drawable.ic_fluent_chat_24_regular, ()->toggleCheckableItem(postsItem), true),
|
||||
mentionsItem=new CheckableListItem<>(R.string.notification_type_mentions_and_replies, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.mention, R.drawable.ic_fluent_mention_24_regular, i->toggleCheckableItem(mentionsItem)),
|
||||
boostsItem=new CheckableListItem<>(R.string.notification_type_reblog, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, i->toggleCheckableItem(boostsItem)),
|
||||
favoritesItem=new CheckableListItem<>(R.string.notification_type_favorite, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.favourite, R.drawable.ic_fluent_star_24_regular, i->toggleCheckableItem(favoritesItem)),
|
||||
followersItem=new CheckableListItem<>(R.string.notification_type_follow, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.follow, R.drawable.ic_fluent_person_add_24_regular, i->toggleCheckableItem(followersItem)),
|
||||
pollsItem=new CheckableListItem<>(R.string.notification_type_poll, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.poll, R.drawable.ic_fluent_poll_24_regular, i->toggleCheckableItem(pollsItem)),
|
||||
updateItem=new CheckableListItem<>(R.string.sk_notification_type_update, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.update, R.drawable.ic_fluent_history_24_regular, i->toggleCheckableItem(updateItem)),
|
||||
postsItem=new CheckableListItem<>(R.string.sk_notification_type_posts, 0, CheckableListItem.Style.CHECKBOX, pushSubscription.alerts.status, R.drawable.ic_fluent_chat_24_regular, i->toggleCheckableItem(postsItem), true),
|
||||
|
||||
uniformIconItem=new CheckableListItem<>(R.string.sk_settings_uniform_icon_for_notifications, R.string.mo_setting_uniform_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.uniformNotificationIcon, R.drawable.ic_ntf_logo, ()->toggleCheckableItem(uniformIconItem)),
|
||||
uniformIconItem=new CheckableListItem<>(R.string.sk_settings_uniform_icon_for_notifications, R.string.mo_setting_uniform_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.uniformNotificationIcon, R.drawable.ic_ntf_logo, i->toggleCheckableItem(uniformIconItem)),
|
||||
swapBookmarkWithReblogItem=new CheckableListItem<>(R.string.mo_swap_bookmark_with_reblog, R.string.mo_swap_bookmark_with_reblog_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.swapBookmarkWithBoostAction, R.drawable.ic_boost, ()->toggleCheckableItem(swapBookmarkWithReblogItem)),
|
||||
deleteItem=new CheckableListItem<>(R.string.sk_settings_enable_delete_notifications, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enableDeleteNotifications, R.drawable.ic_fluent_mail_inbox_dismiss_24_regular, ()->toggleCheckableItem(deleteItem)),
|
||||
onlyLatestItem=new CheckableListItem<>(R.string.sk_settings_single_notification, 0, CheckableListItem.Style.SWITCH, lp.keepOnlyLatestNotification, R.drawable.ic_fluent_convert_range_24_regular, ()->toggleCheckableItem(onlyLatestItem), true),
|
||||
unifiedPushItem=new CheckableListItem<>(R.string.sk_settings_unifiedpush, 0, CheckableListItem.Style.SWITCH, useUnifiedPush, R.drawable.ic_fluent_alert_arrow_up_24_regular, this::onUnifiedPush, true)
|
||||
deleteItem=new CheckableListItem<>(R.string.sk_settings_enable_delete_notifications, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enableDeleteNotifications, R.drawable.ic_fluent_mail_inbox_dismiss_24_regular, i->toggleCheckableItem(deleteItem)),
|
||||
onlyLatestItem=new CheckableListItem<>(R.string.sk_settings_single_notification, 0, CheckableListItem.Style.SWITCH, lp.keepOnlyLatestNotification, R.drawable.ic_fluent_convert_range_24_regular, i->toggleCheckableItem(onlyLatestItem), true),
|
||||
unifiedPushItem=new CheckableListItem<>(R.string.sk_settings_unifiedpush, 0, CheckableListItem.Style.SWITCH, useUnifiedPush, R.drawable.ic_fluent_alert_arrow_up_24_regular, i->onUnifiedPushClick(), true)
|
||||
));
|
||||
|
||||
//only enable when distributors, who can receive notifications, are available
|
||||
@@ -102,7 +101,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
|
||||
typeItems=List.of(mentionsItem, boostsItem, favoritesItem, followersItem, pollsItem, updateItem, postsItem);
|
||||
pauseItem.checkedChangeListener=checked->onPauseNotificationsClick(true);
|
||||
unifiedPushItem.checkedChangeListener=checked->onUnifiedPush();
|
||||
unifiedPushItem.checkedChangeListener=checked->onUnifiedPushClick();
|
||||
updatePolicyItem(null);
|
||||
updatePauseItem();
|
||||
}
|
||||
@@ -253,7 +252,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
alert.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||
}
|
||||
|
||||
private void onNotificationsPolicyClick(){
|
||||
private void onNotificationsPolicyClick(ListItem<?> item_){
|
||||
String[] items=Stream.of(
|
||||
R.string.notifications_policy_anyone,
|
||||
R.string.notifications_policy_followed,
|
||||
@@ -327,7 +326,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
|
||||
}
|
||||
}
|
||||
|
||||
private void onUnifiedPush(){
|
||||
private void onUnifiedPushClick(){
|
||||
if(getDistributor(getContext()).isEmpty()){
|
||||
List<String> distributors = UnifiedPush.getDistributors(getContext(), new ArrayList<>());
|
||||
showUnifiedPushRegisterDialog(distributors);
|
||||
|
||||
@@ -2,40 +2,98 @@ package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsPrivacyFragment extends BaseSettingsFragment<Void>{
|
||||
private CheckableListItem<Void> discoverableItem, indexableItem;
|
||||
private CheckableListItem<Void> discoverableItem, indexableItem, lockedItem;
|
||||
private ListItem<Void> privacyItem;
|
||||
private StatusPrivacy privacy=null;
|
||||
private Instance instance;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.settings_privacy);
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
AccountSession session=AccountSessionManager.get(accountID);
|
||||
Account self=session.self;
|
||||
instance=AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||
privacy=self.source.privacy;
|
||||
onDataLoaded(List.of(
|
||||
discoverableItem=new CheckableListItem<>(R.string.settings_discoverable, 0, CheckableListItem.Style.SWITCH, self.discoverable, R.drawable.ic_fluent_thumb_like_dislike_24_regular, ()->toggleCheckableItem(discoverableItem)),
|
||||
indexableItem=new CheckableListItem<>(R.string.settings_indexable, 0, CheckableListItem.Style.SWITCH, self.source.indexable!=null ? self.source.indexable : true, R.drawable.ic_fluent_search_24_regular, ()->toggleCheckableItem(indexableItem))
|
||||
privacyItem=new ListItem<>(R.string.sk_settings_default_visibility, getPrivacyString(privacy), R.drawable.ic_fluent_eye_24_regular, this::onPrivacyClick, 0, true),
|
||||
lockedItem=new CheckableListItem<>(R.string.sk_settings_lock_account, 0, CheckableListItem.Style.SWITCH, self.locked, R.drawable.ic_fluent_person_available_24_regular, i->toggleCheckableItem(lockedItem))
|
||||
));
|
||||
if(self.source.indexable==null)
|
||||
indexableItem.isEnabled=false;
|
||||
|
||||
if(!instance.isAkkoma()){
|
||||
data.addAll(List.of(
|
||||
discoverableItem=new CheckableListItem<>(R.string.settings_discoverable, 0, CheckableListItem.Style.SWITCH, self.discoverable, R.drawable.ic_fluent_thumb_like_dislike_24_regular, i->toggleCheckableItem(discoverableItem)),
|
||||
indexableItem=new CheckableListItem<>(R.string.settings_indexable, 0, CheckableListItem.Style.SWITCH, self.source.indexable!=null ? self.source.indexable : true, R.drawable.ic_fluent_search_24_regular, i->toggleCheckableItem(indexableItem))
|
||||
));
|
||||
if(self.source.indexable==null)
|
||||
indexableItem.isEnabled=false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
private @StringRes int getPrivacyString(StatusPrivacy p){
|
||||
if(p==null) return R.string.visibility_public;
|
||||
return switch(p){
|
||||
case PUBLIC -> R.string.visibility_public;
|
||||
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||
case PRIVATE -> R.string.visibility_followers_only;
|
||||
case DIRECT -> R.string.visibility_private;
|
||||
case LOCAL -> R.string.sk_local_only;
|
||||
};
|
||||
}
|
||||
|
||||
private void onPrivacyClick(ListItem<?> item_){
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
List<StatusPrivacy> options=new ArrayList<>(List.of(StatusPrivacy.PUBLIC, StatusPrivacy.UNLISTED, StatusPrivacy.PRIVATE, StatusPrivacy.DIRECT));
|
||||
if(instance.isAkkoma()) options.add(StatusPrivacy.LOCAL);
|
||||
int selected=options.indexOf(self.source.privacy);
|
||||
int[] newSelected={selected};
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.sk_settings_default_visibility)
|
||||
.setSingleChoiceItems(options.stream().map(this::getPrivacyString).map(this::getString).toArray(String[]::new),
|
||||
selected, (dlg, item)->newSelected[0]=item)
|
||||
.setPositiveButton(R.string.ok, (dlg, item)->{
|
||||
privacy=options.get(newSelected[0]);
|
||||
privacyItem.subtitleRes=getPrivacyString(privacy);
|
||||
rebindItem(privacyItem);
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
if(self.discoverable!=discoverableItem.checked || (self.source.indexable!=null && self.source.indexable!=indexableItem.checked)){
|
||||
self.discoverable=discoverableItem.checked;
|
||||
self.source.indexable=indexableItem.checked;
|
||||
AccountSessionManager.get(accountID).savePreferencesLater();
|
||||
AccountSession s=AccountSessionManager.get(accountID);
|
||||
Account self=s.self;
|
||||
boolean savePlease=self.locked!=lockedItem.checked
|
||||
|| self.source.privacy!=privacy
|
||||
|| (discoverableItem!=null && self.discoverable!=discoverableItem.checked)
|
||||
|| (indexableItem!=null && self.source.indexable!=null && self.source.indexable!=indexableItem.checked);
|
||||
if(savePlease){
|
||||
if(discoverableItem!=null) self.discoverable=discoverableItem.checked;
|
||||
if(indexableItem!=null) self.source.indexable=indexableItem.checked;
|
||||
self.locked=lockedItem.checked;
|
||||
s.preferences.postingDefaultVisibility=privacy;
|
||||
s.savePreferencesLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public class SettingsServerAboutFragment extends LoaderFragment{
|
||||
if(!TextUtils.isEmpty(instance.email)){
|
||||
needDivider=true;
|
||||
SimpleListItemViewHolder holder=new SimpleListItemViewHolder(getActivity(), scrollingLayout);
|
||||
ListItem<Void> item=new ListItem<>(R.string.send_email_to_server_admin, 0, R.drawable.ic_fluent_mail_24_regular, ()->{});
|
||||
ListItem<Void> item=new ListItem<>(R.string.send_email_to_server_admin, 0, R.drawable.ic_fluent_mail_24_regular, i->{});
|
||||
holder.bind(item);
|
||||
holder.itemView.setBackground(UiUtils.getThemeDrawable(getActivity(), android.R.attr.selectableItemBackground));
|
||||
holder.itemView.setOnClickListener(v->openAdminEmail());
|
||||
|
||||
@@ -178,7 +178,6 @@ public class Account extends BaseModel implements Searchable{
|
||||
if(url==null) url="";
|
||||
if(note==null) note="";
|
||||
if(avatar==null) avatar="";
|
||||
if(displayName!=null) displayName='\u2068'+displayName+'\u2069';
|
||||
}
|
||||
|
||||
public boolean isLocal(){
|
||||
@@ -208,6 +207,10 @@ public class Account extends BaseModel implements Searchable{
|
||||
return fqn != null ? fqn : acct.split("@")[0] + "@" + getDomainFromURL();
|
||||
}
|
||||
|
||||
public String getDisplayName(){
|
||||
return '\u2068'+displayName+'\u2069';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Account{"+
|
||||
|
||||
@@ -28,23 +28,13 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.joinmastodon.android.api.session.AccountSession;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.events.StatusMuteChangedEvent;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.utils.StatusTextEncoder;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Parcel
|
||||
@@ -109,6 +99,7 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
||||
private transient String strippedText;
|
||||
public transient TranslationState translationState=TranslationState.HIDDEN;
|
||||
public transient Translation translation;
|
||||
public transient boolean fromStatusCreated;
|
||||
|
||||
public Status(){}
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ public class AccountViewModel{
|
||||
V.dp(50), V.dp(50));
|
||||
emojiHelper=new CustomEmojiHelper();
|
||||
if(session.getLocalPreferences().customEmojiInNames)
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.getDisplayName(), account.emojis);
|
||||
else
|
||||
parsedName=account.displayName;
|
||||
parsedName=account.getDisplayName();
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(parsedName);
|
||||
ssb.append(parsedBio);
|
||||
|
||||
@@ -9,42 +9,42 @@ public class CheckableListItem<T> extends ListItem<T>{
|
||||
public boolean checked;
|
||||
public Consumer<Boolean> checkedChangeListener;
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick, T parentObject, boolean dividerAfter){
|
||||
super(title, subtitle, iconRes, onClick, parentObject, 0, dividerAfter);
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Consumer<CheckableListItem<T>> onClick, T parentObject, boolean dividerAfter){
|
||||
super(title, subtitle, iconRes, (Consumer<ListItem<T>>)(Object)onClick, parentObject, 0, dividerAfter);
|
||||
this.style=style;
|
||||
this.checked=checked;
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Runnable onClick){
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Consumer<CheckableListItem<T>> onClick){
|
||||
this(title, subtitle, style, checked, 0, onClick, null, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Runnable onClick, T parentObject){
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Consumer<CheckableListItem<T>> onClick, T parentObject){
|
||||
this(title, subtitle, style, checked, 0, onClick, parentObject, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick){
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Consumer<CheckableListItem<T>> onClick){
|
||||
this(title, subtitle, style, checked, iconRes, onClick, null, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick, T parentObject){
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Consumer<CheckableListItem<T>> onClick, T parentObject){
|
||||
this(title, subtitle, style, checked, iconRes, onClick, parentObject, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Runnable onClick){
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Consumer<CheckableListItem<T>> onClick){
|
||||
this(titleRes, subtitleRes, style, checked, 0, onClick, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Runnable onClick, boolean dividerAfter){
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Consumer<CheckableListItem<T>> onClick, boolean dividerAfter){
|
||||
this(titleRes, subtitleRes, style, checked, 0, onClick, dividerAfter);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Runnable onClick){
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Consumer<CheckableListItem<T>> onClick){
|
||||
this(titleRes, subtitleRes, style, checked, iconRes, onClick, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Runnable onClick, boolean dividerAfter){
|
||||
super(titleRes, subtitleRes, iconRes, onClick, 0, dividerAfter);
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Consumer<CheckableListItem<T>> onClick, boolean dividerAfter){
|
||||
super(titleRes, subtitleRes, iconRes, (Consumer<ListItem<T>>)(Object)onClick, 0, dividerAfter);
|
||||
this.style=style;
|
||||
this.checked=checked;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
@@ -16,11 +18,11 @@ public class ListItem<T>{
|
||||
public int iconRes;
|
||||
public int colorOverrideAttr;
|
||||
public boolean dividerAfter;
|
||||
public Runnable onClick;
|
||||
private Consumer<ListItem<T>> onClick;
|
||||
public boolean isEnabled=true;
|
||||
public T parentObject;
|
||||
|
||||
public ListItem(String title, String subtitle, int iconRes, Runnable onClick, T parentObject, int colorOverrideAttr, boolean dividerAfter){
|
||||
public ListItem(String title, String subtitle, int iconRes, Consumer<ListItem<T>> onClick, T parentObject, int colorOverrideAttr, boolean dividerAfter){
|
||||
this.title=title;
|
||||
this.subtitle=subtitle;
|
||||
this.iconRes=iconRes;
|
||||
@@ -32,45 +34,41 @@ public class ListItem<T>{
|
||||
isEnabled=false;
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, Runnable onClick){
|
||||
public ListItem(String title, String subtitle, Consumer<ListItem<T>> onClick){
|
||||
this(title, subtitle, 0, onClick, null, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, Runnable onClick, T parentObject){
|
||||
public ListItem(String title, String subtitle, Consumer<ListItem<T>> onClick, T parentObject){
|
||||
this(title, subtitle, 0, onClick, parentObject, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Runnable onClick){
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Consumer<ListItem<T>> onClick){
|
||||
this(title, subtitle, iconRes, onClick, null, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Runnable onClick, boolean dividerAfter){
|
||||
this(title, subtitle, iconRes, onClick, null, 0, dividerAfter);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Runnable onClick, T parentObject){
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Consumer<ListItem<T>> onClick, T parentObject){
|
||||
this(title, subtitle, iconRes, onClick, parentObject, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Runnable onClick){
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Consumer<ListItem<T>> onClick){
|
||||
this(null, null, 0, onClick, null, 0, false);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Runnable onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Consumer<ListItem<T>> onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
this(null, null, 0, onClick, null, colorOverrideAttr, dividerAfter);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Runnable onClick){
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Consumer<ListItem<T>> onClick){
|
||||
this(null, null, iconRes, onClick, null, 0, false);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Runnable onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Consumer<ListItem<T>> onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
this(null, null, iconRes, onClick, null, colorOverrideAttr, dividerAfter);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
@@ -79,4 +77,13 @@ public class ListItem<T>{
|
||||
public int getItemViewType(){
|
||||
return colorOverrideAttr==0 ? R.id.list_item_simple : R.id.list_item_simple_tinted;
|
||||
}
|
||||
|
||||
public void performClick(){
|
||||
if(onClick!=null)
|
||||
onClick.accept(this);
|
||||
}
|
||||
|
||||
public <I extends ListItem<T>> void setOnClick(Consumer<I> onClick){
|
||||
this.onClick=(Consumer<ListItem<T>>) onClick;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
@@ -27,6 +27,8 @@ 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.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.CheckableRelativeLayout;
|
||||
|
||||
@@ -40,7 +42,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import me.grishka.appkit.FragmentStackActivity;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
@@ -283,7 +284,7 @@ public class AccountSwitcherSheet extends BottomSheet{
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBind(AccountSession item){
|
||||
name.setText(item.self.displayName);
|
||||
HtmlParser.setTextWithCustomEmoji(name, item.self.getDisplayName(), item.self.emojis);
|
||||
username.setText(item.getFullUsername());
|
||||
radioButton.setVisibility(externalShare ? View.GONE : View.VISIBLE);
|
||||
extraBtnWrap.setVisibility(externalShare && openInApp ? View.VISIBLE : View.GONE);
|
||||
|
||||
@@ -26,9 +26,7 @@ import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.ProgressBarButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
@@ -53,9 +51,9 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
|
||||
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), parentFragment.getAccountID());
|
||||
if(account.emojis.isEmpty()){
|
||||
parsedName=account.displayName;
|
||||
parsedName=account.getDisplayName();
|
||||
}else{
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.getDisplayName(), account.emojis);
|
||||
emojiHelper.setText(new SpannableStringBuilder(parsedName).append(parsedBio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
GlobalUserPreferences.playGifs ? user.avatar : user.avatarStatic,
|
||||
V.dp(50), V.dp(50));
|
||||
this.accountID=accountID;
|
||||
parsedName=new SpannableStringBuilder(user.displayName);
|
||||
parsedName=new SpannableStringBuilder(user.getDisplayName());
|
||||
this.status=status;
|
||||
this.notification=notification;
|
||||
this.scheduledStatus=scheduledStatus;
|
||||
|
||||
@@ -18,7 +18,6 @@ import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
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.fragments.BaseStatusListFragment;
|
||||
@@ -62,7 +61,7 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
TextUtils.isEmpty(notification.account.avatar) ? session.getDefaultAvatarUrl() :
|
||||
GlobalUserPreferences.playGifs ? notification.account.avatar : notification.account.avatarStatic,
|
||||
V.dp(50), V.dp(50));
|
||||
SpannableStringBuilder parsedName=new SpannableStringBuilder(notification.account.displayName);
|
||||
SpannableStringBuilder parsedName=new SpannableStringBuilder(notification.account.getDisplayName());
|
||||
HtmlParser.parseCustomEmoji(parsedName, notification.account.emojis);
|
||||
String str = parentFragment.getString(switch(notification.type){
|
||||
case FOLLOW -> R.string.user_followed_you;
|
||||
|
||||
@@ -87,8 +87,9 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
CustomEmojiHelper helper=index<emojiHelper.getImageCount() ? emojiHelper : extra.emojiHelper;
|
||||
return helper.getImageRequest(index%emojiHelper.getImageCount());
|
||||
int firstHelperCount=emojiHelper.getImageCount();
|
||||
CustomEmojiHelper helper=index<firstHelperCount ? emojiHelper : extra.emojiHelper;
|
||||
return helper.getImageRequest(firstHelperCount>0 ? index%firstHelperCount : index);
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<ReblogOrReplyLineStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
@@ -136,8 +137,9 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable image){
|
||||
CustomEmojiHelper helper=index<item.emojiHelper.getImageCount() ? item.emojiHelper : item.extra.emojiHelper;
|
||||
helper.setImageDrawable(index%item.emojiHelper.getImageCount(), image);
|
||||
int firstHelperCount=item.emojiHelper.getImageCount();
|
||||
CustomEmojiHelper helper=index<firstHelperCount ? item.emojiHelper : item.extra.emojiHelper;
|
||||
helper.setImageDrawable(firstHelperCount>0 ? index%firstHelperCount : index, image);
|
||||
text.invalidate();
|
||||
extraText.invalidate();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountLocalPreferences;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
@@ -30,7 +29,6 @@ import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.DisplayItemsParent;
|
||||
import org.joinmastodon.android.model.LegacyFilter;
|
||||
import org.joinmastodon.android.model.FilterAction;
|
||||
import org.joinmastodon.android.model.FilterContext;
|
||||
import org.joinmastodon.android.model.FilterResult;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
@@ -41,7 +39,6 @@ import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
|
||||
import org.joinmastodon.android.utils.StatusFilterPredicate;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -144,11 +141,11 @@ public abstract class StatusDisplayItem{
|
||||
String parentID = parent.getID();
|
||||
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
|
||||
: account == null ? fragment.getString(R.string.sk_in_reply)
|
||||
: status.reblog != null ? account.displayName
|
||||
: fragment.getString(R.string.in_reply_to, account.displayName);
|
||||
: status.reblog != null ? account.getDisplayName()
|
||||
: fragment.getString(R.string.in_reply_to, account.getDisplayName());
|
||||
String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
|
||||
: account == null ? fragment.getString(R.string.sk_in_reply)
|
||||
: fragment.getString(R.string.in_reply_to, account.displayName);
|
||||
: fragment.getString(R.string.in_reply_to, account.getDisplayName());
|
||||
return new ReblogOrReplyLineStatusDisplayItem(
|
||||
parentID, fragment, text, account == null ? List.of() : account.emojis,
|
||||
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText, status
|
||||
@@ -181,12 +178,11 @@ public abstract class StatusDisplayItem{
|
||||
|
||||
statusForContent.rebloggedBy = status.account;
|
||||
|
||||
String fullText = fragment.getString(R.string.user_boosted, status.account.displayName);
|
||||
String text = replyLine != null ? status.account.displayName : fullText;
|
||||
String text=fragment.getString(R.string.user_boosted, status.account.getDisplayName());
|
||||
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, text, status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20sp_filled, isOwnPost ? status.visibility : null, i->{
|
||||
args.putParcelable("profileAccount", Parcels.wrap(status.account));
|
||||
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
|
||||
}, fullText, status));
|
||||
}, null, status));
|
||||
} else if (!(status.tags.isEmpty() ||
|
||||
fragment instanceof HashtagTimelineFragment ||
|
||||
fragment instanceof ListTimelineFragment
|
||||
|
||||
@@ -213,9 +213,10 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
Translation existingTrans=item.status.getContentStatus().translation;
|
||||
String existingTransLang=existingTrans!=null ? existingTrans.detectedSourceLanguage : null;
|
||||
String lang=existingTransLang!=null ? existingTransLang : item.status.getContentStatus().language;
|
||||
String displayLang=Locale.forLanguageTag(lang != null ? lang
|
||||
: AccountSessionManager.get(item.parentFragment.getAccountID()).preferences.postingDefaultLanguage).getDisplayLanguage();
|
||||
translationButton.setText(item.parentFragment.getString(R.string.translate_post, !displayLang.isBlank() ? displayLang : lang));
|
||||
Locale locale=lang!=null ? Locale.forLanguageTag(lang) : null;
|
||||
translationButton.setText(locale!=null
|
||||
? item.parentFragment.getString(R.string.translate_post, locale.getDisplayLanguage())
|
||||
: item.parentFragment.getString(R.string.sk_translate_post));
|
||||
translationButton.setClickable(true);
|
||||
translationButton.animate().alpha(1).setDuration(100).start();
|
||||
translationInfo.setVisibility(View.GONE);
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.joinmastodon.android.ui.utils;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.IntEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.ActionMode;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import me.grishka.appkit.FragmentStackActivity;
|
||||
import me.grishka.appkit.fragments.AppKitFragment;
|
||||
|
||||
public class ActionModeHelper{
|
||||
public static ActionMode startActionMode(AppKitFragment fragment, IntSupplier statusBarColorSupplier, ActionMode.Callback callback){
|
||||
FragmentStackActivity activity=(FragmentStackActivity) fragment.getActivity();
|
||||
return activity.startActionMode(new ActionMode.Callback(){
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu){
|
||||
if(!callback.onCreateActionMode(mode, menu))
|
||||
return false;
|
||||
ObjectAnimator anim=ObjectAnimator.ofInt(activity.getWindow(), "statusBarColor", statusBarColorSupplier.getAsInt(), UiUtils.getThemeColor(activity, R.attr.colorM3Primary));
|
||||
anim.setEvaluator(new IntEvaluator(){
|
||||
@Override
|
||||
public Integer evaluate(float fraction, Integer startValue, Integer endValue){
|
||||
return UiUtils.alphaBlendColors(startValue, endValue, fraction);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
activity.invalidateSystemBarColors(fragment);
|
||||
View fakeView=new View(activity);
|
||||
// mode.setCustomView(fakeView);
|
||||
// int buttonID=activity.getResources().getIdentifier("action_mode_close_button", "id", "android");
|
||||
// View btn=activity.getWindow().getDecorView().findViewById(buttonID);
|
||||
// if(btn!=null){
|
||||
// ((ViewGroup.MarginLayoutParams)btn.getLayoutParams()).setMarginEnd(0);
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu){
|
||||
if(!callback.onPrepareActionMode(mode, menu))
|
||||
return false;
|
||||
for(int i=0;i<menu.size();i++){
|
||||
Drawable icon=menu.getItem(i).getIcon();
|
||||
if(icon!=null){
|
||||
icon=icon.mutate();
|
||||
icon.setTint(UiUtils.getThemeColor(activity, R.attr.colorM3OnPrimary));
|
||||
menu.getItem(i).setIcon(icon);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item){
|
||||
return callback.onActionItemClicked(mode, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode){
|
||||
ObjectAnimator anim=ObjectAnimator.ofInt(activity.getWindow(), "statusBarColor", UiUtils.getThemeColor(activity, R.attr.colorM3Primary), statusBarColorSupplier.getAsInt());
|
||||
anim.setEvaluator(new IntEvaluator(){
|
||||
@Override
|
||||
public Integer evaluate(float fraction, Integer startValue, Integer endValue){
|
||||
return UiUtils.alphaBlendColors(startValue, endValue, fraction);
|
||||
}
|
||||
});
|
||||
anim.addListener(new AnimatorListenerAdapter(){
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation){
|
||||
activity.getWindow().setStatusBarColor(0);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
activity.invalidateSystemBarColors(fragment);
|
||||
callback.onDestroyActionMode(mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -489,7 +489,7 @@ public class UiUtils {
|
||||
|
||||
public static void confirmToggleBlockUser(Activity activity, String accountID, Account account, boolean currentlyBlocked, Consumer<Relationship> resultCallback) {
|
||||
showConfirmationAlert(activity, activity.getString(currentlyBlocked ? R.string.confirm_unblock_title : R.string.confirm_block_title),
|
||||
activity.getString(currentlyBlocked ? R.string.confirm_unblock : R.string.confirm_block, account.displayName),
|
||||
activity.getString(currentlyBlocked ? R.string.confirm_unblock : R.string.confirm_block, account.getDisplayName()),
|
||||
activity.getString(currentlyBlocked ? R.string.do_unblock : R.string.do_block),
|
||||
R.drawable.ic_fluent_person_prohibited_28_regular,
|
||||
() -> {
|
||||
@@ -517,7 +517,7 @@ public class UiUtils {
|
||||
public static void confirmSoftBlockUser(Activity activity, String accountID, Account account, Consumer<Relationship> resultCallback) {
|
||||
showConfirmationAlert(activity,
|
||||
activity.getString(R.string.sk_remove_follower),
|
||||
activity.getString(R.string.sk_remove_follower_confirm, account.displayName),
|
||||
activity.getString(R.string.sk_remove_follower_confirm, account.getDisplayName()),
|
||||
activity.getString(R.string.sk_do_remove_follower),
|
||||
R.drawable.ic_fluent_person_delete_24_regular,
|
||||
() -> new SetAccountBlocked(account.id, true).setCallback(new Callback<>() {
|
||||
@@ -575,7 +575,7 @@ public class UiUtils {
|
||||
params.setMargins(0, V.dp(-12), 0, 0);
|
||||
durationView.setLayoutParams(params);
|
||||
Button button=durationView.findViewById(R.id.button);
|
||||
((TextView) durationView.findViewById(R.id.message)).setText(context.getString(R.string.confirm_mute, account.displayName));
|
||||
((TextView) durationView.findViewById(R.id.message)).setText(context.getString(R.string.confirm_mute, account.getDisplayName()));
|
||||
|
||||
AtomicReference<Duration> muteDuration=new AtomicReference<>(Duration.ZERO);
|
||||
|
||||
@@ -609,7 +609,7 @@ public class UiUtils {
|
||||
|
||||
new M3AlertDialogBuilder(context)
|
||||
.setTitle(context.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title))
|
||||
.setMessage(currentlyMuted ? context.getString(R.string.confirm_unmute, account.displayName) : null)
|
||||
.setMessage(currentlyMuted ? context.getString(R.string.confirm_unmute, account.getDisplayName()) : null)
|
||||
.setView(currentlyMuted ? null : durationView)
|
||||
.setPositiveButton(context.getString(currentlyMuted ? R.string.do_unmute : R.string.do_mute), (dlg, i)->{
|
||||
new SetAccountMuted(account.id, !currentlyMuted, muteDuration.get().getSeconds())
|
||||
|
||||
@@ -73,6 +73,6 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
|
||||
|
||||
@Override
|
||||
public void onClick(){
|
||||
item.onClick.run();
|
||||
item.performClick();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,40 @@
|
||||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
/**
|
||||
* A LinearLayout for TextViews. First child TextView will get truncated if it doesn't fit, remaining will always wrap content.
|
||||
*/
|
||||
public class HeaderSubtitleLinearLayout extends LinearLayout{
|
||||
private float firstFraction;
|
||||
|
||||
public HeaderSubtitleLinearLayout(Context context){
|
||||
super(context);
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public HeaderSubtitleLinearLayout(Context context, AttributeSet attrs){
|
||||
super(context, attrs);
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public HeaderSubtitleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr){
|
||||
super(context, attrs, defStyleAttr);
|
||||
TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.HeaderSubtitleLinearLayout);
|
||||
firstFraction=ta.getFraction(R.styleable.HeaderSubtitleLinearLayout_firstFraction, 1, 1, 0.5f);
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
if(getLayoutChildCount()>1){
|
||||
int remainingWidth=MeasureSpec.getSize(widthMeasureSpec);
|
||||
int fullWidth=MeasureSpec.getSize(widthMeasureSpec);
|
||||
int remainingWidth=fullWidth;
|
||||
for(int i=1;i<getChildCount();i++){
|
||||
View v=getChildAt(i);
|
||||
if(v.getVisibility()==GONE)
|
||||
@@ -36,12 +43,9 @@ public class HeaderSubtitleLinearLayout extends LinearLayout{
|
||||
LayoutParams lp=(LayoutParams) v.getLayoutParams();
|
||||
remainingWidth-=v.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;
|
||||
}
|
||||
if(getChildAt(0) instanceof TextView first){
|
||||
// guaranteeing at least 64sp of width for the display name
|
||||
first.setMaxWidth(Math.max(remainingWidth, V.sp(64)));
|
||||
}
|
||||
if(getChildAt(1) instanceof TextView second){
|
||||
second.setMaxWidth(Math.max(remainingWidth, V.sp(120)));
|
||||
View first=getChildAt(0);
|
||||
if(first instanceof TextView){
|
||||
((TextView) first).setMaxWidth(Math.max(remainingWidth, (int)(firstFraction*fullWidth)));
|
||||
}
|
||||
}else{
|
||||
View first=getChildAt(0);
|
||||
@@ -60,4 +64,12 @@ public class HeaderSubtitleLinearLayout extends LinearLayout{
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setFirstFraction(float firstFraction){
|
||||
this.firstFraction=firstFraction;
|
||||
}
|
||||
|
||||
public float getFirstFraction(){
|
||||
return firstFraction;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user