feat: implement title autofill based on URL (#707)

This commit is contained in:
Diego Beraldin 2024-04-21 09:18:56 +02:00 committed by GitHub
parent 8353ed0bc6
commit 3049de99d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 2 deletions

View File

@ -58,6 +58,7 @@ interface CreatePostMviModel :
data class ChangeBodyValue(val value: TextFieldValue) : Intent
data object Send : Intent
data object SaveDraft : Intent
data object AutoFillTitle : Intent
}
data class UiState(
@ -91,5 +92,6 @@ interface CreatePostMviModel :
data object Success : Effect
data class Failure(val message: String?) : Effect
data object DraftSaved : Effect
data object AutoFillFailed : Effect
}
}

View File

@ -1,6 +1,7 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.createpost
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
@ -51,6 +53,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -61,6 +64,7 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.toTypography
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
@ -205,11 +209,14 @@ class CreatePostScreen(
}
CreatePostMviModel.Effect.DraftSaved -> navigationCoordinator.popScreen()
CreatePostMviModel.Effect.AutoFillFailed -> {
snackbarHostState.showSnackbar(genericError)
}
}
}.launchIn(this)
}
LaunchedEffect(notificationCenter)
{
LaunchedEffect(notificationCenter) {
notificationCenter.subscribe(NotificationCenterEvent.SelectCommunity::class)
.onEach { evt ->
model.reduce(CreatePostMviModel.Intent.SetCommunity(evt.model))
@ -356,6 +363,29 @@ class CreatePostScreen(
textStyle = typography.titleMedium,
value = uiState.title,
singleLine = true,
trailingIcon = {
if (uiState.url.isNotBlank()) {
Text(
modifier = Modifier
.padding(horizontal = Spacing.s)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(CornerSize.m),
)
.padding(Spacing.xs)
.onClick(
onClick = rememberCallback {
model.reduce(CreatePostMviModel.Intent.AutoFillTitle)
},
),
text = "auto".uppercase(),
style = MaterialTheme.typography.labelSmall,
fontFamily = FontFamily.Default,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onPrimary,
)
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Ascii,
autoCorrect = true,

View File

@ -136,6 +136,7 @@ class CreatePostViewModel(
CreatePostMviModel.Intent.Send -> submit()
CreatePostMviModel.Intent.SaveDraft -> saveDraft()
CreatePostMviModel.Intent.AutoFillTitle -> autofillTitle()
}
}
@ -338,4 +339,19 @@ class CreatePostViewModel(
notificationCenter.send(NotificationCenterEvent.DraftDeleted)
}
}
private fun autofillTitle() {
val url = uiState.value.url.takeUnless { it.isBlank() } ?: return
screenModelScope.launch {
updateState { it.copy(loading = true) }
val metadata = siteRepository.getMetadata(url)
val suggestedTitle = metadata?.title.takeUnless { it.isNullOrBlank() }
updateState { it.copy(loading = false) }
if (suggestedTitle == null) {
emitEffect(CreatePostMviModel.Effect.AutoFillFailed)
} else {
updateState { it.copy(title = suggestedTitle) }
}
}
}
}