Merge pull request #1270 from believethehype/gallery_options

add option for 2 profile gallery views
This commit is contained in:
Vitor Pamplona 2025-02-10 08:41:37 -05:00 committed by GitHub
commit c34c107a7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 92 additions and 8 deletions

View File

@ -35,6 +35,7 @@ data class Settings(
val dontShowPushNotificationSelector: Boolean = false, val dontShowPushNotificationSelector: Boolean = false,
val dontAskForNotificationPermissions: Boolean = false, val dontAskForNotificationPermissions: Boolean = false,
val featureSet: FeatureSetType = FeatureSetType.SIMPLIFIED, val featureSet: FeatureSetType = FeatureSetType.SIMPLIFIED,
val gallerySet: ProfileGalleryType = ProfileGalleryType.CLASSIC,
) )
enum class ThemeType( enum class ThemeType(
@ -75,6 +76,14 @@ enum class FeatureSetType(
PERFORMANCE(2, R.string.ui_feature_set_type_performance), PERFORMANCE(2, R.string.ui_feature_set_type_performance),
} }
enum class ProfileGalleryType(
val screenCode: Int,
val resourceId: Int,
) {
CLASSIC(0, R.string.gallery_type_classic),
MODERN(1, R.string.gallery_type_modern),
}
fun parseConnectivityType(code: Boolean?): ConnectivityType = fun parseConnectivityType(code: Boolean?): ConnectivityType =
when (code) { when (code) {
ConnectivityType.ALWAYS.prefCode -> ConnectivityType.ALWAYS ConnectivityType.ALWAYS.prefCode -> ConnectivityType.ALWAYS
@ -105,6 +114,15 @@ fun parseFeatureSetType(screenCode: Int): FeatureSetType =
} }
} }
fun parseGalleryType(screenCode: Int): ProfileGalleryType =
when (screenCode) {
ProfileGalleryType.CLASSIC.screenCode -> ProfileGalleryType.CLASSIC
ProfileGalleryType.MODERN.screenCode -> ProfileGalleryType.MODERN
else -> {
ProfileGalleryType.CLASSIC
}
}
enum class BooleanType( enum class BooleanType(
val prefCode: Boolean?, val prefCode: Boolean?,
val screenCode: Int, val screenCode: Int,

View File

@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.model.BooleanType import com.vitorpamplona.amethyst.model.BooleanType
import com.vitorpamplona.amethyst.model.ConnectivityType import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.FeatureSetType
import com.vitorpamplona.amethyst.model.ProfileGalleryType
import com.vitorpamplona.amethyst.model.Settings import com.vitorpamplona.amethyst.model.Settings
import com.vitorpamplona.amethyst.model.ThemeType import com.vitorpamplona.amethyst.model.ThemeType
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -56,6 +57,7 @@ class SettingsState {
var dontShowPushNotificationSelector by mutableStateOf<Boolean>(false) var dontShowPushNotificationSelector by mutableStateOf<Boolean>(false)
var dontAskForNotificationPermissions by mutableStateOf<Boolean>(false) var dontAskForNotificationPermissions by mutableStateOf<Boolean>(false)
var featureSet by mutableStateOf(FeatureSetType.SIMPLIFIED) var featureSet by mutableStateOf(FeatureSetType.SIMPLIFIED)
var gallerySet by mutableStateOf(ProfileGalleryType.CLASSIC)
var isOnMobileData: State<Boolean> = mutableStateOf(false) var isOnMobileData: State<Boolean> = mutableStateOf(false)
@ -71,6 +73,14 @@ class SettingsState {
} }
} }
val modernGalleryStyle =
derivedStateOf {
when (gallerySet) {
ProfileGalleryType.CLASSIC -> false
ProfileGalleryType.MODERN -> true
}
}
val showUrlPreview = val showUrlPreview =
derivedStateOf { derivedStateOf {
when (automaticallyShowUrlPreview) { when (automaticallyShowUrlPreview) {
@ -117,6 +127,7 @@ class SharedPreferencesViewModel : ViewModel() {
sharedPrefs.automaticallyShowProfilePictures = savedSettings.automaticallyShowProfilePictures sharedPrefs.automaticallyShowProfilePictures = savedSettings.automaticallyShowProfilePictures
sharedPrefs.dontShowPushNotificationSelector = savedSettings.dontShowPushNotificationSelector sharedPrefs.dontShowPushNotificationSelector = savedSettings.dontShowPushNotificationSelector
sharedPrefs.dontAskForNotificationPermissions = savedSettings.dontAskForNotificationPermissions sharedPrefs.dontAskForNotificationPermissions = savedSettings.dontAskForNotificationPermissions
sharedPrefs.gallerySet = savedSettings.gallerySet
sharedPrefs.featureSet = savedSettings.featureSet sharedPrefs.featureSet = savedSettings.featureSet
updateLanguageInTheUI() updateLanguageInTheUI()
@ -191,6 +202,13 @@ class SharedPreferencesViewModel : ViewModel() {
} }
} }
fun updateGallerySetType(newgalleryType: ProfileGalleryType) {
if (sharedPrefs.gallerySet != newgalleryType) {
sharedPrefs.gallerySet = newgalleryType
saveSharedSettings()
}
}
fun dontShowPushNotificationSelector() { fun dontShowPushNotificationSelector() {
if (sharedPrefs.dontShowPushNotificationSelector == false) { if (sharedPrefs.dontShowPushNotificationSelector == false) {
sharedPrefs.dontShowPushNotificationSelector = true sharedPrefs.dontShowPushNotificationSelector = true
@ -237,6 +255,7 @@ class SharedPreferencesViewModel : ViewModel() {
sharedPrefs.dontShowPushNotificationSelector, sharedPrefs.dontShowPushNotificationSelector,
sharedPrefs.dontAskForNotificationPermissions, sharedPrefs.dontAskForNotificationPermissions,
sharedPrefs.featureSet, sharedPrefs.featureSet,
sharedPrefs.gallerySet,
), ),
) )
} }

View File

@ -46,6 +46,7 @@ fun GalleryCardCompose(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
ratio: Float = 1.0f,
) { ) {
WatchNoteEvent(baseNote = baseNote, accountViewModel = accountViewModel, shortPreview = true) { WatchNoteEvent(baseNote = baseNote, accountViewModel = accountViewModel, shortPreview = true) {
CheckHiddenFeedWatchBlockAndReport( CheckHiddenFeedWatchBlockAndReport(
@ -74,6 +75,7 @@ fun GalleryCardCompose(
modifier = modifier, modifier = modifier,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,
ratio = ratio,
) )
} else { } else {
RedirectableGalleryCard( RedirectableGalleryCard(
@ -82,6 +84,7 @@ fun GalleryCardCompose(
modifier = modifier, modifier = modifier,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,
ratio = ratio,
) )
} }
} }
@ -92,6 +95,7 @@ fun GalleryCardCompose(
modifier = modifier, modifier = modifier,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,
ratio = ratio,
) )
} }
} }
@ -105,6 +109,7 @@ fun RedirectableGalleryCard(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
ratio: Float = 1.0f,
) { ) {
QuickActionGallery(baseNote = galleryNote, accountViewModel = accountViewModel) { showPopup -> QuickActionGallery(baseNote = galleryNote, accountViewModel = accountViewModel) { showPopup ->
ClickableNote( ClickableNote(
@ -123,7 +128,7 @@ fun RedirectableGalleryCard(
note = galleryNote, note = galleryNote,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) { ) {
GalleryThumbnail(galleryNote, accountViewModel, nav) GalleryThumbnail(galleryNote, accountViewModel, nav, ratio = ratio)
} }
} }
} }

View File

@ -77,6 +77,7 @@ fun GalleryThumbnail(
baseNote: Note, baseNote: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
ratio: Float = 1.0f,
) { ) {
val noteState by baseNote.live().metadata.observeAsState() val noteState by baseNote.live().metadata.observeAsState()
val noteEvent = noteState?.note?.event ?: return val noteEvent = noteState?.note?.event ?: return
@ -134,7 +135,7 @@ fun GalleryThumbnail(
emptyList() emptyList()
} }
InnerRenderGalleryThumb(content, baseNote, accountViewModel) InnerRenderGalleryThumb(content, baseNote, accountViewModel, ratio)
} }
@Composable @Composable
@ -142,9 +143,10 @@ fun InnerRenderGalleryThumb(
content: List<MediaUrlContent>, content: List<MediaUrlContent>,
note: Note, note: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
ratio: Float = 1.0f,
) { ) {
if (content.isNotEmpty()) { if (content.isNotEmpty()) {
GalleryContentView(content, accountViewModel) GalleryContentView(content, accountViewModel, ratio = ratio)
} else { } else {
DisplayGalleryAuthorBanner(note) DisplayGalleryAuthorBanner(note)
} }
@ -162,16 +164,17 @@ fun DisplayGalleryAuthorBanner(note: Note) {
fun GalleryContentView( fun GalleryContentView(
contentList: List<MediaUrlContent>, contentList: List<MediaUrlContent>,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
ratio: Float = 1.0f,
) { ) {
AutoNonlazyGrid(contentList.size) { contentIndex -> AutoNonlazyGrid(contentList.size) { contentIndex ->
when (val content = contentList[contentIndex]) { when (val content = contentList[contentIndex]) {
is MediaUrlImage -> is MediaUrlImage ->
SensitivityWarning(content.contentWarning != null, accountViewModel) { SensitivityWarning(content.contentWarning != null, accountViewModel) {
UrlImageView(content, accountViewModel) UrlImageView(content, accountViewModel, ratio = ratio)
} }
is MediaUrlVideo -> is MediaUrlVideo ->
SensitivityWarning(content.contentWarning != null, accountViewModel) { SensitivityWarning(content.contentWarning != null, accountViewModel) {
UrlVideoView(content, accountViewModel) UrlVideoView(content, accountViewModel, ratio = ratio)
} }
} }
} }
@ -182,8 +185,9 @@ fun UrlImageView(
content: MediaUrlImage, content: MediaUrlImage,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
alwayShowImage: Boolean = false, alwayShowImage: Boolean = false,
ratio: Float = 1.0f,
) { ) {
val defaultModifier = Modifier.fillMaxSize().aspectRatio(1f) val defaultModifier = Modifier.fillMaxSize().aspectRatio(ratio)
val showImage = val showImage =
remember { remember {
@ -250,8 +254,9 @@ fun UrlImageView(
fun UrlVideoView( fun UrlVideoView(
content: MediaUrlVideo, content: MediaUrlVideo,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
ratio: Float = 1.0f,
) { ) {
val defaultModifier = Modifier.fillMaxSize().aspectRatio(1f) val defaultModifier = Modifier.fillMaxSize().aspectRatio(ratio)
val automaticallyStartPlayback = val automaticallyStartPlayback =
remember(content) { remember(content) {

View File

@ -33,6 +33,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.FeedError
@ -40,6 +41,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedState
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.screen.FeedViewModel import com.vitorpamplona.amethyst.ui.screen.FeedViewModel
import com.vitorpamplona.amethyst.ui.screen.SharedPreferencesViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.FeedPadding
@ -87,6 +89,14 @@ private fun GalleryFeedLoaded(
nav: INav, nav: INav,
) { ) {
val items by loaded.feed.collectAsStateWithLifecycle() val items by loaded.feed.collectAsStateWithLifecycle()
val sharedPreferencesViewModel: SharedPreferencesViewModel = viewModel()
sharedPreferencesViewModel.init()
var ratio = 1.0f
if (sharedPreferencesViewModel.sharedPrefs.modernGalleryStyle.value) {
ratio = 0.8f
}
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Fixed(3), columns = GridCells.Fixed(3),
@ -100,11 +110,12 @@ private fun GalleryFeedLoaded(
baseNote = item, baseNote = item,
modifier = modifier =
Modifier Modifier
.aspectRatio(1f) .aspectRatio(ratio)
.fillMaxSize() .fillMaxSize()
.animateItem(), .animateItem(),
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,
ratio = ratio,
) )
} }
} }

View File

@ -48,10 +48,12 @@ import androidx.core.os.LocaleListCompat
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.FeatureSetType
import com.vitorpamplona.amethyst.model.ProfileGalleryType
import com.vitorpamplona.amethyst.model.ThemeType import com.vitorpamplona.amethyst.model.ThemeType
import com.vitorpamplona.amethyst.model.parseBooleanType import com.vitorpamplona.amethyst.model.parseBooleanType
import com.vitorpamplona.amethyst.model.parseConnectivityType import com.vitorpamplona.amethyst.model.parseConnectivityType
import com.vitorpamplona.amethyst.model.parseFeatureSetType import com.vitorpamplona.amethyst.model.parseFeatureSetType
import com.vitorpamplona.amethyst.model.parseGalleryType
import com.vitorpamplona.amethyst.model.parseThemeType import com.vitorpamplona.amethyst.model.parseThemeType
import com.vitorpamplona.amethyst.ui.components.PushNotificationSettingsRow import com.vitorpamplona.amethyst.ui.components.PushNotificationSettingsRow
import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.INav
@ -187,6 +189,12 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) {
TitleExplainer(stringRes(FeatureSetType.PERFORMANCE.resourceId)), TitleExplainer(stringRes(FeatureSetType.PERFORMANCE.resourceId)),
) )
val galleryItems =
persistentListOf(
TitleExplainer(stringRes(ProfileGalleryType.CLASSIC.resourceId)),
TitleExplainer(stringRes(ProfileGalleryType.MODERN.resourceId)),
)
val showImagesIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyShowImages.screenCode val showImagesIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyShowImages.screenCode
val videoIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyStartPlayback.screenCode val videoIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyStartPlayback.screenCode
val linkIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyShowUrlPreview.screenCode val linkIndex = sharedPreferencesViewModel.sharedPrefs.automaticallyShowUrlPreview.screenCode
@ -204,6 +212,8 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) {
val featureSetIndex = val featureSetIndex =
sharedPreferencesViewModel.sharedPrefs.featureSet.screenCode sharedPreferencesViewModel.sharedPrefs.featureSet.screenCode
val galleryIndex =
sharedPreferencesViewModel.sharedPrefs.gallerySet.screenCode
Column( Column(
Modifier Modifier
@ -295,9 +305,19 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) {
) { ) {
sharedPreferencesViewModel.updateFeatureSetType(parseFeatureSetType(it)) sharedPreferencesViewModel.updateFeatureSetType(parseFeatureSetType(it))
} }
Spacer(modifier = HalfVertSpacer)
Spacer(modifier = HalfVertSpacer) Spacer(modifier = HalfVertSpacer)
SettingsRow(
R.string.gallery_style,
R.string.gallery_style_description,
galleryItems,
galleryIndex,
) {
sharedPreferencesViewModel.updateGallerySetType(parseGalleryType(it))
}
PushNotificationSettingsRow(sharedPreferencesViewModel) PushNotificationSettingsRow(sharedPreferencesViewModel)
} }
} }

View File

@ -634,6 +634,9 @@
<string name="ui_feature_set_type_simplified">Simplified</string> <string name="ui_feature_set_type_simplified">Simplified</string>
<string name="ui_feature_set_type_performance">Performance</string> <string name="ui_feature_set_type_performance">Performance</string>
<string name="gallery_type_classic">Classic</string>
<string name="gallery_type_modern">Modern</string>
<string name="system">System</string> <string name="system">System</string>
<string name="light">Light</string> <string name="light">Light</string>
<string name="dark">Dark</string> <string name="dark">Dark</string>
@ -650,6 +653,9 @@
<string name="ui_style">UI Mode</string> <string name="ui_style">UI Mode</string>
<string name="ui_style_description">Choose the post style</string> <string name="ui_style_description">Choose the post style</string>
<string name="gallery_style">Profile Gallery Style</string>
<string name="gallery_style_description">Choose the gallery style</string>
<string name="load_image">Load Image</string> <string name="load_image">Load Image</string>
<string name="spamming_users">Spammers</string> <string name="spamming_users">Spammers</string>