Wellbeing mode (#1992)

* Add wellbeing mode settings toggle

* Translate wellbeing mode string to german

* Disable fav/boost count on toots if wellbeing is enabled

* Hide follow/post stats on profiles

* Reload notifications when wellbeing mode is toggled

* Add wellbeing mode explainer dialog

* Move wellbeing filter timeline into own category

* Add toggles for quantitative stats

* Hide announcement badge counts if wellbeing is enabled

* Move fetching of wellbeing setting to activity

* Add wellbeing option to statusDisplayOptions

* Update post filters for all accounts

* Remove local translations

* Revert "Remove local translations"

This reverts commit e92e636a5c759b09649174ab68ec91bc13680287.

* Remove german translations
This commit is contained in:
Garrit Franke 2020-12-23 19:13:37 +01:00 committed by GitHub
commit 0fbb4e9713
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 164 additions and 29 deletions

View file

@ -32,6 +32,7 @@ import com.keylesspalace.tusky.util.LinkHelper
import com.keylesspalace.tusky.util.emojify
import kotlinx.android.synthetic.main.item_announcement.view.*
interface AnnouncementActionListener: LinkListener {
fun openReactionPicker(announcementId: String, target: View)
fun addReaction(announcementId: String, name: String)
@ -40,7 +41,8 @@ interface AnnouncementActionListener: LinkListener {
class AnnouncementAdapter(
private var items: List<Announcement> = emptyList(),
private val listener: AnnouncementActionListener
private val listener: AnnouncementActionListener,
private val wellbeingEnabled: Boolean = false
) : RecyclerView.Adapter<AnnouncementAdapter.AnnouncementViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnnouncementViewHolder {
@ -68,6 +70,14 @@ class AnnouncementAdapter(
fun bind(item: Announcement) {
LinkHelper.setClickableText(text, item.content, null, listener)
// If wellbeing mode is enabled, announcement badge counts should not be shown.
if (wellbeingEnabled) {
// Since reactions are not visible in wellbeing mode,
// we shouldn't be able to add any ourselves.
addReactionChip.visibility = View.GONE
return
}
item.reactions.forEachIndexed { i, reaction ->
(chips.getChildAt(i)?.takeUnless { it.id == R.id.addReactionChip } as Chip?
?: Chip(ContextThemeWrapper(view.context, R.style.Widget_MaterialComponents_Chip_Choice)).apply {

View file

@ -17,18 +17,23 @@ 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.MenuItem
import android.view.View
import android.widget.PopupWindow
import androidx.activity.viewModels
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.keylesspalace.tusky.*
import com.keylesspalace.tusky.BottomSheetActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.ViewTagActivity
import com.keylesspalace.tusky.adapter.EmojiAdapter
import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.di.ViewModelFactory
import com.keylesspalace.tusky.settings.PrefKeys
import com.keylesspalace.tusky.util.*
import com.keylesspalace.tusky.view.EmojiPicker
import kotlinx.android.synthetic.main.activity_announcements.*
@ -42,7 +47,7 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
private val viewModel: AnnouncementsViewModel by viewModels { viewModelFactory }
private val adapter = AnnouncementAdapter(emptyList(), this)
private lateinit var adapter: AnnouncementAdapter
private val picker by lazy { EmojiPicker(this) }
private val pickerDialog by lazy {
@ -75,6 +80,12 @@ class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener,
announcementsList.layoutManager = LinearLayoutManager(this)
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
announcementsList.addItemDecoration(divider)
val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val wellbeingEnabled = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
adapter = AnnouncementAdapter(emptyList(), this, wellbeingEnabled)
announcementsList.adapter = adapter
viewModel.announcements.observe(this) {

View file

@ -34,6 +34,7 @@ import com.keylesspalace.tusky.di.ViewModelFactory
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.util.CardViewMode
import com.keylesspalace.tusky.util.NetworkState
import com.keylesspalace.tusky.util.StatusDisplayOptions
@ -68,7 +69,9 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
showBotOverlay = preferences.getBoolean("showBotOverlay", true),
useBlurhash = preferences.getBoolean("useBlurhash", true),
cardViewMode = CardViewMode.NONE,
confirmReblogs = preferences.getBoolean("confirmReblogs", true)
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
)
adapter = ConversationAdapter(statusDisplayOptions, this, ::onTopLoaded, viewModel::retry)

View file

@ -19,10 +19,14 @@ import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.entity.Notification
import com.keylesspalace.tusky.settings.*
import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.deserialize
import com.keylesspalace.tusky.util.getNonNullString
import com.keylesspalace.tusky.util.serialize
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.colorInt
@ -35,6 +39,9 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
@Inject
lateinit var okhttpclient: OkHttpClient
@Inject
lateinit var accountManager: AccountManager
private val iconSize by lazy { resources.getDimensionPixelSize(R.dimen.preference_icon_size) }
private var httpProxyPref: Preference? = null
@ -192,6 +199,45 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
}
}
preferenceCategory(R.string.pref_title_wellbeing_mode) {
switchPreference {
title = getString(R.string.limit_notifications)
setDefaultValue(false)
key = PrefKeys.WELLBEING_LIMITED_NOTIFICATIONS
setOnPreferenceChangeListener { _, value ->
for (account in accountManager.accounts) {
val notificationFilter = deserialize(account.notificationsFilter).toMutableSet()
if (value == true) {
notificationFilter.add(Notification.Type.FAVOURITE)
notificationFilter.add(Notification.Type.FOLLOW)
notificationFilter.add(Notification.Type.REBLOG)
} else {
notificationFilter.remove(Notification.Type.FAVOURITE)
notificationFilter.remove(Notification.Type.FOLLOW)
notificationFilter.remove(Notification.Type.REBLOG)
}
account.notificationsFilter = serialize(notificationFilter)
accountManager.saveAccount(account)
}
true
}
}
switchPreference {
title = getString(R.string.wellbeing_hide_stats_posts)
setDefaultValue(false)
key = PrefKeys.WELLBEING_HIDE_STATS_POSTS
}
switchPreference {
title = getString(R.string.wellbeing_hide_stats_profile)
setDefaultValue(false)
key = PrefKeys.WELLBEING_HIDE_STATS_PROFILE
}
}
preferenceCategory(R.string.pref_title_proxy_settings) {
httpProxyPref = preference {
setTitle(R.string.pref_title_http_proxy_settings)

View file

@ -41,6 +41,7 @@ import com.keylesspalace.tusky.di.Injectable
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.util.CardViewMode
import com.keylesspalace.tusky.util.StatusDisplayOptions
import com.keylesspalace.tusky.util.hide
@ -118,7 +119,8 @@ class ReportStatusesFragment : Fragment(), Injectable, AdapterHandler {
showBotOverlay = false,
useBlurhash = preferences.getBoolean("useBlurhash", true),
cardViewMode = CardViewMode.NONE,
confirmReblogs = preferences.getBoolean("confirmReblogs", true)
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
)
adapter = StatusesAdapter(statusDisplayOptions,

View file

@ -52,6 +52,7 @@ import com.keylesspalace.tusky.entity.Status
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.util.CardViewMode
import com.keylesspalace.tusky.util.NetworkState
import com.keylesspalace.tusky.util.StatusDisplayOptions
@ -84,7 +85,8 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
showBotOverlay = preferences.getBoolean("showBotOverlay", true),
useBlurhash = preferences.getBoolean("useBlurhash", true),
cardViewMode = CardViewMode.NONE,
confirmReblogs = preferences.getBoolean("confirmReblogs", true)
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false)
)
searchRecyclerView.addItemDecoration(DividerItemDecoration(searchRecyclerView.context, DividerItemDecoration.VERTICAL))