WIP: prefs
This commit is contained in:
parent
0dc32774ec
commit
b7e0494778
|
@ -24,7 +24,6 @@ import android.widget.LinearLayout
|
|||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
|
@ -35,7 +34,7 @@ import com.keylesspalace.tusky.databinding.ItemFollowRequestBinding
|
|||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.entity.TimelineAccount
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.BindingHolder
|
||||
import com.keylesspalace.tusky.util.Either
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
|
@ -56,6 +55,9 @@ class AccountsInListFragment : DialogFragment(), Injectable {
|
|||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: AccountsInListViewModel by viewModels { viewModelFactory }
|
||||
private val binding by viewBinding(FragmentAccountsInListBinding::bind)
|
||||
|
||||
|
@ -65,9 +67,8 @@ class AccountsInListFragment : DialogFragment(), Injectable {
|
|||
private val searchAdapter = SearchAdapter()
|
||||
|
||||
private val radius by lazy { resources.getDimensionPixelSize(R.dimen.avatar_radius_48dp) }
|
||||
private val pm by lazy { PreferenceManager.getDefaultSharedPreferences(requireContext()) }
|
||||
private val animateAvatar by lazy { pm.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false) }
|
||||
private val animateEmojis by lazy { pm.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false) }
|
||||
private val animateAvatar by lazy { prefs.animateAvatars }
|
||||
private val animateEmojis by lazy { prefs.animateEmojis }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
|
@ -18,7 +18,6 @@ package com.keylesspalace.tusky;
|
|||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
@ -34,7 +33,6 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.keylesspalace.tusky.adapter.AccountSelectionAdapter;
|
||||
|
@ -44,6 +42,7 @@ import com.keylesspalace.tusky.db.AccountManager;
|
|||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.interfaces.AccountSelectionListener;
|
||||
import com.keylesspalace.tusky.interfaces.PermissionRequester;
|
||||
import com.keylesspalace.tusky.settings.Prefs;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -57,6 +56,9 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
|
|||
@Inject
|
||||
public AccountManager accountManager;
|
||||
|
||||
@Inject
|
||||
public Prefs prefs;
|
||||
|
||||
private static final int REQUESTER_NONE = Integer.MAX_VALUE;
|
||||
private HashMap<Integer, PermissionRequester> requesters;
|
||||
|
||||
|
@ -64,25 +66,24 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
|
|||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
/* There isn't presently a way to globally change the theme of a whole application at
|
||||
* runtime, just individual activities. So, each activity has to set its theme before any
|
||||
* views are created. */
|
||||
String theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT);
|
||||
// There isn't presently a way to globally change the theme of a whole application at
|
||||
// runtime, just individual activities. So, each activity has to set its theme before any
|
||||
// views are created.
|
||||
String theme = prefs.getAppTheme();
|
||||
Log.d("activeTheme", theme);
|
||||
if (theme.equals("black")) {
|
||||
setTheme(R.style.TuskyBlackTheme);
|
||||
}
|
||||
|
||||
/* set the taskdescription programmatically, the theme would turn it blue */
|
||||
// set the task description programmatically, the theme would turn it blue
|
||||
String appName = getString(R.string.app_name);
|
||||
Bitmap appIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
|
||||
int recentsBackgroundColor = ThemeUtils.getColor(this, R.attr.colorSurface);
|
||||
|
||||
setTaskDescription(new ActivityManager.TaskDescription(appName, appIcon, recentsBackgroundColor));
|
||||
|
||||
int style = textStyle(preferences.getString("statusTextSize", "medium"));
|
||||
int style = textStyle(prefs.getStatusTextSize());
|
||||
getTheme().applyStyle(style, false);
|
||||
|
||||
if(requiresLogin()) {
|
||||
|
@ -189,7 +190,7 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
|
|||
if (!showActiveAccount && activeAccount != null) {
|
||||
accounts.remove(activeAccount);
|
||||
}
|
||||
AccountSelectionAdapter adapter = new AccountSelectionAdapter(this);
|
||||
AccountSelectionAdapter adapter = new AccountSelectionAdapter(this, this.prefs);
|
||||
adapter.addAll(accounts);
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
|
|
|
@ -40,7 +40,6 @@ import androidx.emoji.text.EmojiCompat
|
|||
import androidx.emoji.text.EmojiCompat.InitCallback
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.viewpager2.widget.MarginPageTransformer
|
||||
import autodispose2.androidx.lifecycle.autoDispose
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -78,6 +77,7 @@ import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
|||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.pager.MainPagerAdapter
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.deleteStaleCachedMedia
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
|
@ -136,6 +136,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
@Inject
|
||||
lateinit var draftHelper: DraftHelper
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val binding by viewBinding(ActivityMainBinding::inflate)
|
||||
|
||||
private lateinit var header: AccountHeaderView
|
||||
|
@ -145,8 +148,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
private var unreadAnnouncementsCount = 0
|
||||
|
||||
private val preferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
||||
|
||||
private lateinit var glide: RequestManager
|
||||
|
||||
private var accountLocked: Boolean = false
|
||||
|
@ -215,7 +216,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
showNotificationTab = true
|
||||
}
|
||||
}
|
||||
window.statusBarColor = Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
|
||||
window.statusBarColor =
|
||||
Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
|
||||
setContentView(binding.root)
|
||||
|
||||
glide = Glide.with(this)
|
||||
|
@ -225,7 +227,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
startActivity(composeIntent)
|
||||
}
|
||||
|
||||
val hideTopToolbar = preferences.getBoolean(PrefKeys.HIDE_TOP_TOOLBAR, false)
|
||||
val hideTopToolbar = prefs.hideTopToolbar
|
||||
binding.mainToolbar.visible(!hideTopToolbar)
|
||||
|
||||
loadDrawerAvatar(activeAccount.profilePictureUrl, true)
|
||||
|
@ -362,7 +364,12 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
header = AccountHeaderView(this).apply {
|
||||
headerBackgroundScaleType = ImageView.ScaleType.CENTER_CROP
|
||||
currentHiddenInList = true
|
||||
onAccountHeaderListener = { _: View?, profile: IProfile, current: Boolean -> handleProfileClick(profile, current) }
|
||||
onAccountHeaderListener = { _: View?, profile: IProfile, current: Boolean ->
|
||||
handleProfileClick(
|
||||
profile,
|
||||
current
|
||||
)
|
||||
}
|
||||
addProfile(
|
||||
ProfileSettingDrawerItem().apply {
|
||||
identifier = DRAWER_ITEM_ADD_ACCOUNT
|
||||
|
@ -377,9 +384,19 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
closeDrawerOnProfileListClick = true
|
||||
}
|
||||
|
||||
header.accountHeaderBackground.setColorFilter(ContextCompat.getColor(this, R.color.headerBackgroundFilter))
|
||||
header.accountHeaderBackground.setBackgroundColor(ThemeUtils.getColor(this, R.attr.colorBackgroundAccent))
|
||||
val animateAvatars = preferences.getBoolean("animateGifAvatars", false)
|
||||
header.accountHeaderBackground.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
this,
|
||||
R.color.headerBackgroundFilter
|
||||
)
|
||||
)
|
||||
header.accountHeaderBackground.setBackgroundColor(
|
||||
ThemeUtils.getColor(
|
||||
this,
|
||||
R.attr.colorBackgroundAccent
|
||||
)
|
||||
)
|
||||
val animateAvatars = prefs.animateAvatars
|
||||
|
||||
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
|
||||
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
|
||||
|
@ -440,7 +457,11 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
nameRes = R.string.action_view_follow_requests
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_person_add
|
||||
onClick = {
|
||||
val intent = AccountListActivity.newIntent(context, AccountListActivity.Type.FOLLOW_REQUESTS, accountLocked = accountLocked)
|
||||
val intent = AccountListActivity.newIntent(
|
||||
context,
|
||||
AccountListActivity.Type.FOLLOW_REQUESTS,
|
||||
accountLocked = accountLocked
|
||||
)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -474,8 +495,18 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
startActivityWithSlideInAnimation(AnnouncementsActivity.newIntent(context))
|
||||
}
|
||||
badgeStyle = BadgeStyle().apply {
|
||||
textColor = ColorHolder.fromColor(ThemeUtils.getColor(this@MainActivity, R.attr.colorOnPrimary))
|
||||
color = ColorHolder.fromColor(ThemeUtils.getColor(this@MainActivity, R.attr.colorPrimary))
|
||||
textColor = ColorHolder.fromColor(
|
||||
ThemeUtils.getColor(
|
||||
this@MainActivity,
|
||||
R.attr.colorOnPrimary
|
||||
)
|
||||
)
|
||||
color = ColorHolder.fromColor(
|
||||
ThemeUtils.getColor(
|
||||
this@MainActivity,
|
||||
R.attr.colorPrimary
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
DividerDrawerItem(),
|
||||
|
@ -483,7 +514,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
nameRes = R.string.action_view_account_preferences
|
||||
iconRes = R.drawable.ic_account_settings
|
||||
onClick = {
|
||||
val intent = PreferencesActivity.newIntent(context, PreferencesActivity.ACCOUNT_PREFERENCES)
|
||||
val intent = PreferencesActivity.newIntent(
|
||||
context,
|
||||
PreferencesActivity.ACCOUNT_PREFERENCES
|
||||
)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -491,7 +525,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
nameRes = R.string.action_view_preferences
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_settings
|
||||
onClick = {
|
||||
val intent = PreferencesActivity.newIntent(context, PreferencesActivity.GENERAL_PREFERENCES)
|
||||
val intent = PreferencesActivity.newIntent(
|
||||
context,
|
||||
PreferencesActivity.GENERAL_PREFERENCES
|
||||
)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -544,16 +581,18 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
private fun setupTabs(selectNotificationTab: Boolean) {
|
||||
|
||||
val activeTabLayout = if (preferences.getString("mainNavPosition", "top") == "bottom") {
|
||||
val activeTabLayout = if (prefs.mainNavPosition == "bottom") {
|
||||
val actionBarSize = ThemeUtils.getDimension(this, R.attr.actionBarSize)
|
||||
val fabMargin = resources.getDimensionPixelSize(R.dimen.fabMargin)
|
||||
(binding.composeButton.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = actionBarSize + fabMargin
|
||||
(binding.composeButton.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin =
|
||||
actionBarSize + fabMargin
|
||||
binding.tabLayout.hide()
|
||||
binding.bottomTabLayout
|
||||
} else {
|
||||
binding.bottomNav.hide()
|
||||
(binding.viewPager.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 0
|
||||
(binding.composeButton.layoutParams as CoordinatorLayout.LayoutParams).anchorId = R.id.viewPager
|
||||
(binding.composeButton.layoutParams as CoordinatorLayout.LayoutParams).anchorId =
|
||||
R.id.viewPager
|
||||
binding.tabLayout
|
||||
}
|
||||
|
||||
|
@ -561,7 +600,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
val adapter = MainPagerAdapter(tabs, this)
|
||||
binding.viewPager.adapter = adapter
|
||||
TabLayoutMediator(activeTabLayout, binding.viewPager) { _: TabLayout.Tab?, _: Int -> }.attach()
|
||||
TabLayoutMediator(
|
||||
activeTabLayout,
|
||||
binding.viewPager
|
||||
) { _: TabLayout.Tab?, _: Int -> }.attach()
|
||||
activeTabLayout.removeAllTabs()
|
||||
for (i in tabs.indices) {
|
||||
val tab = activeTabLayout.newTab()
|
||||
|
@ -584,8 +626,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
|
||||
binding.viewPager.setPageTransformer(MarginPageTransformer(pageMargin))
|
||||
|
||||
val enableSwipeForTabs = preferences.getBoolean("enableSwipeForTabs", true)
|
||||
binding.viewPager.isUserInputEnabled = enableSwipeForTabs
|
||||
binding.viewPager.isUserInputEnabled = prefs.enableSwipeForTabs
|
||||
|
||||
onTabSelectedListener?.let {
|
||||
activeTabLayout.removeOnTabSelectedListener(it)
|
||||
|
@ -594,7 +635,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
onTabSelectedListener = object : OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
if (tab.position == notificationTabPosition) {
|
||||
NotificationHelper.clearNotificationsForActiveAccount(this@MainActivity, accountManager)
|
||||
NotificationHelper.clearNotificationsForActiveAccount(
|
||||
this@MainActivity,
|
||||
accountManager
|
||||
)
|
||||
}
|
||||
|
||||
binding.mainToolbar.title = tabs[tab.position].title(this@MainActivity)
|
||||
|
@ -660,7 +704,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
.setMessage(getString(R.string.action_logout_confirm, activeAccount.fullName))
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
lifecycleScope.launch {
|
||||
NotificationHelper.deleteNotificationChannelsForAccount(activeAccount, this@MainActivity)
|
||||
NotificationHelper.deleteNotificationChannelsForAccount(
|
||||
activeAccount,
|
||||
this@MainActivity
|
||||
)
|
||||
cacheUpdater.clearForUser(activeAccount.id)
|
||||
conversationRepository.deleteCacheForAccount(activeAccount.id)
|
||||
draftHelper.deleteAllDraftsAndAttachmentsForAccount(activeAccount.id)
|
||||
|
@ -709,7 +756,10 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
loadDrawerAvatar(me.avatar, false)
|
||||
|
||||
accountManager.updateActiveAccount(me)
|
||||
NotificationHelper.createNotificationChannelsForAccount(accountManager.activeAccount!!, this)
|
||||
NotificationHelper.createNotificationChannelsForAccount(
|
||||
accountManager.activeAccount!!,
|
||||
this
|
||||
)
|
||||
|
||||
accountLocked = me.locked
|
||||
|
||||
|
@ -720,7 +770,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
private fun loadDrawerAvatar(avatarUrl: String, showPlaceholder: Boolean) {
|
||||
val navIconSize = resources.getDimensionPixelSize(R.dimen.avatar_toolbar_nav_icon_size)
|
||||
|
||||
val animateAvatars = preferences.getBoolean("animateGifAvatars", false)
|
||||
val animateAvatars = prefs.animateAvatars
|
||||
|
||||
if (animateAvatars) {
|
||||
glide.asDrawable()
|
||||
|
@ -737,20 +787,26 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
override fun onLoadStarted(placeholder: Drawable?) {
|
||||
if (placeholder != null) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
binding.mainToolbar.navigationIcon =
|
||||
FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
transition: Transition<in Drawable>?
|
||||
) {
|
||||
if (resource is Animatable) {
|
||||
resource.start()
|
||||
}
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(resource, navIconSize, navIconSize)
|
||||
binding.mainToolbar.navigationIcon =
|
||||
FixedSizeDrawable(resource, navIconSize, navIconSize)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
if (placeholder != null) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
binding.mainToolbar.navigationIcon =
|
||||
FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -769,17 +825,26 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
override fun onLoadStarted(placeholder: Drawable?) {
|
||||
if (placeholder != null) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
binding.mainToolbar.navigationIcon =
|
||||
FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(BitmapDrawable(resources, resource), navIconSize, navIconSize)
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap,
|
||||
transition: Transition<in Bitmap>?
|
||||
) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(
|
||||
BitmapDrawable(resources, resource),
|
||||
navIconSize,
|
||||
navIconSize
|
||||
)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
if (placeholder != null) {
|
||||
binding.mainToolbar.navigationIcon = FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
binding.mainToolbar.navigationIcon =
|
||||
FixedSizeDrawable(placeholder, navIconSize, navIconSize)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -802,23 +867,28 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
}
|
||||
|
||||
private fun updateAnnouncementsBadge() {
|
||||
binding.mainDrawer.updateBadge(DRAWER_ITEM_ANNOUNCEMENTS, StringHolder(if (unreadAnnouncementsCount <= 0) null else unreadAnnouncementsCount.toString()))
|
||||
binding.mainDrawer.updateBadge(
|
||||
DRAWER_ITEM_ANNOUNCEMENTS,
|
||||
StringHolder(if (unreadAnnouncementsCount <= 0) null else unreadAnnouncementsCount.toString())
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateProfiles() {
|
||||
val animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
val profiles: MutableList<IProfile> = accountManager.getAllAccountsOrderedByActive().map { acc ->
|
||||
val emojifiedName = EmojiCompat.get().process(acc.displayName.emojify(acc.emojis, header, animateEmojis))
|
||||
val animateEmojis = prefs.animateEmojis
|
||||
val profiles: MutableList<IProfile> =
|
||||
accountManager.getAllAccountsOrderedByActive().map { acc ->
|
||||
val emojifiedName = EmojiCompat.get()
|
||||
.process(acc.displayName.emojify(acc.emojis, header, animateEmojis))
|
||||
|
||||
ProfileDrawerItem().apply {
|
||||
isSelected = acc.isActive
|
||||
nameText = emojifiedName
|
||||
iconUrl = acc.profilePictureUrl
|
||||
isNameShown = true
|
||||
identifier = acc.id
|
||||
descriptionText = acc.fullName
|
||||
}
|
||||
}.toMutableList()
|
||||
ProfileDrawerItem().apply {
|
||||
isSelected = acc.isActive
|
||||
nameText = emojifiedName
|
||||
iconUrl = acc.profilePictureUrl
|
||||
isNameShown = true
|
||||
identifier = acc.id
|
||||
descriptionText = acc.fullName
|
||||
}
|
||||
}.toMutableList()
|
||||
|
||||
// reuse the already existing "add account" item
|
||||
for (profile in header.profiles.orEmpty()) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import autodispose2.AutoDisposePlugins
|
|||
import com.keylesspalace.tusky.components.notifications.NotificationWorkerFactory
|
||||
import com.keylesspalace.tusky.di.AppInjector
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.EmojiCompatFont
|
||||
import com.keylesspalace.tusky.util.LocaleManager
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
|
@ -44,6 +45,9 @@ class TuskyApplication : Application(), HasAndroidInjector {
|
|||
@Inject
|
||||
lateinit var notificationWorkerFactory: NotificationWorkerFactory
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
override fun onCreate() {
|
||||
// Uncomment me to get StrictMode violation logs
|
||||
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
|
@ -63,17 +67,16 @@ class TuskyApplication : Application(), HasAndroidInjector {
|
|||
|
||||
AppInjector.init(this)
|
||||
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
// init the custom emoji fonts
|
||||
val emojiSelection = preferences.getInt(PrefKeys.EMOJI, 0)
|
||||
val emojiSelection = prefs.emojiFont
|
||||
val emojiConfig = EmojiCompatFont.byId(emojiSelection)
|
||||
.getConfig(this)
|
||||
.setReplaceAll(true)
|
||||
EmojiCompat.init(emojiConfig)
|
||||
|
||||
// init night mode
|
||||
val theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT)
|
||||
val theme = prefs.appTheme
|
||||
ThemeUtils.setAppNightMode(theme)
|
||||
|
||||
RxJavaPlugins.setErrorHandler {
|
||||
|
@ -89,7 +92,8 @@ class TuskyApplication : Application(), HasAndroidInjector {
|
|||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
localeManager = LocaleManager(base)
|
||||
// special case: injected field cannot be injected here yet so we create Prefs by hand
|
||||
localeManager = LocaleManager(Prefs(base))
|
||||
super.attachBaseContext(localeManager.setLocale(base))
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,14 @@ import com.keylesspalace.tusky.R
|
|||
import com.keylesspalace.tusky.databinding.ItemAutocompleteAccountBinding
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
import com.keylesspalace.tusky.util.loadAvatar
|
||||
|
||||
class AccountSelectionAdapter(context: Context) : ArrayAdapter<AccountEntity>(context, R.layout.item_autocomplete_account) {
|
||||
class AccountSelectionAdapter(
|
||||
context: Context,
|
||||
private val prefs: Prefs,
|
||||
) : ArrayAdapter<AccountEntity>(context, R.layout.item_autocomplete_account) {
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val binding = if (convertView == null) {
|
||||
|
@ -39,14 +43,15 @@ class AccountSelectionAdapter(context: Context) : ArrayAdapter<AccountEntity>(co
|
|||
|
||||
val account = getItem(position)
|
||||
if (account != null) {
|
||||
val pm = PreferenceManager.getDefaultSharedPreferences(binding.avatar.context)
|
||||
val animateEmojis = pm.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
// TODO: is this even okay to do prefs things for each invocation here?
|
||||
val animateEmojis = prefs.animateEmojis
|
||||
|
||||
binding.username.text = account.fullName
|
||||
binding.displayName.text = account.displayName.emojify(account.emojis, binding.displayName, animateEmojis)
|
||||
binding.displayName.text =
|
||||
account.displayName.emojify(account.emojis, binding.displayName, animateEmojis)
|
||||
|
||||
val avatarRadius = context.resources.getDimensionPixelSize(R.dimen.avatar_radius_42dp)
|
||||
val animateAvatar = pm.getBoolean("animateGifAvatars", false)
|
||||
val animateAvatar = prefs.animateAvatars
|
||||
|
||||
loadAvatar(account.profilePictureUrl, binding.avatar, avatarRadius, animateAvatar)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class AccountViewHolder extends RecyclerView.ViewHolder {
|
|||
displayName = itemView.findViewById(R.id.account_display_name);
|
||||
avatar = itemView.findViewById(R.id.account_avatar);
|
||||
avatarInset = itemView.findViewById(R.id.account_avatar_inset);
|
||||
// TODO: wtf
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(itemView.getContext());
|
||||
showBotOverlay = sharedPrefs.getBoolean("showBotOverlay", true);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
|||
import com.keylesspalace.tusky.interfaces.LinkListener
|
||||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.DefaultTextWatcher
|
||||
import com.keylesspalace.tusky.util.Error
|
||||
import com.keylesspalace.tusky.util.Loading
|
||||
|
@ -78,7 +79,6 @@ import com.keylesspalace.tusky.util.emojify
|
|||
import com.keylesspalace.tusky.util.getDomain
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.loadAvatar
|
||||
import com.keylesspalace.tusky.util.openLink
|
||||
import com.keylesspalace.tusky.util.setClickableText
|
||||
import com.keylesspalace.tusky.util.show
|
||||
import com.keylesspalace.tusky.util.viewBinding
|
||||
|
@ -96,6 +96,8 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
|
|||
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: AccountViewModel by viewModels { viewModelFactory }
|
||||
|
||||
|
@ -146,10 +148,9 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
|
|||
// Obtain information to fill out the profile.
|
||||
viewModel.setAccountInfo(intent.getStringExtra(KEY_ACCOUNT_ID)!!)
|
||||
|
||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
animateAvatar = sharedPrefs.getBoolean("animateGifAvatars", false)
|
||||
animateEmojis = sharedPrefs.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
hideFab = sharedPrefs.getBoolean("fabHide", false)
|
||||
animateAvatar = prefs.animateAvatars
|
||||
animateEmojis = prefs.animateEmojis
|
||||
hideFab = prefs.hideFab
|
||||
|
||||
handleWindowInsets()
|
||||
setupToolbar()
|
||||
|
@ -214,8 +215,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
|
|||
}
|
||||
|
||||
// If wellbeing mode is enabled, follow stats and posts count should be hidden
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_PROFILE, false)
|
||||
val wellbeingEnabled = prefs.hideStatsProfile
|
||||
|
||||
if (wellbeingEnabled) {
|
||||
binding.accountStatuses.hide()
|
||||
|
@ -577,8 +577,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
|
|||
showingReblogs = relation.showingReblogs
|
||||
|
||||
// If wellbeing mode is enabled, "follows you" text should not be visible
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_PROFILE, false)
|
||||
val wellbeingEnabled = prefs.hideStatsProfile
|
||||
|
||||
binding.accountFollowsYouTextView.visible(relation.followedBy && !wellbeingEnabled)
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ package com.keylesspalace.tusky.components.announcements
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.PopupWindow
|
||||
|
@ -34,6 +33,7 @@ import com.keylesspalace.tusky.databinding.ActivityAnnouncementsBinding
|
|||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.Error
|
||||
import com.keylesspalace.tusky.util.Loading
|
||||
import com.keylesspalace.tusky.util.Success
|
||||
|
@ -47,6 +47,8 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
|
|||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: AnnouncementsViewModel by viewModels { viewModelFactory }
|
||||
|
||||
|
@ -86,9 +88,8 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
|
|||
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
|
||||
binding.announcementsList.addItemDecoration(divider)
|
||||
|
||||
val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
|
||||
val animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
val wellbeingEnabled = prefs.hideStatsPosts
|
||||
val animateEmojis = prefs.animateEmojis
|
||||
|
||||
adapter = AnnouncementAdapter(emptyList(), this, wellbeingEnabled, animateEmojis)
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.app.ProgressDialog
|
|||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
|
@ -75,6 +74,7 @@ import com.keylesspalace.tusky.entity.Emoji
|
|||
import com.keylesspalace.tusky.entity.NewPoll
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.ComposeTokenizer
|
||||
import com.keylesspalace.tusky.util.PickMediaFiles
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
|
@ -112,6 +112,8 @@ class ComposeActivity :
|
|||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private lateinit var composeOptionsBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var addMediaBehavior: BottomSheetBehavior<*>
|
||||
|
@ -163,8 +165,7 @@ class ComposeActivity :
|
|||
accountManager.setActiveAccount(accountId)
|
||||
}
|
||||
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT)
|
||||
val theme = prefs.appTheme
|
||||
if (theme == "black") {
|
||||
setTheme(R.style.TuskyDialogActivityBlackTheme)
|
||||
}
|
||||
|
@ -174,7 +175,7 @@ class ComposeActivity :
|
|||
// do not do anything when not logged in, activity will be finished in super.onCreate() anyway
|
||||
val activeAccount = accountManager.activeAccount ?: return
|
||||
|
||||
setupAvatar(preferences, activeAccount)
|
||||
setupAvatar(activeAccount)
|
||||
val mediaAdapter = MediaPreviewAdapter(
|
||||
this,
|
||||
onAddCaption = { item ->
|
||||
|
@ -210,7 +211,7 @@ class ComposeActivity :
|
|||
binding.composeScheduleView.setDateTime(composeOptions?.scheduledAt)
|
||||
}
|
||||
|
||||
setupComposeField(preferences, viewModel.startingText)
|
||||
setupComposeField(viewModel.startingText)
|
||||
setupContentWarningField(composeOptions?.contentWarning)
|
||||
setupPollView()
|
||||
applyShareIntent(intent, savedInstanceState)
|
||||
|
@ -295,7 +296,7 @@ class ComposeActivity :
|
|||
binding.composeContentWarningField.onTextChanged { _, _, _, _ -> updateVisibleCharactersLeft() }
|
||||
}
|
||||
|
||||
private fun setupComposeField(preferences: SharedPreferences, startingText: String?) {
|
||||
private fun setupComposeField(startingText: String?) {
|
||||
binding.composeEditField.setOnReceiveContentListener(this)
|
||||
|
||||
binding.composeEditField.setOnKeyListener { _, keyCode, event -> this.onKeyDown(keyCode, event) }
|
||||
|
@ -303,8 +304,8 @@ class ComposeActivity :
|
|||
binding.composeEditField.setAdapter(
|
||||
ComposeAutoCompleteAdapter(
|
||||
this,
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
prefs.animateAvatars,
|
||||
prefs.animateEmojis,
|
||||
)
|
||||
)
|
||||
binding.composeEditField.setTokenizer(ComposeTokenizer())
|
||||
|
@ -429,13 +430,13 @@ class ComposeActivity :
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupAvatar(preferences: SharedPreferences, activeAccount: AccountEntity) {
|
||||
private fun setupAvatar(activeAccount: AccountEntity) {
|
||||
val actionBarSizeAttr = intArrayOf(R.attr.actionBarSize)
|
||||
val a = obtainStyledAttributes(null, actionBarSizeAttr)
|
||||
val avatarSize = a.getDimensionPixelSize(0, 1)
|
||||
a.recycle()
|
||||
|
||||
val animateAvatars = preferences.getBoolean("animateGifAvatars", false)
|
||||
val animateAvatars = prefs.animateAvatars
|
||||
loadAvatar(
|
||||
activeAccount.profilePictureUrl,
|
||||
binding.composeAvatar,
|
||||
|
|
|
@ -39,6 +39,7 @@ import com.keylesspalace.tusky.fragment.SFragment
|
|||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.CardViewMode
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
|
@ -56,6 +57,8 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
|
|||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: ConversationsViewModel by viewModels { viewModelFactory }
|
||||
|
||||
|
@ -73,19 +76,17 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
|
|||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(view.context)
|
||||
|
||||
val statusDisplayOptions = StatusDisplayOptions(
|
||||
animateAvatars = preferences.getBoolean("animateGifAvatars", false),
|
||||
mediaPreviewEnabled = accountManager.activeAccount?.mediaPreviewEnabled ?: true,
|
||||
useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false),
|
||||
showBotOverlay = preferences.getBoolean("showBotOverlay", true),
|
||||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
animateAvatars = prefs.animateAvatars,
|
||||
mediaPreviewEnabled = accountManager.activeAccount?.mediaPreviewEnabled ?: true,
|
||||
useAbsoluteTime = prefs.useAbsoluteTime,
|
||||
showBotOverlay = prefs.showBotOverlay,
|
||||
useBlurhash = prefs.useBlurhash,
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
confirmFavourites = preferences.getBoolean("confirmFavourites", false),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
confirmReblogs = prefs.confirmReblogs,
|
||||
confirmFavourites = prefs.confirmFavourites,
|
||||
hideStats = prefs.hideStatsPosts,
|
||||
animateEmojis = prefs.animateEmojis,
|
||||
)
|
||||
|
||||
adapter = ConversationAdapter(statusDisplayOptions, this)
|
||||
|
|
|
@ -51,6 +51,7 @@ class LoginActivity : BaseActivity(), Injectable {
|
|||
|
||||
private val binding by viewBinding(ActivityLoginBinding::inflate)
|
||||
|
||||
/** Special SharedPreferences for persisting login state in some cases. */
|
||||
private lateinit var preferences: SharedPreferences
|
||||
|
||||
private val oauthRedirectUri: String
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.keylesspalace.tusky.di.ViewModelFactory
|
|||
import com.keylesspalace.tusky.entity.Attachment
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.CardViewMode
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
import com.keylesspalace.tusky.util.viewBinding
|
||||
|
@ -60,6 +61,9 @@ class ReportStatusesFragment : Fragment(R.layout.fragment_report_statuses), Inje
|
|||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: ReportViewModel by activityViewModels { viewModelFactory }
|
||||
|
||||
private val binding by viewBinding(FragmentReportStatusesBinding::bind)
|
||||
|
@ -105,18 +109,17 @@ class ReportStatusesFragment : Fragment(R.layout.fragment_report_statuses), Inje
|
|||
}
|
||||
|
||||
private fun initStatusesView() {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val statusDisplayOptions = StatusDisplayOptions(
|
||||
animateAvatars = false,
|
||||
mediaPreviewEnabled = accountManager.activeAccount?.mediaPreviewEnabled ?: true,
|
||||
useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false),
|
||||
useAbsoluteTime = prefs.useAbsoluteTime,
|
||||
showBotOverlay = false,
|
||||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
useBlurhash = prefs.useBlurhash,
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
confirmFavourites = preferences.getBoolean("confirmFavourites", false),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
confirmReblogs = prefs.confirmReblogs,
|
||||
confirmFavourites = prefs.confirmFavourites,
|
||||
hideStats = prefs.hideStatsPosts,
|
||||
animateEmojis = prefs.animateEmojis,
|
||||
)
|
||||
|
||||
adapter = StatusesAdapter(statusDisplayOptions, viewModel.statusViewState, this)
|
||||
|
|
|
@ -21,16 +21,19 @@ import androidx.preference.PreferenceManager
|
|||
import com.keylesspalace.tusky.components.search.adapter.SearchAccountsAdapter
|
||||
import com.keylesspalace.tusky.entity.TimelineAccount
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Inject
|
||||
|
||||
class SearchAccountsFragment : SearchFragment<TimelineAccount>() {
|
||||
override fun createAdapter(): PagingDataAdapter<TimelineAccount, *> {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(binding.searchRecyclerView.context)
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
override fun createAdapter(): PagingDataAdapter<TimelineAccount, *> {
|
||||
return SearchAccountsAdapter(
|
||||
this,
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
animateAvatars = prefs.animateAvatars,
|
||||
animateEmojis = prefs.animateEmojis,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ import com.keylesspalace.tusky.entity.Status.Mention
|
|||
import com.keylesspalace.tusky.interfaces.AccountSelectionListener
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.CardViewMode
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
import com.keylesspalace.tusky.util.openLink
|
||||
|
@ -61,8 +62,11 @@ import com.keylesspalace.tusky.viewdata.AttachmentViewData
|
|||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Inject
|
||||
|
||||
class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), StatusActionListener {
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
override val data: Flow<PagingData<StatusViewData.Concrete>>
|
||||
get() = viewModel.statusesFlow
|
||||
|
@ -71,18 +75,17 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
|
|||
get() = super.adapter as SearchStatusesAdapter
|
||||
|
||||
override fun createAdapter(): PagingDataAdapter<StatusViewData.Concrete, *> {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(binding.searchRecyclerView.context)
|
||||
val statusDisplayOptions = StatusDisplayOptions(
|
||||
animateAvatars = preferences.getBoolean("animateGifAvatars", false),
|
||||
animateAvatars = prefs.animateAvatars,
|
||||
mediaPreviewEnabled = viewModel.mediaPreviewEnabled,
|
||||
useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false),
|
||||
showBotOverlay = preferences.getBoolean("showBotOverlay", true),
|
||||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
useAbsoluteTime = prefs.useAbsoluteTime,
|
||||
showBotOverlay = prefs.showBotOverlay,
|
||||
useBlurhash = prefs.useBlurhash,
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
||||
confirmFavourites = preferences.getBoolean("confirmFavourites", false),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
confirmReblogs = prefs.confirmReblogs,
|
||||
confirmFavourites = prefs.confirmFavourites,
|
||||
hideStats = prefs.hideStatsPosts,
|
||||
animateEmojis = prefs.animateEmojis,
|
||||
)
|
||||
|
||||
binding.searchRecyclerView.addItemDecoration(DividerItemDecoration(binding.searchRecyclerView.context, DividerItemDecoration.VERTICAL))
|
||||
|
|
|
@ -56,6 +56,7 @@ import com.keylesspalace.tusky.interfaces.RefreshableFragment
|
|||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.CardViewMode
|
||||
import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
|
@ -88,6 +89,9 @@ class TimelineFragment :
|
|||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val viewModel: TimelineViewModel by lazy {
|
||||
if (kind == TimelineViewModel.Kind.HOME) {
|
||||
ViewModelProvider(this, viewModelFactory)[CachedTimelineViewModel::class.java]
|
||||
|
@ -136,22 +140,17 @@ class TimelineFragment :
|
|||
|
||||
isSwipeToRefreshEnabled = arguments.getBoolean(ARG_ENABLE_SWIPE_TO_REFRESH, true)
|
||||
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val statusDisplayOptions = StatusDisplayOptions(
|
||||
animateAvatars = preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false),
|
||||
animateAvatars = prefs.animateAvatars,
|
||||
mediaPreviewEnabled = accountManager.activeAccount!!.mediaPreviewEnabled,
|
||||
useAbsoluteTime = preferences.getBoolean(PrefKeys.ABSOLUTE_TIME_VIEW, false),
|
||||
showBotOverlay = preferences.getBoolean(PrefKeys.SHOW_BOT_OVERLAY, true),
|
||||
useBlurhash = preferences.getBoolean(PrefKeys.USE_BLURHASH, true),
|
||||
cardViewMode = if (preferences.getBoolean(
|
||||
PrefKeys.SHOW_CARDS_IN_TIMELINES,
|
||||
false
|
||||
)
|
||||
) CardViewMode.INDENTED else CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean(PrefKeys.CONFIRM_REBLOGS, true),
|
||||
confirmFavourites = preferences.getBoolean(PrefKeys.CONFIRM_FAVOURITES, false),
|
||||
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
useAbsoluteTime = prefs.useAbsoluteTime,
|
||||
showBotOverlay = prefs.showBotOverlay,
|
||||
useBlurhash = prefs.useBlurhash,
|
||||
cardViewMode = if (prefs.showCardsInTimelines) CardViewMode.INDENTED else CardViewMode.NONE,
|
||||
confirmReblogs = prefs.confirmReblogs,
|
||||
confirmFavourites = prefs.confirmFavourites,
|
||||
hideStats = prefs.hideStatsPosts,
|
||||
animateEmojis = prefs.animateEmojis,
|
||||
)
|
||||
adapter = TimelinePagingAdapter(
|
||||
statusDisplayOptions,
|
||||
|
@ -184,16 +183,28 @@ class TimelineFragment :
|
|||
is LoadState.NotLoading -> {
|
||||
if (loadState.append is LoadState.NotLoading && loadState.source.refresh is LoadState.NotLoading) {
|
||||
binding.statusView.show()
|
||||
binding.statusView.setup(R.drawable.elephant_friend_empty, R.string.message_empty, null)
|
||||
binding.statusView.setup(
|
||||
R.drawable.elephant_friend_empty,
|
||||
R.string.message_empty,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
is LoadState.Error -> {
|
||||
binding.statusView.show()
|
||||
|
||||
if ((loadState.refresh as LoadState.Error).error is IOException) {
|
||||
binding.statusView.setup(R.drawable.elephant_offline, R.string.error_network, null)
|
||||
binding.statusView.setup(
|
||||
R.drawable.elephant_offline,
|
||||
R.string.error_network,
|
||||
null
|
||||
)
|
||||
} else {
|
||||
binding.statusView.setup(R.drawable.elephant_error, R.string.error_generic, null)
|
||||
binding.statusView.setup(
|
||||
R.drawable.elephant_error,
|
||||
R.string.error_generic,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
is LoadState.Loading -> {
|
||||
|
@ -209,7 +220,10 @@ class TimelineFragment :
|
|||
binding.recyclerView.post {
|
||||
if (getView() != null) {
|
||||
if (isSwipeToRefreshEnabled) {
|
||||
binding.recyclerView.scrollBy(0, Utils.dpToPx(requireContext(), -30))
|
||||
binding.recyclerView.scrollBy(
|
||||
0,
|
||||
Utils.dpToPx(requireContext(), -30)
|
||||
)
|
||||
} else binding.recyclerView.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
|
@ -224,8 +238,7 @@ class TimelineFragment :
|
|||
}
|
||||
|
||||
if (actionButtonPresent()) {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
hideFab = preferences.getBoolean("fabHide", false)
|
||||
hideFab = prefs.hideFab
|
||||
scrollListener = object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(view: RecyclerView, dx: Int, dy: Int) {
|
||||
val composeButton = (activity as ActionButtonActivity).actionButton
|
||||
|
@ -388,9 +401,9 @@ class TimelineFragment :
|
|||
|
||||
override fun onViewAccount(id: String) {
|
||||
if ((
|
||||
viewModel.kind == TimelineViewModel.Kind.USER ||
|
||||
viewModel.kind == TimelineViewModel.Kind.USER_WITH_REPLIES
|
||||
) &&
|
||||
viewModel.kind == TimelineViewModel.Kind.USER ||
|
||||
viewModel.kind == TimelineViewModel.Kind.USER_WITH_REPLIES
|
||||
) &&
|
||||
viewModel.id == id
|
||||
) {
|
||||
/* If already viewing an account page, then any requests to view that account page
|
||||
|
@ -401,10 +414,9 @@ class TimelineFragment :
|
|||
}
|
||||
|
||||
private fun onPreferenceChanged(key: String) {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
when (key) {
|
||||
PrefKeys.FAB_HIDE -> {
|
||||
hideFab = sharedPreferences.getBoolean(PrefKeys.FAB_HIDE, false)
|
||||
hideFab = prefs.hideFab
|
||||
}
|
||||
PrefKeys.MEDIA_PREVIEW_ENABLED -> {
|
||||
val enabled = accountManager.activeAccount!!.mediaPreviewEnabled
|
||||
|
@ -441,9 +453,9 @@ class TimelineFragment :
|
|||
|
||||
private fun actionButtonPresent(): Boolean {
|
||||
return viewModel.kind != TimelineViewModel.Kind.TAG &&
|
||||
viewModel.kind != TimelineViewModel.Kind.FAVOURITES &&
|
||||
viewModel.kind != TimelineViewModel.Kind.BOOKMARKS &&
|
||||
activity is ActionButtonActivity
|
||||
viewModel.kind != TimelineViewModel.Kind.FAVOURITES &&
|
||||
viewModel.kind != TimelineViewModel.Kind.BOOKMARKS &&
|
||||
activity is ActionButtonActivity
|
||||
}
|
||||
|
||||
private var talkBackWasEnabled = false
|
||||
|
@ -468,14 +480,17 @@ class TimelineFragment :
|
|||
* Auto dispose observable on pause
|
||||
*/
|
||||
private fun startUpdateTimestamp() {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val useAbsoluteTime = preferences.getBoolean(PrefKeys.ABSOLUTE_TIME_VIEW, false)
|
||||
val useAbsoluteTime = prefs.useAbsoluteTime
|
||||
if (!useAbsoluteTime) {
|
||||
Observable.interval(1, TimeUnit.MINUTES)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.autoDispose(this, Lifecycle.Event.ON_PAUSE)
|
||||
.subscribe {
|
||||
adapter.notifyItemRangeChanged(0, adapter.itemCount, listOf(StatusBaseViewHolder.Key.KEY_CREATED))
|
||||
adapter.notifyItemRangeChanged(
|
||||
0,
|
||||
adapter.itemCount,
|
||||
listOf(StatusBaseViewHolder.Key.KEY_CREATED)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package com.keylesspalace.tusky.components.timeline.viewmodel
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.ExperimentalPagingApi
|
||||
|
@ -41,6 +40,7 @@ import com.keylesspalace.tusky.entity.Poll
|
|||
import com.keylesspalace.tusky.network.FilterModel
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.network.TimelineCases
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.dec
|
||||
import com.keylesspalace.tusky.util.inc
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
|
@ -61,11 +61,11 @@ class CachedTimelineViewModel @Inject constructor(
|
|||
private val api: MastodonApi,
|
||||
eventHub: EventHub,
|
||||
accountManager: AccountManager,
|
||||
sharedPreferences: SharedPreferences,
|
||||
prefs: Prefs,
|
||||
filterModel: FilterModel,
|
||||
private val db: AppDatabase,
|
||||
private val gson: Gson
|
||||
) : TimelineViewModel(timelineCases, api, eventHub, accountManager, sharedPreferences, filterModel) {
|
||||
) : TimelineViewModel(timelineCases, api, eventHub, accountManager, prefs, filterModel) {
|
||||
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
override val statuses = Pager(
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package com.keylesspalace.tusky.components.timeline.viewmodel
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.ExperimentalPagingApi
|
||||
|
@ -35,6 +34,7 @@ import com.keylesspalace.tusky.entity.Status
|
|||
import com.keylesspalace.tusky.network.FilterModel
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.network.TimelineCases
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.dec
|
||||
import com.keylesspalace.tusky.util.getDomain
|
||||
import com.keylesspalace.tusky.util.inc
|
||||
|
@ -58,9 +58,9 @@ class NetworkTimelineViewModel @Inject constructor(
|
|||
private val api: MastodonApi,
|
||||
eventHub: EventHub,
|
||||
accountManager: AccountManager,
|
||||
sharedPreferences: SharedPreferences,
|
||||
prefs: Prefs,
|
||||
filterModel: FilterModel
|
||||
) : TimelineViewModel(timelineCases, api, eventHub, accountManager, sharedPreferences, filterModel) {
|
||||
) : TimelineViewModel(timelineCases, api, eventHub, accountManager, prefs, filterModel) {
|
||||
|
||||
var currentSource: NetworkTimelinePagingSource? = null
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package com.keylesspalace.tusky.components.timeline.viewmodel
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
@ -41,6 +40,7 @@ import com.keylesspalace.tusky.network.FilterModel
|
|||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.network.TimelineCases
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -53,7 +53,7 @@ abstract class TimelineViewModel(
|
|||
private val api: MastodonApi,
|
||||
private val eventHub: EventHub,
|
||||
protected val accountManager: AccountManager,
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val prefs: Prefs,
|
||||
private val filterModel: FilterModel
|
||||
) : ViewModel() {
|
||||
|
||||
|
@ -81,10 +81,8 @@ abstract class TimelineViewModel(
|
|||
this.tags = tags
|
||||
|
||||
if (kind == Kind.HOME) {
|
||||
filterRemoveReplies =
|
||||
!sharedPreferences.getBoolean(PrefKeys.TAB_FILTER_HOME_REPLIES, true)
|
||||
filterRemoveReblogs =
|
||||
!sharedPreferences.getBoolean(PrefKeys.TAB_FILTER_HOME_BOOSTS, true)
|
||||
filterRemoveReplies = !prefs.tabFilterHomeReplies
|
||||
filterRemoveReblogs = !prefs.tabFilterHomeBoosts
|
||||
}
|
||||
this.alwaysShowSensitiveMedia = accountManager.activeAccount!!.alwaysShowSensitiveMedia
|
||||
this.alwaysOpenSpoilers = accountManager.activeAccount!!.alwaysOpenSpoiler
|
||||
|
@ -182,7 +180,7 @@ abstract class TimelineViewModel(
|
|||
private fun onPreferenceChanged(key: String) {
|
||||
when (key) {
|
||||
PrefKeys.TAB_FILTER_HOME_REPLIES -> {
|
||||
val filter = sharedPreferences.getBoolean(PrefKeys.TAB_FILTER_HOME_REPLIES, true)
|
||||
val filter = prefs.tabFilterHomeReplies
|
||||
val oldRemoveReplies = filterRemoveReplies
|
||||
filterRemoveReplies = kind == Kind.HOME && !filter
|
||||
if (oldRemoveReplies != filterRemoveReplies) {
|
||||
|
@ -190,7 +188,7 @@ abstract class TimelineViewModel(
|
|||
}
|
||||
}
|
||||
PrefKeys.TAB_FILTER_HOME_BOOSTS -> {
|
||||
val filter = sharedPreferences.getBoolean(PrefKeys.TAB_FILTER_HOME_BOOSTS, true)
|
||||
val filter = prefs.tabFilterHomeBoosts
|
||||
val oldRemoveReblogs = filterRemoveReblogs
|
||||
filterRemoveReblogs = kind == Kind.HOME && !filter
|
||||
if (oldRemoveReblogs != filterRemoveReblogs) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.keylesspalace.tusky.db.AccountManager
|
|||
import com.keylesspalace.tusky.json.SpannedTypeAdapter
|
||||
import com.keylesspalace.tusky.network.InstanceSwitchAuthInterceptor
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.getNonNullString
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
@ -62,11 +63,11 @@ class NetworkModule {
|
|||
fun providesHttpClient(
|
||||
accountManager: AccountManager,
|
||||
context: Context,
|
||||
preferences: SharedPreferences
|
||||
prefs: Prefs,
|
||||
): OkHttpClient {
|
||||
val httpProxyEnabled = preferences.getBoolean("httpProxyEnabled", false)
|
||||
val httpServer = preferences.getNonNullString("httpProxyServer", "")
|
||||
val httpPort = preferences.getNonNullString("httpProxyPort", "-1").toIntOrNull() ?: -1
|
||||
val httpProxyEnabled = prefs.httpProxyEnabled
|
||||
val httpServer = prefs.httpProxyServer
|
||||
val httpPort = prefs.httpProxyPort.toIntOrNull() ?: -1
|
||||
val cacheSize = 25 * 1024 * 1024L // 25 MiB
|
||||
val builder = OkHttpClient.Builder()
|
||||
.addInterceptor { chain ->
|
||||
|
|
|
@ -47,6 +47,7 @@ import com.keylesspalace.tusky.entity.TimelineAccount
|
|||
import com.keylesspalace.tusky.interfaces.AccountActionListener
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import com.keylesspalace.tusky.util.HttpHeaderLink
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.show
|
||||
|
@ -65,6 +66,8 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct
|
|||
lateinit var api: MastodonApi
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
@Inject
|
||||
lateinit var prefs: Prefs
|
||||
|
||||
private val binding by viewBinding(FragmentAccountListBinding::bind)
|
||||
|
||||
|
@ -92,9 +95,8 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct
|
|||
|
||||
binding.recyclerView.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
|
||||
|
||||
val pm = PreferenceManager.getDefaultSharedPreferences(view.context)
|
||||
val animateAvatar = pm.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false)
|
||||
val animateEmojis = pm.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
val animateAvatar = prefs.animateAvatars
|
||||
val animateEmojis = prefs.animateEmojis
|
||||
|
||||
adapter = when (type) {
|
||||
Type.BLOCKS -> BlocksAdapter(this, animateAvatar, animateEmojis)
|
||||
|
|
|
@ -18,7 +18,6 @@ package com.keylesspalace.tusky.fragment;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
@ -73,6 +72,7 @@ import com.keylesspalace.tusky.interfaces.ActionButtonActivity;
|
|||
import com.keylesspalace.tusky.interfaces.ReselectableFragment;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.settings.PrefKeys;
|
||||
import com.keylesspalace.tusky.settings.Prefs;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.Either;
|
||||
import com.keylesspalace.tusky.util.HttpHeaderLink;
|
||||
|
@ -156,6 +156,8 @@ public class NotificationsFragment extends SFragment implements
|
|||
AccountManager accountManager;
|
||||
@Inject
|
||||
EventHub eventHub;
|
||||
@Inject
|
||||
Prefs prefs;
|
||||
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private RecyclerView recyclerView;
|
||||
|
@ -213,9 +215,8 @@ public class NotificationsFragment extends SFragment implements
|
|||
View rootView = inflater.inflate(R.layout.fragment_timeline_notifications, container, false);
|
||||
|
||||
@NonNull Context context = inflater.getContext(); // from inflater to silence warning
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
boolean showNotificationsFilterSetting = preferences.getBoolean("showNotificationsFilter", true);
|
||||
boolean showNotificationsFilterSetting = prefs.getShowNotificationsFilter();
|
||||
//Clear notifications on filter visibility change to force refresh
|
||||
if (showNotificationsFilterSetting != showNotificationsFilter)
|
||||
notifications.clear();
|
||||
|
@ -251,16 +252,16 @@ public class NotificationsFragment extends SFragment implements
|
|||
recyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
|
||||
|
||||
StatusDisplayOptions statusDisplayOptions = new StatusDisplayOptions(
|
||||
preferences.getBoolean("animateGifAvatars", false),
|
||||
prefs.getAnimateAvatars(),
|
||||
accountManager.getActiveAccount().getMediaPreviewEnabled(),
|
||||
preferences.getBoolean("absoluteTimeView", false),
|
||||
preferences.getBoolean("showBotOverlay", true),
|
||||
preferences.getBoolean("useBlurhash", true),
|
||||
prefs.getUseAbsoluteTime(),
|
||||
prefs.getShowBotOverlay(),
|
||||
prefs.getUseBlurhash(),
|
||||
CardViewMode.NONE,
|
||||
preferences.getBoolean("confirmReblogs", true),
|
||||
preferences.getBoolean("confirmFavourites", false),
|
||||
preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
prefs.getConfirmReblogs(),
|
||||
prefs.getConfirmFavourites(),
|
||||
prefs.getHideStatsPosts(),
|
||||
prefs.getAnimateEmojis()
|
||||
);
|
||||
|
||||
adapter = new NotificationsAdapter(accountManager.getActiveAccount().getAccountId(),
|
||||
|
@ -324,12 +325,11 @@ public class NotificationsFragment extends SFragment implements
|
|||
Activity activity = getActivity();
|
||||
if (activity == null) throw new AssertionError("Activity is null");
|
||||
|
||||
/* This is delayed until onActivityCreated solely because MainActivity.composeButton isn't
|
||||
* guaranteed to be set until then.
|
||||
* Use a modified scroll listener that both loads more notificationsEnabled as it goes, and hides
|
||||
* the compose button on down-scroll. */
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
hideFab = preferences.getBoolean("fabHide", false);
|
||||
// This is delayed until onActivityCreated solely because MainActivity.composeButton isn't
|
||||
// guaranteed to be set until then.
|
||||
// Use a modified scroll listener that both loads more notificationsEnabled as it goes, and hides
|
||||
// the compose button on down-scroll.
|
||||
hideFab = prefs.getHideFab();
|
||||
scrollListener = new EndlessOnScrollListener(layoutManager) {
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView view, int dx, int dy) {
|
||||
|
@ -798,11 +798,11 @@ public class NotificationsFragment extends SFragment implements
|
|||
|
||||
private void onPreferenceChanged(String key) {
|
||||
switch (key) {
|
||||
case "fabHide": {
|
||||
hideFab = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("fabHide", false);
|
||||
case PrefKeys.FAB_HIDE: {
|
||||
hideFab = prefs.getHideFab();
|
||||
break;
|
||||
}
|
||||
case "mediaPreviewEnabled": {
|
||||
case PrefKeys.MEDIA_PREVIEW_ENABLED: {
|
||||
boolean enabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
|
||||
if (enabled != adapter.isMediaPreviewEnabled()) {
|
||||
adapter.setMediaPreviewEnabled(enabled);
|
||||
|
@ -810,9 +810,9 @@ public class NotificationsFragment extends SFragment implements
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "showNotificationsFilter": {
|
||||
case PrefKeys.SHOW_NOTIFICATIONS_FILTER: {
|
||||
if (isAdded()) {
|
||||
showNotificationsFilter = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("showNotificationsFilter", true);
|
||||
showNotificationsFilter = prefs.getShowNotificationsFilter();
|
||||
updateFilterVisibility();
|
||||
fullyRefreshWithProgressBar(true);
|
||||
}
|
||||
|
@ -1224,8 +1224,7 @@ public class NotificationsFragment extends SFragment implements
|
|||
* Auto dispose observable on pause
|
||||
*/
|
||||
private void startUpdateTimestamp() {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false);
|
||||
boolean useAbsoluteTime = prefs.getUseAbsoluteTime();
|
||||
if (!useAbsoluteTime) {
|
||||
Observable.interval(1, TimeUnit.MINUTES)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
|
@ -17,7 +17,6 @@ package com.keylesspalace.tusky.fragment;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
@ -59,6 +58,7 @@ import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
|||
import com.keylesspalace.tusky.network.FilterModel;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.settings.PrefKeys;
|
||||
import com.keylesspalace.tusky.settings.Prefs;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate;
|
||||
|
@ -93,6 +93,8 @@ public final class ViewThreadFragment extends SFragment implements
|
|||
public EventHub eventHub;
|
||||
@Inject
|
||||
public FilterModel filterModel;
|
||||
@Inject
|
||||
public Prefs prefs;
|
||||
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private RecyclerView recyclerView;
|
||||
|
@ -129,22 +131,20 @@ public final class ViewThreadFragment extends SFragment implements
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
thisThreadsStatusId = getArguments().getString("id");
|
||||
SharedPreferences preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
StatusDisplayOptions statusDisplayOptions = new StatusDisplayOptions(
|
||||
preferences.getBoolean("animateGifAvatars", false),
|
||||
prefs.getAnimateAvatars(),
|
||||
accountManager.getActiveAccount().getMediaPreviewEnabled(),
|
||||
preferences.getBoolean("absoluteTimeView", false),
|
||||
preferences.getBoolean("showBotOverlay", true),
|
||||
preferences.getBoolean("useBlurhash", true),
|
||||
preferences.getBoolean("showCardsInTimelines", false) ?
|
||||
prefs.getUseAbsoluteTime(),
|
||||
prefs.getShowBotOverlay(),
|
||||
prefs.getUseBlurhash(),
|
||||
prefs.getShowCardsInTimelines() ?
|
||||
CardViewMode.INDENTED :
|
||||
CardViewMode.NONE,
|
||||
preferences.getBoolean("confirmReblogs", true),
|
||||
preferences.getBoolean("confirmFavourites", false),
|
||||
preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
||||
preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
prefs.getConfirmReblogs(),
|
||||
prefs.getConfirmFavourites(),
|
||||
prefs.getHideStatsPosts(),
|
||||
prefs.getAnimateEmojis()
|
||||
);
|
||||
adapter = new ThreadAdapter(statusDisplayOptions, this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
package com.keylesspalace.tusky.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.annotation.Keep
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
// TODO: do we every plan to use them as writable properties?
|
||||
// TODO: is this enough to preserve fields/names?
|
||||
// TODO: what about observing changes? Do we keep PrefKeys and reference them?
|
||||
@Keep
|
||||
class Prefs @Inject constructor(context: Context) {
|
||||
// TODO: not sure if should be lazy or non-cached at all
|
||||
private val sharedPreferences: SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
var appTheme by stringProperty(ThemeUtils.APP_THEME_DEFAULT)
|
||||
var emojiFont by intProperty(0, "selected_emoji_font")
|
||||
val hideFab by booleanProperty(false, "fabHide")
|
||||
var language by stringProperty(defaultValue = "default")
|
||||
val statusTextSize by stringProperty("medium")
|
||||
val mainNavPosition by stringProperty()
|
||||
val hideTopToolbar by booleanProperty(false)
|
||||
|
||||
val animateAvatars by booleanProperty(false, "animateGifAvatars")
|
||||
val useAbsoluteTime by booleanProperty(false, "absoluteTimeView")
|
||||
val showBotOverlay by booleanProperty(true)
|
||||
val useBlurhash by booleanProperty(true)
|
||||
val showNotificationsFilter by booleanProperty(true)
|
||||
val showCardsInTimelines by booleanProperty(false)
|
||||
val confirmReblogs by booleanProperty(true)
|
||||
val confirmFavourites by booleanProperty(false)
|
||||
val enableSwipeForTabs by booleanProperty(true)
|
||||
val customTabs by booleanProperty(false)
|
||||
val hideStatsPosts by booleanProperty(false, "wellbeingHideStatsPosts")
|
||||
val hideStatsProfile by booleanProperty(false, "wellbeingHideStatsProfile")
|
||||
val animateEmojis by booleanProperty(false, "animateCustomEmojis")
|
||||
val tabFilterHomeReplies by booleanProperty(true)
|
||||
val tabFilterHomeBoosts by booleanProperty(true)
|
||||
|
||||
val httpProxyEnabled by booleanProperty(false)
|
||||
val httpProxyServer by stringProperty(defaultValue = "")
|
||||
val httpProxyPort by stringProperty(defaultValue = "")
|
||||
|
||||
private fun stringProperty(overrideName: String? = null) =
|
||||
StringProperty(sharedPreferences, overrideName)
|
||||
|
||||
private fun stringProperty(
|
||||
defaultValue: String,
|
||||
overrideName: String? = null,
|
||||
): ReadWriteProperty<Prefs, String> =
|
||||
this.stringProperty(overrideName).withDefault(defaultValue)
|
||||
|
||||
private fun booleanProperty(
|
||||
defaultValue: Boolean,
|
||||
overrideName: String? = null,
|
||||
) = BooleanProperty(sharedPreferences, overrideName, defaultValue)
|
||||
|
||||
private fun intProperty(
|
||||
defaultValue: Int,
|
||||
overrideName: String? = null,
|
||||
) = IntProperty(sharedPreferences, overrideName, defaultValue)
|
||||
}
|
||||
|
||||
private fun <T, P> ReadWriteProperty<T, P?>.withDefault(
|
||||
default: P
|
||||
): ReadWriteProperty<T, P> = object : ReadWriteProperty<T, P> {
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): P {
|
||||
return this@withDefault.getValue(thisRef, property) ?: default
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: P) {
|
||||
this@withDefault.setValue(thisRef, property, value)
|
||||
}
|
||||
}
|
||||
|
||||
private class StringProperty(
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val overrideName: String?,
|
||||
) : ReadWriteProperty<Prefs, String?> {
|
||||
override fun getValue(thisRef: Prefs, property: KProperty<*>): String? {
|
||||
return sharedPreferences.getString(overrideName ?: property.name, null)
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Prefs, property: KProperty<*>, value: String?) {
|
||||
sharedPreferences.edit().putString(overrideName ?: property.name, value)
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
|
||||
private class BooleanProperty(
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val overrideName: String?,
|
||||
private val defaultValue: Boolean,
|
||||
) : ReadWriteProperty<Prefs, Boolean> {
|
||||
override fun getValue(thisRef: Prefs, property: KProperty<*>): Boolean {
|
||||
return sharedPreferences.getBoolean(
|
||||
overrideName ?: property.name,
|
||||
defaultValue,
|
||||
)
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Prefs, property: KProperty<*>, value: Boolean) {
|
||||
sharedPreferences.edit().putBoolean(overrideName ?: property.name, value)
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
|
||||
private class IntProperty(
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val overrideName: String?,
|
||||
private val defaultValue: Int,
|
||||
) : ReadWriteProperty<Prefs, Int> {
|
||||
override fun getValue(thisRef: Prefs, property: KProperty<*>): Int {
|
||||
return sharedPreferences.getInt(
|
||||
overrideName ?: property.name,
|
||||
defaultValue,
|
||||
)
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Prefs, property: KProperty<*>, value: Int) {
|
||||
sharedPreferences.edit().putInt(overrideName ?: property.name, value)
|
||||
.apply()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,14 @@
|
|||
package com.keylesspalace.tusky.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.annotation.Keep
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
enum class AppTheme(val value: String) {
|
||||
NIGHT("night"),
|
||||
DAY("day"),
|
||||
|
@ -62,4 +71,4 @@ object PrefKeys {
|
|||
|
||||
const val TAB_FILTER_HOME_REPLIES = "tabFilterHomeReplies"
|
||||
const val TAB_FILTER_HOME_BOOSTS = "tabFilterHomeBoosts"
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import com.keylesspalace.tusky.R
|
|||
import com.keylesspalace.tusky.entity.HashTag
|
||||
import com.keylesspalace.tusky.entity.Status.Mention
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
|
||||
fun getDomain(urlString: String?): String {
|
||||
val host = urlString?.toUri()?.host
|
||||
|
@ -184,7 +185,7 @@ fun createClickableText(text: String, link: String): CharSequence {
|
|||
*/
|
||||
fun Context.openLink(url: String) {
|
||||
val uri = url.toUri().normalizeScheme()
|
||||
val useCustomTabs = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("customTabs", false)
|
||||
val useCustomTabs = Prefs(this).customTabs
|
||||
|
||||
if (useCustomTabs) {
|
||||
openLinkInCustomTab(uri, this)
|
||||
|
|
|
@ -16,17 +16,16 @@
|
|||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import androidx.preference.PreferenceManager
|
||||
import java.util.Locale
|
||||
import com.keylesspalace.tusky.settings.Prefs
|
||||
import java.util.*
|
||||
|
||||
class LocaleManager(context: Context) {
|
||||
|
||||
private var prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
class LocaleManager(
|
||||
private val prefs: Prefs,
|
||||
) {
|
||||
|
||||
fun setLocale(context: Context): Context {
|
||||
val language = prefs.getNonNullString("language", "default")
|
||||
val language = prefs.language
|
||||
if (language == "default") {
|
||||
return context
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue