* 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
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
|
|
||||||
enum class UiFontFamily {
|
enum class UiFontFamily {
|
||||||
|
Default,
|
||||||
TitilliumWeb,
|
TitilliumWeb,
|
||||||
NotoSans,
|
NotoSans,
|
||||||
CharisSIL,
|
CharisSIL,
|
||||||
Comfortaa,
|
|
||||||
Poppins,
|
Poppins,
|
||||||
Default,
|
Comfortaa,
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Int.toUiFontFamily() = when (this) {
|
fun Int.toUiFontFamily() = when (this) {
|
||||||
7 -> UiFontFamily.Default
|
0 -> UiFontFamily.Poppins
|
||||||
6 -> UiFontFamily.TitilliumWeb
|
|
||||||
5 -> UiFontFamily.Comfortaa
|
|
||||||
4 -> UiFontFamily.CharisSIL
|
|
||||||
3 -> UiFontFamily.NotoSans
|
3 -> UiFontFamily.NotoSans
|
||||||
else -> UiFontFamily.Poppins
|
4 -> UiFontFamily.CharisSIL
|
||||||
|
5 -> UiFontFamily.Comfortaa
|
||||||
|
6 -> UiFontFamily.TitilliumWeb
|
||||||
|
else -> UiFontFamily.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
fun UiFontFamily.toInt() = when (this) {
|
fun UiFontFamily.toInt() = when (this) {
|
||||||
UiFontFamily.Poppins -> 0
|
UiFontFamily.Poppins -> 0
|
||||||
UiFontFamily.Comfortaa -> 5
|
|
||||||
UiFontFamily.CharisSIL -> 4
|
|
||||||
UiFontFamily.NotoSans -> 3
|
UiFontFamily.NotoSans -> 3
|
||||||
|
UiFontFamily.CharisSIL -> 4
|
||||||
|
UiFontFamily.Comfortaa -> 5
|
||||||
UiFontFamily.TitilliumWeb -> 6
|
UiFontFamily.TitilliumWeb -> 6
|
||||||
UiFontFamily.Default -> 7
|
UiFontFamily.Default -> 7
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UiFontFamily.toReadableName() = when (this) {
|
fun UiFontFamily.toReadableName() = when (this) {
|
||||||
UiFontFamily.Default -> stringResource(MR.strings.settings_font_family_default)
|
|
||||||
UiFontFamily.Poppins -> "Poppins"
|
UiFontFamily.Poppins -> "Poppins"
|
||||||
UiFontFamily.Comfortaa -> "Comfortaa"
|
|
||||||
UiFontFamily.CharisSIL -> "Charis SIL"
|
|
||||||
UiFontFamily.NotoSans -> "Noto Sans"
|
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
|
@Composable
|
||||||
fun UiFontFamily.toTypography(): Typography {
|
fun UiFontFamily.toTypography(): Typography {
|
||||||
val fontFamily = when (this) {
|
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.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
|
else -> FontFamily.Default
|
||||||
}
|
}
|
||||||
return Typography(
|
return Typography(
|
||||||
|
@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
private const val SECOND_ACTION_THRESHOLD = 0.35f
|
private const val SECOND_ACTION_THRESHOLD = 0.38f
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui
|
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.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.Icons
|
||||||
import androidx.compose.material.icons.filled.Code
|
import androidx.compose.material.icons.filled.Code
|
||||||
import androidx.compose.material.icons.filled.FormatBold
|
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.Image
|
||||||
import androidx.compose.material.icons.filled.InsertLink
|
import androidx.compose.material.icons.filled.InsertLink
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.TextRange
|
import androidx.compose.ui.text.TextRange
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
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.appearance.theme.Spacing
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
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.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
|
@Composable
|
||||||
fun TextFormattingBar(
|
fun TextFormattingBar(
|
||||||
textFieldValue: TextFieldValue,
|
textFieldValue: TextFieldValue,
|
||||||
onTextFieldValueChanged: (TextFieldValue) -> Unit,
|
onTextFieldValueChanged: (TextFieldValue) -> Unit,
|
||||||
onSelectImage: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
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,
|
modifier = modifier,
|
||||||
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
||||||
) {
|
) {
|
||||||
Icon(
|
// bold
|
||||||
modifier = Modifier.onClick(
|
item {
|
||||||
onClick = {
|
Icon(
|
||||||
val selection = textFieldValue.selection
|
modifier = Modifier.onClick(
|
||||||
val newValue = textFieldValue.let {
|
onClick = {
|
||||||
val newText = buildString {
|
val selection = textFieldValue.selection
|
||||||
append(it.text.substring(0, selection.start))
|
val newValue = textFieldValue.let {
|
||||||
append("**")
|
val newText = buildString {
|
||||||
if (selection.length == 0) {
|
append(it.text.substring(0, selection.start))
|
||||||
append("text here")
|
append("**")
|
||||||
} else {
|
if (selection.length == 0) {
|
||||||
|
append(textPlaceholder)
|
||||||
|
} else {
|
||||||
|
append(
|
||||||
|
it.text.substring(
|
||||||
|
selection.start,
|
||||||
|
selection.end
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
append("**")
|
||||||
append(
|
append(
|
||||||
it.text.substring(
|
it.text.substring(
|
||||||
selection.start,
|
selection.end,
|
||||||
selection.end
|
it.text.length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
append("**")
|
val newSelection = if (selection.length == 0) {
|
||||||
append(
|
TextRange(index = selection.start + textPlaceholder.length + 2)
|
||||||
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")
|
|
||||||
} else {
|
} 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(
|
append(
|
||||||
it.text.substring(
|
it.text.substring(
|
||||||
selection.start,
|
selection.end,
|
||||||
selection.end
|
it.text.length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
append("*")
|
val newSelection = if (selection.length == 0) {
|
||||||
append(
|
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||||
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")
|
|
||||||
} else {
|
} 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(
|
append(
|
||||||
it.text.substring(
|
it.text.substring(
|
||||||
selection.start,
|
selection.end,
|
||||||
selection.end
|
it.text.length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
append("~~")
|
val newSelection = if (selection.length == 0) {
|
||||||
append(
|
TextRange(index = selection.start + textPlaceholder.length + 2)
|
||||||
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")
|
|
||||||
} else {
|
} 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(
|
append(
|
||||||
it.text.substring(
|
it.text.substring(
|
||||||
selection.start,
|
selection.end,
|
||||||
selection.end
|
it.text.length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
append("](URL here)")
|
val newSelection = if (selection.length == 0) {
|
||||||
append(
|
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||||
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")
|
|
||||||
} else {
|
} 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(
|
append(
|
||||||
it.text.substring(
|
it.text.substring(
|
||||||
selection.start,
|
selection.end,
|
||||||
selection.end
|
it.text.length
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
append("`")
|
val newSelection = if (selection.length == 0) {
|
||||||
append(
|
TextRange(index = selection.start + textPlaceholder.length + 1)
|
||||||
it.text.substring(
|
} else {
|
||||||
selection.end,
|
TextRange(
|
||||||
it.text.length
|
start = it.selection.start + 1,
|
||||||
|
end = it.selection.end + 1
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
it.copy(text = newText, selection = newSelection)
|
||||||
}
|
}
|
||||||
val newSelection = if (selection.length == 0) {
|
onTextFieldValueChanged(newValue)
|
||||||
TextRange(index = selection.start + 10)
|
}),
|
||||||
} else {
|
imageVector = Icons.Default.Code,
|
||||||
TextRange(start = it.selection.start + 1, end = it.selection.end + 1)
|
contentDescription = null,
|
||||||
}
|
)
|
||||||
it.copy(text = newText, selection = newSelection)
|
}
|
||||||
}
|
|
||||||
onTextFieldValueChanged(newValue)
|
// block quote
|
||||||
}),
|
item {
|
||||||
imageVector = Icons.Default.Code,
|
Icon(
|
||||||
contentDescription = null,
|
modifier = Modifier.onClick(
|
||||||
)
|
onClick = {
|
||||||
Icon(
|
val newValue = textFieldValue.let {
|
||||||
modifier = Modifier.onClick(
|
val selection = it.selection
|
||||||
onClick = {
|
val newText = buildString {
|
||||||
val newValue = textFieldValue.let {
|
append(it.text.substring(0, selection.start))
|
||||||
val selection = it.selection
|
append("\n> ")
|
||||||
val newText = buildString {
|
append(
|
||||||
append(it.text.substring(0, selection.start))
|
it.text.substring(
|
||||||
append("\n> ")
|
selection.end,
|
||||||
append(
|
it.text.length
|
||||||
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)
|
onTextFieldValueChanged(newValue)
|
||||||
it.copy(text = newText, selection = newSelection)
|
}),
|
||||||
}
|
imageVector = Icons.Default.FormatQuote,
|
||||||
onTextFieldValueChanged(newValue)
|
contentDescription = null,
|
||||||
}),
|
)
|
||||||
imageVector = Icons.Default.FormatQuote,
|
}
|
||||||
contentDescription = null,
|
|
||||||
)
|
// bulleted list
|
||||||
Icon(
|
item {
|
||||||
modifier = Modifier.onClick(
|
Icon(
|
||||||
onClick = {
|
modifier = Modifier.onClick(
|
||||||
val newValue = textFieldValue.let {
|
onClick = {
|
||||||
val selection = it.selection
|
val newValue = textFieldValue.let {
|
||||||
val newText = buildString {
|
val selection = it.selection
|
||||||
append(it.text.substring(0, selection.start))
|
val newText = buildString {
|
||||||
append("\n- ")
|
append(it.text.substring(0, selection.start))
|
||||||
append(
|
append("\n- ")
|
||||||
it.text.substring(
|
append(
|
||||||
selection.end,
|
it.text.substring(
|
||||||
it.text.length
|
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)
|
onTextFieldValueChanged(newValue)
|
||||||
it.copy(text = newText, selection = newSelection)
|
}),
|
||||||
}
|
imageVector = Icons.Default.FormatListBulleted,
|
||||||
onTextFieldValueChanged(newValue)
|
contentDescription = null,
|
||||||
}),
|
)
|
||||||
imageVector = Icons.Default.FormatListBulleted,
|
}
|
||||||
contentDescription = null,
|
|
||||||
)
|
// numbered list
|
||||||
Icon(
|
item {
|
||||||
modifier = Modifier.onClick(
|
Icon(
|
||||||
onClick = {
|
modifier = Modifier.onClick(
|
||||||
val newValue = textFieldValue.let {
|
onClick = {
|
||||||
val selection = it.selection
|
val newValue = textFieldValue.let {
|
||||||
val newText = buildString {
|
val selection = it.selection
|
||||||
append(it.text.substring(0, selection.start))
|
val newText = buildString {
|
||||||
append("\n1. ")
|
append(it.text.substring(0, selection.start))
|
||||||
append(
|
append("\n1. ")
|
||||||
it.text.substring(
|
append(
|
||||||
selection.end,
|
it.text.substring(
|
||||||
it.text.length
|
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)
|
onTextFieldValueChanged(newValue)
|
||||||
it.copy(text = newText, selection = newSelection)
|
}),
|
||||||
}
|
imageVector = Icons.Default.FormatListNumbered,
|
||||||
onTextFieldValueChanged(newValue)
|
contentDescription = null,
|
||||||
}),
|
)
|
||||||
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.Comfortaa -> fontFamilyResource(MR.fonts.Comfortaa.regular)
|
||||||
UiFontFamily.Poppins -> fontFamilyResource(MR.fonts.Poppins.regular)
|
UiFontFamily.Poppins -> fontFamilyResource(MR.fonts.Poppins.regular)
|
||||||
UiFontFamily.TitilliumWeb -> fontFamilyResource(MR.fonts.TitilliumWeb.regular)
|
UiFontFamily.TitilliumWeb -> fontFamilyResource(MR.fonts.TitilliumWeb.regular)
|
||||||
else -> FontFamily.Default
|
UiFontFamily.Default -> FontFamily.Default
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = value.toReadableName(),
|
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,
|
val visible: Boolean = true,
|
||||||
@Transient
|
@Transient
|
||||||
val loadMoreButtonVisible: Boolean = false,
|
val loadMoreButtonVisible: Boolean = false,
|
||||||
|
val languageId: Int = 0,
|
||||||
) : JavaSerializable {
|
) : JavaSerializable {
|
||||||
val depth: Int get() = (path.split(".").size - 2).coerceAtLeast(0)
|
val depth: Int get() = (path.split(".").size - 2).coerceAtLeast(0)
|
||||||
val parentId: String?
|
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 featuredCommunity: Boolean = false,
|
||||||
val removed: Boolean = false,
|
val removed: Boolean = false,
|
||||||
val locked: Boolean = false,
|
val locked: Boolean = false,
|
||||||
|
val languageId: Int = 0,
|
||||||
) : JavaSerializable
|
) : JavaSerializable
|
||||||
|
|
||||||
val PostModel.imageUrl: String
|
val PostModel.imageUrl: String
|
||||||
|
@ -48,7 +48,7 @@ interface CommentRepository {
|
|||||||
suspend fun downVote(
|
suspend fun downVote(
|
||||||
comment: CommentModel,
|
comment: CommentModel,
|
||||||
auth: String,
|
auth: String,
|
||||||
downVoted: Boolean
|
downVoted: Boolean,
|
||||||
): Result<Response<CommentResponse>>
|
): Result<Response<CommentResponse>>
|
||||||
|
|
||||||
fun asSaved(comment: CommentModel, saved: Boolean): CommentModel
|
fun asSaved(comment: CommentModel, saved: Boolean): CommentModel
|
||||||
@ -56,19 +56,21 @@ interface CommentRepository {
|
|||||||
suspend fun save(
|
suspend fun save(
|
||||||
comment: CommentModel,
|
comment: CommentModel,
|
||||||
auth: String,
|
auth: String,
|
||||||
saved: Boolean
|
saved: Boolean,
|
||||||
): Result<Response<CommentResponse>>
|
): Result<Response<CommentResponse>>
|
||||||
|
|
||||||
suspend fun create(
|
suspend fun create(
|
||||||
postId: Int,
|
postId: Int,
|
||||||
parentId: Int?,
|
parentId: Int?,
|
||||||
text: String,
|
text: String,
|
||||||
|
languageId: Int? = null,
|
||||||
auth: String,
|
auth: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun edit(
|
suspend fun edit(
|
||||||
commentId: Int,
|
commentId: Int,
|
||||||
text: String,
|
text: String,
|
||||||
|
languageId: Int? = null,
|
||||||
auth: String,
|
auth: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -214,12 +214,14 @@ internal class DefaultCommentRepository(
|
|||||||
postId: Int,
|
postId: Int,
|
||||||
parentId: Int?,
|
parentId: Int?,
|
||||||
text: String,
|
text: String,
|
||||||
|
languageId: Int?,
|
||||||
auth: String,
|
auth: String,
|
||||||
) {
|
) {
|
||||||
val data = CreateCommentForm(
|
val data = CreateCommentForm(
|
||||||
content = text,
|
content = text,
|
||||||
postId = postId,
|
postId = postId,
|
||||||
parentId = parentId,
|
parentId = parentId,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
|
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
|
||||||
@ -228,11 +230,13 @@ internal class DefaultCommentRepository(
|
|||||||
override suspend fun edit(
|
override suspend fun edit(
|
||||||
commentId: Int,
|
commentId: Int,
|
||||||
text: String,
|
text: String,
|
||||||
|
languageId: Int?,
|
||||||
auth: String,
|
auth: String,
|
||||||
) {
|
) {
|
||||||
val data = EditCommentForm(
|
val data = EditCommentForm(
|
||||||
content = text,
|
content = text,
|
||||||
commentId = commentId,
|
commentId = commentId,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
|
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
|
||||||
|
@ -169,6 +169,7 @@ internal class DefaultPostRepository(
|
|||||||
body: String?,
|
body: String?,
|
||||||
url: String?,
|
url: String?,
|
||||||
nsfw: Boolean,
|
nsfw: Boolean,
|
||||||
|
languageId: Int?,
|
||||||
auth: String,
|
auth: String,
|
||||||
) {
|
) {
|
||||||
val data = CreatePostForm(
|
val data = CreatePostForm(
|
||||||
@ -177,6 +178,7 @@ internal class DefaultPostRepository(
|
|||||||
body = body,
|
body = body,
|
||||||
url = url,
|
url = url,
|
||||||
nsfw = nsfw,
|
nsfw = nsfw,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
services.post.create(
|
services.post.create(
|
||||||
@ -191,6 +193,7 @@ internal class DefaultPostRepository(
|
|||||||
body: String?,
|
body: String?,
|
||||||
url: String?,
|
url: String?,
|
||||||
nsfw: Boolean,
|
nsfw: Boolean,
|
||||||
|
languageId: Int?,
|
||||||
auth: String,
|
auth: String,
|
||||||
) {
|
) {
|
||||||
val data = EditPostForm(
|
val data = EditPostForm(
|
||||||
@ -199,6 +202,7 @@ internal class DefaultPostRepository(
|
|||||||
body = body,
|
body = body,
|
||||||
url = url,
|
url = url,
|
||||||
nsfw = nsfw,
|
nsfw = nsfw,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
services.post.edit(
|
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.dto.BlockSiteForm
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
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.MetadataModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
|
||||||
@ -57,4 +58,10 @@ internal class DefaultSiteRepository(
|
|||||||
)
|
)
|
||||||
response.body()?.metadata?.toModel()
|
response.body()?.metadata?.toModel()
|
||||||
}.getOrNull()
|
}.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?,
|
body: String?,
|
||||||
url: String? = null,
|
url: String? = null,
|
||||||
nsfw: Boolean = false,
|
nsfw: Boolean = false,
|
||||||
|
languageId: Int? = null,
|
||||||
auth: String,
|
auth: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ interface PostRepository {
|
|||||||
body: String?,
|
body: String?,
|
||||||
url: String? = null,
|
url: String? = null,
|
||||||
nsfw: Boolean = false,
|
nsfw: Boolean = false,
|
||||||
|
languageId: Int? = null,
|
||||||
auth: String,
|
auth: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
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.MetadataModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
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 block(id: Int, blocked: Boolean, auth: String? = null): Result<Unit>
|
||||||
|
|
||||||
suspend fun getMetadata(url: String): MetadataModel?
|
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.CommentView
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.Community
|
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.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.All
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Local
|
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Local
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Subscribed
|
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.CommentModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentReportModel
|
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.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.ListingType
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ModlogItem
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ModlogItem
|
||||||
@ -125,29 +127,16 @@ internal fun PersonAggregates.toModel() = UserScoreModel(
|
|||||||
commentScore = commentScore ?: 0,
|
commentScore = commentScore ?: 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun PostView.toModel() = PostModel(
|
internal fun PostView.toModel() = post.toModel().copy(
|
||||||
id = post.id,
|
|
||||||
originalUrl = post.apId,
|
|
||||||
title = post.name,
|
|
||||||
text = post.body.orEmpty(),
|
|
||||||
score = counts.score,
|
score = counts.score,
|
||||||
upvotes = counts.upvotes,
|
upvotes = counts.upvotes,
|
||||||
downvotes = counts.downvotes,
|
downvotes = counts.downvotes,
|
||||||
comments = counts.comments,
|
comments = counts.comments,
|
||||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
|
||||||
url = post.url,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
creator = creator.toModel(),
|
creator = creator.toModel(),
|
||||||
saved = saved,
|
saved = saved,
|
||||||
myVote = myVote ?: 0,
|
myVote = myVote ?: 0,
|
||||||
publishDate = post.published,
|
|
||||||
updateDate = post.updated,
|
|
||||||
nsfw = post.nsfw,
|
|
||||||
embedVideoUrl = post.embedVideoUrl,
|
|
||||||
read = read,
|
read = read,
|
||||||
featuredCommunity = post.featuredCommunity,
|
|
||||||
removed = post.removed,
|
|
||||||
locked = post.locked,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun Post.toModel() = PostModel(
|
internal fun Post.toModel() = PostModel(
|
||||||
@ -163,11 +152,10 @@ internal fun Post.toModel() = PostModel(
|
|||||||
featuredCommunity = featuredCommunity,
|
featuredCommunity = featuredCommunity,
|
||||||
removed = removed,
|
removed = removed,
|
||||||
locked = locked,
|
locked = locked,
|
||||||
|
languageId = languageId,
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun CommentView.toModel() = CommentModel(
|
internal fun CommentView.toModel() = comment.toModel().copy(
|
||||||
id = comment.id,
|
|
||||||
text = comment.content,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
creator = creator.toModel(),
|
creator = creator.toModel(),
|
||||||
score = counts.score,
|
score = counts.score,
|
||||||
@ -175,13 +163,7 @@ internal fun CommentView.toModel() = CommentModel(
|
|||||||
downvotes = counts.downvotes,
|
downvotes = counts.downvotes,
|
||||||
saved = saved,
|
saved = saved,
|
||||||
myVote = myVote ?: 0,
|
myVote = myVote ?: 0,
|
||||||
publishDate = comment.published,
|
|
||||||
updateDate = comment.updated,
|
|
||||||
postId = comment.postId,
|
|
||||||
comments = counts.childCount,
|
comments = counts.childCount,
|
||||||
path = comment.path,
|
|
||||||
distinguished = comment.distinguished,
|
|
||||||
removed = comment.removed,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun Comment.toModel() = CommentModel(
|
internal fun Comment.toModel() = CommentModel(
|
||||||
@ -193,6 +175,7 @@ internal fun Comment.toModel() = CommentModel(
|
|||||||
path = path,
|
path = path,
|
||||||
distinguished = distinguished,
|
distinguished = distinguished,
|
||||||
removed = removed,
|
removed = removed,
|
||||||
|
languageId = languageId,
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun Community.toModel() = CommunityModel(
|
internal fun Community.toModel() = CommunityModel(
|
||||||
@ -222,37 +205,17 @@ internal fun CommunityView.toModel() = community.toModel().copy(
|
|||||||
internal fun PersonMentionView.toModel() = PersonMentionModel(
|
internal fun PersonMentionView.toModel() = PersonMentionModel(
|
||||||
id = personMention.id,
|
id = personMention.id,
|
||||||
read = personMention.read,
|
read = personMention.read,
|
||||||
post = PostModel(
|
post = post.toModel().copy(
|
||||||
id = post.id,
|
|
||||||
originalUrl = post.apId,
|
|
||||||
title = post.name,
|
|
||||||
text = post.body.orEmpty(),
|
|
||||||
score = counts.score,
|
score = counts.score,
|
||||||
upvotes = counts.upvotes,
|
upvotes = counts.upvotes,
|
||||||
downvotes = counts.downvotes,
|
downvotes = counts.downvotes,
|
||||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
|
||||||
url = post.url,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
creator = creator.toModel(),
|
creator = creator.toModel(),
|
||||||
saved = saved,
|
saved = saved,
|
||||||
myVote = myVote ?: 0,
|
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(
|
comment = comment.toModel().copy(
|
||||||
id = comment.id,
|
|
||||||
postId = comment.postId,
|
|
||||||
text = comment.content,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
publishDate = comment.published,
|
|
||||||
updateDate = comment.updated,
|
|
||||||
distinguished = comment.distinguished,
|
|
||||||
removed = comment.removed,
|
|
||||||
),
|
),
|
||||||
creator = creator.toModel(),
|
creator = creator.toModel(),
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
@ -267,37 +230,17 @@ internal fun PersonMentionView.toModel() = PersonMentionModel(
|
|||||||
internal fun CommentReplyView.toModel() = PersonMentionModel(
|
internal fun CommentReplyView.toModel() = PersonMentionModel(
|
||||||
id = commentReply.id,
|
id = commentReply.id,
|
||||||
read = commentReply.read,
|
read = commentReply.read,
|
||||||
post = PostModel(
|
post = post.toModel().copy(
|
||||||
id = post.id,
|
|
||||||
originalUrl = post.apId,
|
|
||||||
title = post.name,
|
|
||||||
text = post.body.orEmpty(),
|
|
||||||
score = counts.score,
|
score = counts.score,
|
||||||
upvotes = counts.upvotes,
|
upvotes = counts.upvotes,
|
||||||
downvotes = counts.downvotes,
|
downvotes = counts.downvotes,
|
||||||
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
|
||||||
url = post.url,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
creator = UserModel(id = post.creatorId),
|
creator = creator.toModel(),
|
||||||
saved = saved,
|
saved = saved,
|
||||||
myVote = myVote ?: 0,
|
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(
|
comment = comment.toModel().copy(
|
||||||
id = comment.id,
|
|
||||||
postId = comment.postId,
|
|
||||||
text = comment.content,
|
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
publishDate = comment.published,
|
|
||||||
updateDate = comment.updated,
|
|
||||||
distinguished = comment.distinguished,
|
|
||||||
removed = comment.removed,
|
|
||||||
),
|
),
|
||||||
creator = creator.toModel(),
|
creator = creator.toModel(),
|
||||||
community = community.toModel(),
|
community = community.toModel(),
|
||||||
@ -436,3 +379,9 @@ internal fun ModTransferCommunityView.toDto() = ModlogItem.ModTransferCommunity(
|
|||||||
moderator = moderator?.toModel(),
|
moderator = moderator?.toModel(),
|
||||||
user = moddedPerson.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.appearance.data.VoteFormat
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CreatePostSection
|
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
|
import dev.icerock.moko.resources.desc.StringDesc
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@ -30,6 +31,8 @@ interface CreateCommentMviModel :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ChangeLanguage(val value: Int?) : Intent
|
||||||
|
|
||||||
data class Send(val text: String) : Intent
|
data class Send(val text: String) : Intent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +46,8 @@ interface CreateCommentMviModel :
|
|||||||
val autoLoadImages: Boolean = true,
|
val autoLoadImages: Boolean = true,
|
||||||
val currentInstance: String = "",
|
val currentInstance: String = "",
|
||||||
val currentUser: String = "",
|
val currentUser: String = "",
|
||||||
|
val currentLanguageId: Int? = null,
|
||||||
|
val availableLanguages: List<LanguageModel> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed interface Effect {
|
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.PostCardBody
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.TextFormattingBar
|
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.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.navigation.di.getNavigationCoordinator
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
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.onClick
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
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.core.utils.gallery.getGalleryHelper
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||||
@ -116,8 +118,12 @@ class CreateCommentScreen(
|
|||||||
val themeRepository = remember { getThemeRepository() }
|
val themeRepository = remember { getThemeRepository() }
|
||||||
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
||||||
val typography = contentFontFamily.toTypography()
|
val typography = contentFontFamily.toTypography()
|
||||||
|
var selectLanguageDialogOpen by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
LaunchedEffect(model) {
|
LaunchedEffect(model) {
|
||||||
|
if (editedComment != null) {
|
||||||
|
model.reduce(CreateCommentMviModel.Intent.ChangeLanguage(editedComment.languageId))
|
||||||
|
}
|
||||||
model.effects.onEach { effect ->
|
model.effects.onEach { effect ->
|
||||||
when (effect) {
|
when (effect) {
|
||||||
is CreateCommentMviModel.Effect.Failure -> {
|
is CreateCommentMviModel.Effect.Failure -> {
|
||||||
@ -248,7 +254,12 @@ class CreateCommentScreen(
|
|||||||
},
|
},
|
||||||
onSelectImage = {
|
onSelectImage = {
|
||||||
openImagePicker = true
|
openImagePicker = true
|
||||||
}
|
},
|
||||||
|
currentLanguageId = uiState.currentLanguageId,
|
||||||
|
availableLanguages = uiState.availableLanguages,
|
||||||
|
onSelectLanguage = {
|
||||||
|
selectLanguageDialogOpen = true
|
||||||
|
},
|
||||||
)
|
)
|
||||||
TextField(
|
TextField(
|
||||||
modifier = Modifier
|
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()) {
|
if (uiState.value.currentUser.isEmpty()) {
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
val auth = identityRepository.authToken.value.orEmpty()
|
||||||
val currentUser = siteRepository.getCurrentUser(auth)
|
val currentUser = siteRepository.getCurrentUser(auth)
|
||||||
|
val languages = siteRepository.getLanguages(auth)
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
mvi.updateState {
|
mvi.updateState {
|
||||||
it.copy(
|
it.copy(
|
||||||
currentUser = currentUser.name,
|
currentUser = currentUser.name,
|
||||||
currentInstance = currentUser.host,
|
currentInstance = currentUser.host,
|
||||||
|
availableLanguages = languages,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,11 +67,18 @@ class CreateCommentViewModel(
|
|||||||
|
|
||||||
override fun reduce(intent: CreateCommentMviModel.Intent) {
|
override fun reduce(intent: CreateCommentMviModel.Intent) {
|
||||||
when (intent) {
|
when (intent) {
|
||||||
is CreateCommentMviModel.Intent.ChangeSection -> mvi.updateState {
|
is CreateCommentMviModel.Intent.ChangeSection -> {
|
||||||
it.copy(section = intent.value)
|
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)
|
is CreateCommentMviModel.Intent.Send -> submit(intent.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +94,7 @@ class CreateCommentViewModel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
var valid = true
|
var valid = true
|
||||||
|
val languageId = uiState.value.currentLanguageId
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
mvi.updateState {
|
mvi.updateState {
|
||||||
it.copy(
|
it.copy(
|
||||||
@ -106,12 +116,14 @@ class CreateCommentViewModel(
|
|||||||
postId = postId,
|
postId = postId,
|
||||||
parentId = parentId,
|
parentId = parentId,
|
||||||
text = text,
|
text = text,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
} else if (editedCommentId != null) {
|
} else if (editedCommentId != null) {
|
||||||
commentRepository.edit(
|
commentRepository.edit(
|
||||||
commentId = editedCommentId,
|
commentId = editedCommentId,
|
||||||
text = text,
|
text = text,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
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.architecture.MviModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CreatePostSection
|
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.CommunityModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.LanguageModel
|
||||||
import dev.icerock.moko.resources.desc.StringDesc
|
import dev.icerock.moko.resources.desc.StringDesc
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@ -50,6 +51,8 @@ interface CreatePostMviModel :
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class ChangeSection(val value: CreatePostSection) : Intent
|
data class ChangeSection(val value: CreatePostSection) : Intent
|
||||||
|
|
||||||
|
data class ChangeLanguage(val value: Int?) : Intent
|
||||||
data class Send(val body: String) : Intent
|
data class Send(val body: String) : Intent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +74,8 @@ interface CreatePostMviModel :
|
|||||||
val autoLoadImages: Boolean = true,
|
val autoLoadImages: Boolean = true,
|
||||||
val currentInstance: String = "",
|
val currentInstance: String = "",
|
||||||
val currentUser: String = "",
|
val currentUser: String = "",
|
||||||
|
val currentLanguageId: Int? = null,
|
||||||
|
val availableLanguages: List<LanguageModel> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed interface Effect {
|
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.CreatePostSection
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCard
|
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.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.navigation.di.getNavigationCoordinator
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||||
@ -141,11 +142,15 @@ class CreatePostScreen(
|
|||||||
val themeRepository = remember { getThemeRepository() }
|
val themeRepository = remember { getThemeRepository() }
|
||||||
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
val contentFontFamily by themeRepository.contentFontFamily.collectAsState()
|
||||||
val typography = contentFontFamily.toTypography()
|
val typography = contentFontFamily.toTypography()
|
||||||
|
var selectLanguageDialogOpen by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
LaunchedEffect(model) {
|
LaunchedEffect(model) {
|
||||||
val referencePost = editedPost ?: crossPost
|
val referencePost = editedPost ?: crossPost
|
||||||
model.reduce(CreatePostMviModel.Intent.SetTitle(referencePost?.title.orEmpty()))
|
model.reduce(CreatePostMviModel.Intent.SetTitle(referencePost?.title.orEmpty()))
|
||||||
model.reduce(CreatePostMviModel.Intent.SetUrl(referencePost?.url.orEmpty()))
|
model.reduce(CreatePostMviModel.Intent.SetUrl(referencePost?.url.orEmpty()))
|
||||||
|
if (editedPost != null) {
|
||||||
|
model.reduce(CreatePostMviModel.Intent.ChangeLanguage(editedPost.languageId))
|
||||||
|
}
|
||||||
when {
|
when {
|
||||||
communityId != null -> model.reduce(
|
communityId != null -> model.reduce(
|
||||||
CreatePostMviModel.Intent.SetCommunity(CommunityModel(id = communityId))
|
CreatePostMviModel.Intent.SetCommunity(CommunityModel(id = communityId))
|
||||||
@ -439,7 +444,12 @@ class CreatePostScreen(
|
|||||||
},
|
},
|
||||||
onSelectImage = {
|
onSelectImage = {
|
||||||
openImagePickerInBody = true
|
openImagePickerInBody = true
|
||||||
}
|
},
|
||||||
|
currentLanguageId = uiState.currentLanguageId,
|
||||||
|
availableLanguages = uiState.availableLanguages,
|
||||||
|
onSelectLanguage = {
|
||||||
|
selectLanguageDialogOpen = true
|
||||||
|
},
|
||||||
)
|
)
|
||||||
TextField(
|
TextField(
|
||||||
modifier = Modifier
|
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) {
|
if (uiState.loading) {
|
||||||
ProgressHud()
|
ProgressHud()
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,13 @@ class CreatePostViewModel(
|
|||||||
if (uiState.value.currentUser.isEmpty()) {
|
if (uiState.value.currentUser.isEmpty()) {
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
val auth = identityRepository.authToken.value.orEmpty()
|
||||||
val currentUser = siteRepository.getCurrentUser(auth)
|
val currentUser = siteRepository.getCurrentUser(auth)
|
||||||
|
val languages = siteRepository.getLanguages(auth)
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
mvi.updateState {
|
mvi.updateState {
|
||||||
it.copy(
|
it.copy(
|
||||||
currentUser = currentUser.name,
|
currentUser = currentUser.name,
|
||||||
currentInstance = currentUser.host,
|
currentInstance = currentUser.host,
|
||||||
|
availableLanguages = languages,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,6 +110,10 @@ class CreatePostViewModel(
|
|||||||
it.copy(section = intent.value)
|
it.copy(section = intent.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is CreatePostMviModel.Intent.ChangeLanguage -> mvi.updateState {
|
||||||
|
it.copy(currentLanguageId = intent.value)
|
||||||
|
}
|
||||||
|
|
||||||
is CreatePostMviModel.Intent.Send -> submit(intent.body)
|
is CreatePostMviModel.Intent.Send -> submit(intent.body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,6 +171,7 @@ class CreatePostViewModel(
|
|||||||
val title = uiState.value.title
|
val title = uiState.value.title
|
||||||
val url = uiState.value.url.takeIf { it.isNotEmpty() }?.trim()
|
val url = uiState.value.url.takeIf { it.isNotEmpty() }?.trim()
|
||||||
val nsfw = uiState.value.nsfw
|
val nsfw = uiState.value.nsfw
|
||||||
|
val languageId = uiState.value.currentLanguageId
|
||||||
var valid = true
|
var valid = true
|
||||||
if (title.isEmpty()) {
|
if (title.isEmpty()) {
|
||||||
mvi.updateState {
|
mvi.updateState {
|
||||||
@ -215,6 +222,7 @@ class CreatePostViewModel(
|
|||||||
body = body,
|
body = body,
|
||||||
url = url,
|
url = url,
|
||||||
nsfw = nsfw,
|
nsfw = nsfw,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -226,6 +234,7 @@ class CreatePostViewModel(
|
|||||||
body = body,
|
body = body,
|
||||||
url = url,
|
url = url,
|
||||||
nsfw = nsfw,
|
nsfw = nsfw,
|
||||||
|
languageId = languageId,
|
||||||
auth = auth,
|
auth = auth,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user