mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 07:48:44 +01:00
* chore: font reordering * chore: second swipe sensitivity * chore: update models * chore: update repositories * chore: update formatting bar * chore: add dialog * chore: update comment creation * chore: update post creation
This commit is contained in:
parent
c2ef07d4be
commit
7ca04ace88
@ -5,38 +5,38 @@ import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
enum class UiFontFamily {
|
||||
Default,
|
||||
TitilliumWeb,
|
||||
NotoSans,
|
||||
CharisSIL,
|
||||
Comfortaa,
|
||||
Poppins,
|
||||
Default,
|
||||
Comfortaa,
|
||||
}
|
||||
|
||||
fun Int.toUiFontFamily() = when (this) {
|
||||
7 -> UiFontFamily.Default
|
||||
6 -> UiFontFamily.TitilliumWeb
|
||||
5 -> UiFontFamily.Comfortaa
|
||||
4 -> UiFontFamily.CharisSIL
|
||||
0 -> UiFontFamily.Poppins
|
||||
3 -> UiFontFamily.NotoSans
|
||||
else -> UiFontFamily.Poppins
|
||||
4 -> UiFontFamily.CharisSIL
|
||||
5 -> UiFontFamily.Comfortaa
|
||||
6 -> UiFontFamily.TitilliumWeb
|
||||
else -> UiFontFamily.Default
|
||||
}
|
||||
|
||||
fun UiFontFamily.toInt() = when (this) {
|
||||
UiFontFamily.Poppins -> 0
|
||||
UiFontFamily.Comfortaa -> 5
|
||||
UiFontFamily.CharisSIL -> 4
|
||||
UiFontFamily.NotoSans -> 3
|
||||
UiFontFamily.CharisSIL -> 4
|
||||
UiFontFamily.Comfortaa -> 5
|
||||
UiFontFamily.TitilliumWeb -> 6
|
||||
UiFontFamily.Default -> 7
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UiFontFamily.toReadableName() = when (this) {
|
||||
UiFontFamily.Default -> stringResource(MR.strings.settings_font_family_default)
|
||||
UiFontFamily.Poppins -> "Poppins"
|
||||
UiFontFamily.Comfortaa -> "Comfortaa"
|
||||
UiFontFamily.CharisSIL -> "Charis SIL"
|
||||
UiFontFamily.NotoSans -> "Noto Sans"
|
||||
else -> "Titillium Web"
|
||||
UiFontFamily.CharisSIL -> "Charis SIL"
|
||||
UiFontFamily.Comfortaa -> "Comfortaa"
|
||||
UiFontFamily.TitilliumWeb -> "Titillium Web"
|
||||
UiFontFamily.Default -> stringResource(MR.strings.settings_font_family_default)
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import dev.icerock.moko.resources.compose.fontFamilyResource
|
||||
@Composable
|
||||
fun UiFontFamily.toTypography(): Typography {
|
||||
val fontFamily = when (this) {
|
||||
UiFontFamily.CharisSIL -> fontFamilyResource(MR.fonts.CharisSIL.regular)
|
||||
UiFontFamily.NotoSans -> fontFamilyResource(MR.fonts.NotoSans.regular)
|
||||
UiFontFamily.Comfortaa -> fontFamilyResource(MR.fonts.Comfortaa.regular)
|
||||
UiFontFamily.Poppins -> fontFamilyResource(MR.fonts.Poppins.regular)
|
||||
UiFontFamily.TitilliumWeb -> fontFamilyResource(MR.fonts.TitilliumWeb.regular)
|
||||
UiFontFamily.NotoSans -> fontFamilyResource(MR.fonts.NotoSans.regular)
|
||||
UiFontFamily.CharisSIL -> fontFamilyResource(MR.fonts.CharisSIL.regular)
|
||||
UiFontFamily.Poppins -> fontFamilyResource(MR.fonts.Poppins.regular)
|
||||
UiFontFamily.Comfortaa -> fontFamilyResource(MR.fonts.Comfortaa.regular)
|
||||
else -> FontFamily.Default
|
||||
}
|
||||
return Typography(
|
||||
|
@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
private const val SECOND_ACTION_THRESHOLD = 0.35f
|
||||
private const val SECOND_ACTION_THRESHOLD = 0.38f
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
@ -1,7 +1,13 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui
|
||||
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Code
|
||||
import androidx.compose.material.icons.filled.FormatBold
|
||||
@ -13,292 +19,390 @@ import androidx.compose.material.icons.filled.FormatStrikethrough
|
||||
import androidx.compose.material.icons.filled.Image
|
||||
import androidx.compose.material.icons.filled.InsertLink
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.fontFamilyResource
|
||||
|
||||
@Composable
|
||||
fun TextFormattingBar(
|
||||
textFieldValue: TextFieldValue,
|
||||
onTextFieldValueChanged: (TextFieldValue) -> Unit,
|
||||
onSelectImage: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onSelectImage: (() -> Unit)? = null,
|
||||
currentLanguageId: Int? = null,
|
||||
availableLanguages: List<LanguageModel> = emptyList(),
|
||||
onSelectLanguage: (() -> Unit)? = null,
|
||||
) {
|
||||
Row(
|
||||
val textPlaceholder = "text here"
|
||||
val urlPlaceholder = "URL"
|
||||
LazyRow(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("**")
|
||||
if (selection.length == 0) {
|
||||
append("text here")
|
||||
} else {
|
||||
// bold
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("**")
|
||||
if (selection.length == 0) {
|
||||
append(textPlaceholder)
|
||||
} else {
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
)
|
||||
)
|
||||
}
|
||||
append("**")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
append("**")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + 11)
|
||||
} else {
|
||||
TextRange(start = it.selection.start + 2, end = it.selection.end + 2)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatBold,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("*")
|
||||
if (selection.length == 0) {
|
||||
append("text here")
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + textPlaceholder.length + 2)
|
||||
} else {
|
||||
TextRange(
|
||||
start = it.selection.start + 2,
|
||||
end = it.selection.end + 2
|
||||
)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatBold,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// italic
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("*")
|
||||
if (selection.length == 0) {
|
||||
append(textPlaceholder)
|
||||
} else {
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
)
|
||||
)
|
||||
}
|
||||
append("*")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
append("*")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + 10)
|
||||
} else {
|
||||
TextRange(start = it.selection.start + 1, end = it.selection.end + 1)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatItalic,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("~~")
|
||||
if (selection.length == 0) {
|
||||
append("text here")
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||
} else {
|
||||
TextRange(
|
||||
start = it.selection.start + 1,
|
||||
end = it.selection.end + 1
|
||||
)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatItalic,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// strikethrough
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val selection = textFieldValue.selection
|
||||
val newValue = textFieldValue.let {
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("~~")
|
||||
if (selection.length == 0) {
|
||||
append(textPlaceholder)
|
||||
} else {
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
)
|
||||
)
|
||||
}
|
||||
append("~~")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
append("~~")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + 11)
|
||||
} else {
|
||||
TextRange(start = it.selection.start + 2, end = it.selection.end + 2)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatStrikethrough,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectImage()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.Image,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("[")
|
||||
if (selection.length == 0) {
|
||||
append("text here")
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + textPlaceholder.length + 2)
|
||||
} else {
|
||||
TextRange(
|
||||
start = it.selection.start + 2,
|
||||
end = it.selection.end + 2
|
||||
)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatStrikethrough,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// image
|
||||
if (onSelectImage != null) {
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
onSelectImage.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.Image,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// hyperlink
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("[")
|
||||
if (selection.length == 0) {
|
||||
append(textPlaceholder)
|
||||
} else {
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
)
|
||||
)
|
||||
}
|
||||
append("](")
|
||||
append(urlPlaceholder)
|
||||
append(")")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
append("](URL here)")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + 10)
|
||||
} else {
|
||||
TextRange(start = it.selection.start + 1, end = it.selection.end + 1)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.InsertLink,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("`")
|
||||
if (selection.length == 0) {
|
||||
append("text here")
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||
} else {
|
||||
TextRange(
|
||||
start = it.selection.start + 1,
|
||||
end = it.selection.end + 1
|
||||
)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.InsertLink,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// inline code
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("`")
|
||||
if (selection.length == 0) {
|
||||
append(textPlaceholder)
|
||||
} else {
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
)
|
||||
)
|
||||
}
|
||||
append("`")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.start,
|
||||
selection.end
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
}
|
||||
append("`")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||
} else {
|
||||
TextRange(
|
||||
start = it.selection.start + 1,
|
||||
end = it.selection.end + 1
|
||||
)
|
||||
)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
val newSelection = if (selection.length == 0) {
|
||||
TextRange(index = selection.start + 10)
|
||||
} else {
|
||||
TextRange(start = it.selection.start + 1, end = it.selection.end + 1)
|
||||
}
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.Code,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n> ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.Code,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// block quote
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n> ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 3)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 3)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatQuote,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n- ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatQuote,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// bulleted list
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n- ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 3)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 3)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatListBulleted,
|
||||
contentDescription = null,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n1. ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatListBulleted,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// numbered list
|
||||
item {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = {
|
||||
val newValue = textFieldValue.let {
|
||||
val selection = it.selection
|
||||
val newText = buildString {
|
||||
append(it.text.substring(0, selection.start))
|
||||
append("\n1. ")
|
||||
append(
|
||||
it.text.substring(
|
||||
selection.end,
|
||||
it.text.length
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 4)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
val newSelection = TextRange(index = selection.start + 4)
|
||||
it.copy(text = newText, selection = newSelection)
|
||||
}
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatListNumbered,
|
||||
contentDescription = null,
|
||||
)
|
||||
onTextFieldValueChanged(newValue)
|
||||
}),
|
||||
imageVector = Icons.Default.FormatListNumbered,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
// language selection
|
||||
if (onSelectLanguage != null) {
|
||||
item {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(IconSize.m)
|
||||
.border(
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
width = Dp.Hairline,
|
||||
shape = RoundedCornerShape(CornerSize.m)
|
||||
)
|
||||
.clickable(onClick = onSelectLanguage)
|
||||
.padding(Spacing.xxxs),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
val languageCode = availableLanguages.firstOrNull { l ->
|
||||
l.id == currentLanguageId
|
||||
}?.takeIf { l ->
|
||||
l.id > 0 // undetermied language
|
||||
}?.code ?: "λ"
|
||||
Text(
|
||||
text = languageCode,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontFamily = fontFamilyResource(MR.fonts.TitilliumWeb.regular),
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -97,7 +97,7 @@ class FontFamilyBottomSheet(
|
||||
UiFontFamily.Comfortaa -> fontFamilyResource(MR.fonts.Comfortaa.regular)
|
||||
UiFontFamily.Poppins -> fontFamilyResource(MR.fonts.Poppins.regular)
|
||||
UiFontFamily.TitilliumWeb -> fontFamilyResource(MR.fonts.TitilliumWeb.regular)
|
||||
else -> FontFamily.Default
|
||||
UiFontFamily.Default -> FontFamily.Default
|
||||
}
|
||||
Text(
|
||||
text = value.toReadableName(),
|
||||
|
@ -0,0 +1,112 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SelectLanguageDialog(
|
||||
currentLanguageId: Int? = null,
|
||||
languages: List<LanguageModel> = emptyList(),
|
||||
onSelect: ((Int?) -> Unit)? = null,
|
||||
onDismiss: (() -> Unit)? = null,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismiss?.invoke() },
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.surface)
|
||||
.padding(vertical = Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(MR.strings.settings_language),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(Spacing.xs))
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxHeight(0.6f)
|
||||
) {
|
||||
items(items = languages, key = { it.id }) { lang ->
|
||||
LanguageItem(
|
||||
name = lang.name,
|
||||
selected = (currentLanguageId ?: 0) == lang.id,
|
||||
onSelected = rememberCallback {
|
||||
onSelect?.invoke(lang.id)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(Spacing.xxs))
|
||||
Button(
|
||||
onClick = {
|
||||
onDismiss?.invoke()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.button_close))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguageItem(
|
||||
name: String,
|
||||
modifier: Modifier = Modifier,
|
||||
selected: Boolean = false,
|
||||
onSelected: (() -> Unit)? = null,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
onClick = {
|
||||
onSelected?.invoke()
|
||||
},
|
||||
).padding(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
if (selected) {
|
||||
RadioButton(
|
||||
selected = true,
|
||||
onClick = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ data class CommentModel(
|
||||
val visible: Boolean = true,
|
||||
@Transient
|
||||
val loadMoreButtonVisible: Boolean = false,
|
||||
val languageId: Int = 0,
|
||||
) : JavaSerializable {
|
||||
val depth: Int get() = (path.split(".").size - 2).coerceAtLeast(0)
|
||||
val parentId: String?
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data
|
||||
|
||||
data class LanguageModel(
|
||||
val id: Int,
|
||||
val name: String = "",
|
||||
val code: String = "",
|
||||
)
|
@ -27,6 +27,7 @@ data class PostModel(
|
||||
val featuredCommunity: Boolean = false,
|
||||
val removed: Boolean = false,
|
||||
val locked: Boolean = false,
|
||||
val languageId: Int = 0,
|
||||
) : JavaSerializable
|
||||
|
||||
val PostModel.imageUrl: String
|
||||
|
@ -48,7 +48,7 @@ interface CommentRepository {
|
||||
suspend fun downVote(
|
||||
comment: CommentModel,
|
||||
auth: String,
|
||||
downVoted: Boolean
|
||||
downVoted: Boolean,
|
||||
): Result<Response<CommentResponse>>
|
||||
|
||||
fun asSaved(comment: CommentModel, saved: Boolean): CommentModel
|
||||
@ -56,19 +56,21 @@ interface CommentRepository {
|
||||
suspend fun save(
|
||||
comment: CommentModel,
|
||||
auth: String,
|
||||
saved: Boolean
|
||||
saved: Boolean,
|
||||
): Result<Response<CommentResponse>>
|
||||
|
||||
suspend fun create(
|
||||
postId: Int,
|
||||
parentId: Int?,
|
||||
text: String,
|
||||
languageId: Int? = null,
|
||||
auth: String,
|
||||
)
|
||||
|
||||
suspend fun edit(
|
||||
commentId: Int,
|
||||
text: String,
|
||||
languageId: Int? = null,
|
||||
auth: String,
|
||||
)
|
||||
|
||||
|
@ -214,12 +214,14 @@ internal class DefaultCommentRepository(
|
||||
postId: Int,
|
||||
parentId: Int?,
|
||||
text: String,
|
||||
languageId: Int?,
|
||||
auth: String,
|
||||
) {
|
||||
val data = CreateCommentForm(
|
||||
content = text,
|
||||
postId = postId,
|
||||
parentId = parentId,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
|
||||
@ -228,11 +230,13 @@ internal class DefaultCommentRepository(
|
||||
override suspend fun edit(
|
||||
commentId: Int,
|
||||
text: String,
|
||||
languageId: Int?,
|
||||
auth: String,
|
||||
) {
|
||||
val data = EditCommentForm(
|
||||
content = text,
|
||||
commentId = commentId,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
|
||||
|
@ -169,6 +169,7 @@ internal class DefaultPostRepository(
|
||||
body: String?,
|
||||
url: String?,
|
||||
nsfw: Boolean,
|
||||
languageId: Int?,
|
||||
auth: String,
|
||||
) {
|
||||
val data = CreatePostForm(
|
||||
@ -177,6 +178,7 @@ internal class DefaultPostRepository(
|
||||
body = body,
|
||||
url = url,
|
||||
nsfw = nsfw,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.create(
|
||||
@ -191,6 +193,7 @@ internal class DefaultPostRepository(
|
||||
body: String?,
|
||||
url: String?,
|
||||
nsfw: Boolean,
|
||||
languageId: Int?,
|
||||
auth: String,
|
||||
) {
|
||||
val data = EditPostForm(
|
||||
@ -199,6 +202,7 @@ internal class DefaultPostRepository(
|
||||
body = body,
|
||||
url = url,
|
||||
nsfw = nsfw,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.edit(
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockSiteForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
|
||||
@ -57,4 +58,10 @@ internal class DefaultSiteRepository(
|
||||
)
|
||||
response.body()?.metadata?.toModel()
|
||||
}.getOrNull()
|
||||
|
||||
override suspend fun getLanguages(auth: String?): List<LanguageModel> = runCatching {
|
||||
val response = services.site.get(auth = auth)
|
||||
val dto = response.body()
|
||||
dto?.allLanguages?.map { it.toModel() }.orEmpty()
|
||||
}.getOrElse { emptyList() }
|
||||
}
|
@ -57,6 +57,7 @@ interface PostRepository {
|
||||
body: String?,
|
||||
url: String? = null,
|
||||
nsfw: Boolean = false,
|
||||
languageId: Int? = null,
|
||||
auth: String,
|
||||
)
|
||||
|
||||
@ -66,6 +67,7 @@ interface PostRepository {
|
||||
body: String?,
|
||||
url: String? = null,
|
||||
nsfw: Boolean = false,
|
||||
languageId: Int? = null,
|
||||
auth: String,
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
|
||||
@ -11,4 +12,6 @@ interface SiteRepository {
|
||||
suspend fun block(id: Int, blocked: Boolean, auth: String? = null): Result<Unit>
|
||||
|
||||
suspend fun getMetadata(url: String): MetadataModel?
|
||||
|
||||
suspend fun getLanguages(auth: String?): List<LanguageModel>
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommentSortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommentView
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.Community
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommunityView
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.Language
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.All
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Local
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Subscribed
|
||||
@ -48,6 +49,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SubscribedType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentReportModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ModlogItem
|
||||
@ -125,29 +127,16 @@ internal fun PersonAggregates.toModel() = UserScoreModel(
|
||||
commentScore = commentScore ?: 0,
|
||||
)
|
||||
|
||||
internal fun PostView.toModel() = PostModel(
|
||||
id = post.id,
|
||||
originalUrl = post.apId,
|
||||
title = post.name,
|
||||
text = post.body.orEmpty(),
|
||||
internal fun PostView.toModel() = post.toModel().copy(
|
||||
score = counts.score,
|
||||
upvotes = counts.upvotes,
|
||||
downvotes = counts.downvotes,
|
||||
comments = counts.comments,
|
||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
||||
url = post.url,
|
||||
community = community.toModel(),
|
||||
creator = creator.toModel(),
|
||||
saved = saved,
|
||||
myVote = myVote ?: 0,
|
||||
publishDate = post.published,
|
||||
updateDate = post.updated,
|
||||
nsfw = post.nsfw,
|
||||
embedVideoUrl = post.embedVideoUrl,
|
||||
read = read,
|
||||
featuredCommunity = post.featuredCommunity,
|
||||
removed = post.removed,
|
||||
locked = post.locked,
|
||||
)
|
||||
|
||||
internal fun Post.toModel() = PostModel(
|
||||
@ -163,11 +152,10 @@ internal fun Post.toModel() = PostModel(
|
||||
featuredCommunity = featuredCommunity,
|
||||
removed = removed,
|
||||
locked = locked,
|
||||
languageId = languageId,
|
||||
)
|
||||
|
||||
internal fun CommentView.toModel() = CommentModel(
|
||||
id = comment.id,
|
||||
text = comment.content,
|
||||
internal fun CommentView.toModel() = comment.toModel().copy(
|
||||
community = community.toModel(),
|
||||
creator = creator.toModel(),
|
||||
score = counts.score,
|
||||
@ -175,13 +163,7 @@ internal fun CommentView.toModel() = CommentModel(
|
||||
downvotes = counts.downvotes,
|
||||
saved = saved,
|
||||
myVote = myVote ?: 0,
|
||||
publishDate = comment.published,
|
||||
updateDate = comment.updated,
|
||||
postId = comment.postId,
|
||||
comments = counts.childCount,
|
||||
path = comment.path,
|
||||
distinguished = comment.distinguished,
|
||||
removed = comment.removed,
|
||||
)
|
||||
|
||||
internal fun Comment.toModel() = CommentModel(
|
||||
@ -193,6 +175,7 @@ internal fun Comment.toModel() = CommentModel(
|
||||
path = path,
|
||||
distinguished = distinguished,
|
||||
removed = removed,
|
||||
languageId = languageId,
|
||||
)
|
||||
|
||||
internal fun Community.toModel() = CommunityModel(
|
||||
@ -222,37 +205,17 @@ internal fun CommunityView.toModel() = community.toModel().copy(
|
||||
internal fun PersonMentionView.toModel() = PersonMentionModel(
|
||||
id = personMention.id,
|
||||
read = personMention.read,
|
||||
post = PostModel(
|
||||
id = post.id,
|
||||
originalUrl = post.apId,
|
||||
title = post.name,
|
||||
text = post.body.orEmpty(),
|
||||
post = post.toModel().copy(
|
||||
score = counts.score,
|
||||
upvotes = counts.upvotes,
|
||||
downvotes = counts.downvotes,
|
||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
||||
url = post.url,
|
||||
community = community.toModel(),
|
||||
creator = creator.toModel(),
|
||||
saved = saved,
|
||||
myVote = myVote ?: 0,
|
||||
publishDate = post.published,
|
||||
updateDate = post.updated,
|
||||
nsfw = post.nsfw,
|
||||
embedVideoUrl = post.embedVideoUrl,
|
||||
featuredCommunity = post.featuredCommunity,
|
||||
removed = post.removed,
|
||||
locked = post.locked,
|
||||
),
|
||||
comment = CommentModel(
|
||||
id = comment.id,
|
||||
postId = comment.postId,
|
||||
text = comment.content,
|
||||
comment = comment.toModel().copy(
|
||||
community = community.toModel(),
|
||||
publishDate = comment.published,
|
||||
updateDate = comment.updated,
|
||||
distinguished = comment.distinguished,
|
||||
removed = comment.removed,
|
||||
),
|
||||
creator = creator.toModel(),
|
||||
community = community.toModel(),
|
||||
@ -267,37 +230,17 @@ internal fun PersonMentionView.toModel() = PersonMentionModel(
|
||||
internal fun CommentReplyView.toModel() = PersonMentionModel(
|
||||
id = commentReply.id,
|
||||
read = commentReply.read,
|
||||
post = PostModel(
|
||||
id = post.id,
|
||||
originalUrl = post.apId,
|
||||
title = post.name,
|
||||
text = post.body.orEmpty(),
|
||||
post = post.toModel().copy(
|
||||
score = counts.score,
|
||||
upvotes = counts.upvotes,
|
||||
downvotes = counts.downvotes,
|
||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
||||
url = post.url,
|
||||
community = community.toModel(),
|
||||
creator = UserModel(id = post.creatorId),
|
||||
creator = creator.toModel(),
|
||||
saved = saved,
|
||||
myVote = myVote ?: 0,
|
||||
publishDate = post.published,
|
||||
updateDate = post.updated,
|
||||
nsfw = post.nsfw,
|
||||
embedVideoUrl = post.embedVideoUrl,
|
||||
featuredCommunity = post.featuredCommunity,
|
||||
removed = post.removed,
|
||||
locked = post.locked,
|
||||
),
|
||||
comment = CommentModel(
|
||||
id = comment.id,
|
||||
postId = comment.postId,
|
||||
text = comment.content,
|
||||
comment = comment.toModel().copy(
|
||||
community = community.toModel(),
|
||||
publishDate = comment.published,
|
||||
updateDate = comment.updated,
|
||||
distinguished = comment.distinguished,
|
||||
removed = comment.removed,
|
||||
),
|
||||
creator = creator.toModel(),
|
||||
community = community.toModel(),
|
||||
@ -436,3 +379,9 @@ internal fun ModTransferCommunityView.toDto() = ModlogItem.ModTransferCommunity(
|
||||
moderator = moderator?.toModel(),
|
||||
user = moddedPerson.toModel(),
|
||||
)
|
||||
|
||||
internal fun Language.toModel() = LanguageModel(
|
||||
id = id,
|
||||
code = code,
|
||||
name = name,
|
||||
)
|
||||
|
@ -6,6 +6,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CreatePostSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
@ -30,6 +31,8 @@ interface CreateCommentMviModel :
|
||||
}
|
||||
}
|
||||
|
||||
data class ChangeLanguage(val value: Int?) : Intent
|
||||
|
||||
data class Send(val text: String) : Intent
|
||||
}
|
||||
|
||||
@ -43,6 +46,8 @@ interface CreateCommentMviModel :
|
||||
val autoLoadImages: Boolean = true,
|
||||
val currentInstance: String = "",
|
||||
val currentUser: String = "",
|
||||
val currentLanguageId: Int? = null,
|
||||
val availableLanguages: List<LanguageModel> = emptyList(),
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
|
@ -63,11 +63,13 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCardBody
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.TextFormattingBar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.RawContentDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SelectLanguageDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.gallery.getGalleryHelper
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
@ -116,8 +118,12 @@ class CreateCommentScreen(
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
||||
val typography = contentFontFamily.toTypography()
|
||||
var selectLanguageDialogOpen by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
if (editedComment != null) {
|
||||
model.reduce(CreateCommentMviModel.Intent.ChangeLanguage(editedComment.languageId))
|
||||
}
|
||||
model.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
is CreateCommentMviModel.Effect.Failure -> {
|
||||
@ -248,7 +254,12 @@ class CreateCommentScreen(
|
||||
},
|
||||
onSelectImage = {
|
||||
openImagePicker = true
|
||||
}
|
||||
},
|
||||
currentLanguageId = uiState.currentLanguageId,
|
||||
availableLanguages = uiState.availableLanguages,
|
||||
onSelectLanguage = {
|
||||
selectLanguageDialogOpen = true
|
||||
},
|
||||
)
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
@ -426,5 +437,19 @@ class CreateCommentScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectLanguageDialogOpen) {
|
||||
SelectLanguageDialog(
|
||||
languages = uiState.availableLanguages,
|
||||
currentLanguageId = uiState.currentLanguageId,
|
||||
onSelect = rememberCallbackArgs { langId ->
|
||||
model.reduce(CreateCommentMviModel.Intent.ChangeLanguage(langId))
|
||||
selectLanguageDialogOpen = false
|
||||
},
|
||||
onDismiss = rememberCallback {
|
||||
selectLanguageDialogOpen = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,11 +42,13 @@ class CreateCommentViewModel(
|
||||
if (uiState.value.currentUser.isEmpty()) {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
val currentUser = siteRepository.getCurrentUser(auth)
|
||||
val languages = siteRepository.getLanguages(auth)
|
||||
if (currentUser != null) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
currentUser = currentUser.name,
|
||||
currentInstance = currentUser.host,
|
||||
availableLanguages = languages,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -65,11 +67,18 @@ class CreateCommentViewModel(
|
||||
|
||||
override fun reduce(intent: CreateCommentMviModel.Intent) {
|
||||
when (intent) {
|
||||
is CreateCommentMviModel.Intent.ChangeSection -> mvi.updateState {
|
||||
it.copy(section = intent.value)
|
||||
is CreateCommentMviModel.Intent.ChangeSection -> {
|
||||
mvi.updateState { it.copy(section = intent.value) }
|
||||
}
|
||||
|
||||
is CreateCommentMviModel.Intent.ImageSelected -> {
|
||||
loadImageAndAppendUrlInBody(intent.value)
|
||||
}
|
||||
|
||||
is CreateCommentMviModel.Intent.ChangeLanguage -> {
|
||||
mvi.updateState { it.copy(currentLanguageId = intent.value) }
|
||||
}
|
||||
|
||||
is CreateCommentMviModel.Intent.ImageSelected -> loadImageAndAppendUrlInBody(intent.value)
|
||||
is CreateCommentMviModel.Intent.Send -> submit(intent.text)
|
||||
}
|
||||
}
|
||||
@ -85,6 +94,7 @@ class CreateCommentViewModel(
|
||||
)
|
||||
}
|
||||
var valid = true
|
||||
val languageId = uiState.value.currentLanguageId
|
||||
if (text.isEmpty()) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
@ -106,12 +116,14 @@ class CreateCommentViewModel(
|
||||
postId = postId,
|
||||
parentId = parentId,
|
||||
text = text,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
} else if (editedCommentId != null) {
|
||||
commentRepository.edit(
|
||||
commentId = editedCommentId,
|
||||
text = text,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CreatePostSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
@ -50,6 +51,8 @@ interface CreatePostMviModel :
|
||||
}
|
||||
|
||||
data class ChangeSection(val value: CreatePostSection) : Intent
|
||||
|
||||
data class ChangeLanguage(val value: Int?) : Intent
|
||||
data class Send(val body: String) : Intent
|
||||
}
|
||||
|
||||
@ -71,6 +74,8 @@ interface CreatePostMviModel :
|
||||
val autoLoadImages: Boolean = true,
|
||||
val currentInstance: String = "",
|
||||
val currentUser: String = "",
|
||||
val currentLanguageId: Int? = null,
|
||||
val availableLanguages: List<LanguageModel> = emptyList(),
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
|
@ -66,6 +66,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CreatePostSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.TextFormattingBar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SelectLanguageDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
@ -141,11 +142,15 @@ class CreatePostScreen(
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
||||
val typography = contentFontFamily.toTypography()
|
||||
var selectLanguageDialogOpen by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
val referencePost = editedPost ?: crossPost
|
||||
model.reduce(CreatePostMviModel.Intent.SetTitle(referencePost?.title.orEmpty()))
|
||||
model.reduce(CreatePostMviModel.Intent.SetUrl(referencePost?.url.orEmpty()))
|
||||
if (editedPost != null) {
|
||||
model.reduce(CreatePostMviModel.Intent.ChangeLanguage(editedPost.languageId))
|
||||
}
|
||||
when {
|
||||
communityId != null -> model.reduce(
|
||||
CreatePostMviModel.Intent.SetCommunity(CommunityModel(id = communityId))
|
||||
@ -439,7 +444,12 @@ class CreatePostScreen(
|
||||
},
|
||||
onSelectImage = {
|
||||
openImagePickerInBody = true
|
||||
}
|
||||
},
|
||||
currentLanguageId = uiState.currentLanguageId,
|
||||
availableLanguages = uiState.availableLanguages,
|
||||
onSelectLanguage = {
|
||||
selectLanguageDialogOpen = true
|
||||
},
|
||||
)
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
@ -518,6 +528,20 @@ class CreatePostScreen(
|
||||
}
|
||||
}
|
||||
|
||||
if (selectLanguageDialogOpen) {
|
||||
SelectLanguageDialog(
|
||||
languages = uiState.availableLanguages,
|
||||
currentLanguageId = uiState.currentLanguageId,
|
||||
onSelect = rememberCallbackArgs { langId ->
|
||||
model.reduce(CreatePostMviModel.Intent.ChangeLanguage(langId))
|
||||
selectLanguageDialogOpen = false
|
||||
},
|
||||
onDismiss = rememberCallback {
|
||||
selectLanguageDialogOpen = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
|
@ -47,11 +47,13 @@ class CreatePostViewModel(
|
||||
if (uiState.value.currentUser.isEmpty()) {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
val currentUser = siteRepository.getCurrentUser(auth)
|
||||
val languages = siteRepository.getLanguages(auth)
|
||||
if (currentUser != null) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
currentUser = currentUser.name,
|
||||
currentInstance = currentUser.host,
|
||||
availableLanguages = languages,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -108,6 +110,10 @@ class CreatePostViewModel(
|
||||
it.copy(section = intent.value)
|
||||
}
|
||||
|
||||
is CreatePostMviModel.Intent.ChangeLanguage -> mvi.updateState {
|
||||
it.copy(currentLanguageId = intent.value)
|
||||
}
|
||||
|
||||
is CreatePostMviModel.Intent.Send -> submit(intent.body)
|
||||
}
|
||||
}
|
||||
@ -165,6 +171,7 @@ class CreatePostViewModel(
|
||||
val title = uiState.value.title
|
||||
val url = uiState.value.url.takeIf { it.isNotEmpty() }?.trim()
|
||||
val nsfw = uiState.value.nsfw
|
||||
val languageId = uiState.value.currentLanguageId
|
||||
var valid = true
|
||||
if (title.isEmpty()) {
|
||||
mvi.updateState {
|
||||
@ -215,6 +222,7 @@ class CreatePostViewModel(
|
||||
body = body,
|
||||
url = url,
|
||||
nsfw = nsfw,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
@ -226,6 +234,7 @@ class CreatePostViewModel(
|
||||
body = body,
|
||||
url = url,
|
||||
nsfw = nsfw,
|
||||
languageId = languageId,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user