Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ class NoteEditorKmpViewModel(
override val showSearchState: StateFlow<Boolean> = _showSearch.asStateFlow()
override val searchText: StateFlow<String> = _searchText.asStateFlow()

private val hasLinesSelection = writeopiaManager.onEditPositions
.map { it.isNotEmpty() }

override val hasSelectedLines: StateFlow<Boolean> =
combine(
hasLinesSelection,
writeopiaManager.textSelectionState
) { hasLines, selection ->
val hasTextSelection = selection.start != selection.end

hasLines || hasTextSelection
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)

// val selectionOfText = writeopiaManager.

private val findsOfSearch: Flow<Set<Int>> =
combine(writeopiaManager.documentInfo, searchText) { info, query ->
info.id to query
Expand All @@ -157,7 +172,7 @@ class NoteEditorKmpViewModel(
override val isEditable: StateFlow<Boolean> = writeopiaManager
.documentInfo
.map { info -> !info.isLocked }
.stateIn(viewModelScope, started = SharingStarted.Lazily, initialValue = false)
.stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(), initialValue = false)

private val _showGlobalMenu = MutableStateFlow(false)
override val showGlobalMenu = _showGlobalMenu.asStateFlow()
Expand Down Expand Up @@ -192,7 +207,7 @@ class NoteEditorKmpViewModel(
override val currentTitle by lazy {
writeopiaManager.currentDocument.filterNotNull().map { document ->
document.title
}.stateIn(viewModelScope, started = SharingStarted.Lazily, initialValue = "")
}.stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(), initialValue = "")
}

private val _shouldGoToNextScreen = MutableStateFlow(false)
Expand All @@ -207,7 +222,7 @@ class NoteEditorKmpViewModel(

else -> EditState.TEXT
}
}.stateIn(viewModelScope, started = SharingStarted.Lazily, initialValue = EditState.TEXT)
}.stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(), initialValue = EditState.TEXT)
}

private val story: StateFlow<StoryState> = writeopiaManager.currentStory
Expand All @@ -229,7 +244,7 @@ class NoteEditorKmpViewModel(
override val notFavorite: StateFlow<Boolean> = writeopiaManager
.documentInfo
.map { info -> !info.isFavorite }
.stateIn(viewModelScope, started = SharingStarted.Lazily, initialValue = false)
.stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(), initialValue = false)

private var aiJob: Job? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ interface NoteEditorViewModel : BackstackInform, BackstackHandler {

val searchText: StateFlow<String>

val hasSelectedLines: StateFlow<Boolean>

fun showSearch()

fun hideSearch()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.writeopia.sdk.models.span.Span
import io.writeopia.ui.icons.WrSdkIcons
Expand All @@ -32,6 +33,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
@Composable
fun EditionScreen(
modifier: Modifier = Modifier,
iconSize: Dp = 36.dp,
onSpanClick: (Span) -> Unit = {},
checkboxClick: () -> Unit = {},
listItemClick: () -> Unit = {},
Expand All @@ -43,15 +45,13 @@ fun EditionScreen(
) {
val iconPadding = PaddingValues(vertical = 4.dp)
val clipShape = MaterialTheme.shapes.medium
val iconSize = 36.dp
val spaceWidth = 8.dp

Row(modifier = modifier.padding(8.dp), verticalAlignment = Alignment.CenterVertically) {
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
val tint = MaterialTheme.colorScheme.onPrimary

Row(
modifier = Modifier
.weight(1f)
.horizontalScroll(rememberScrollState()),
verticalAlignment = Alignment.CenterVertically
) {
Expand Down Expand Up @@ -133,7 +133,7 @@ fun EditionScreen(
modifier = Modifier
.clip(clipShape)
.clickable(onClick = onCopy)
.size(32.dp)
.size(iconSize)
.padding(iconPadding),
imageVector = WrSdkIcons.copy,
contentDescription = "Copy",
Expand All @@ -146,7 +146,7 @@ fun EditionScreen(
modifier = Modifier
.clip(clipShape)
.clickable(onClick = onCut)
.size(32.dp)
.size(iconSize)
.padding(iconPadding),
imageVector = Icons.Default.ContentCut,
contentDescription = "Cut",
Expand Down Expand Up @@ -195,6 +195,110 @@ fun EditionScreen(
}
}

@Composable
fun EditionScreenForText(
modifier: Modifier = Modifier,
iconSize: Dp = 36.dp,
onSpanClick: (Span) -> Unit = {},
) {
val iconPadding = PaddingValues(vertical = 4.dp)
val clipShape = MaterialTheme.shapes.medium
val spaceWidth = 8.dp

Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
val tint = MaterialTheme.colorScheme.onPrimary

Row(
modifier = Modifier
.horizontalScroll(rememberScrollState()),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
modifier = Modifier
.clip(clipShape)
.clickable {
onSpanClick(Span.BOLD)
}
.size(iconSize)
.padding(iconPadding),
imageVector = Icons.Outlined.FormatBold,
contentDescription = "BOLD",
// contentDescription = stringResource(R.string.delete),
tint = tint
)

Icon(
modifier = Modifier
.clip(clipShape)
.clickable {
onSpanClick(Span.ITALIC)
}
.size(iconSize)
.padding(iconPadding),
imageVector = Icons.Outlined.FormatItalic,
contentDescription = "ITALIC",
// contentDescription = stringResource(R.string.delete),
tint = tint
)

Spacer(modifier = Modifier.width(spaceWidth))

Icon(
modifier = Modifier
.clip(clipShape)
.clickable {
onSpanClick(Span.UNDERLINE)
}
.size(iconSize)
.padding(iconPadding),
imageVector = Icons.Outlined.FormatUnderlined,
contentDescription = "UNDERLINE",
// contentDescription = stringResource(R.string.delete),
tint = tint
)

// Spacer(modifier = Modifier.width(spaceWidth))
//
// Icon(
// modifier = Modifier
// .clip(clipShape)
// .clickable(onClick = onCopy)
// .size(iconSize)
// .padding(iconPadding),
// imageVector = WrSdkIcons.copy,
// contentDescription = "Copy",
// tint = tint
// )
//
// Spacer(modifier = Modifier.width(spaceWidth))
//
// Icon(
// modifier = Modifier
// .clip(clipShape)
// .clickable(onClick = onCut)
// .size(iconSize)
// .padding(iconPadding),
// imageVector = Icons.Default.ContentCut,
// contentDescription = "Cut",
// tint = tint
// )

// Spacer(modifier = Modifier.width(spaceWidth))
//
// Icon(
// modifier = Modifier
// .clip(clipShape)
// .clickable(onClick = onAddPage)
// .size(iconSize)
// .padding(iconPadding),
// imageVector = WrSdkIcons.linkPage,
// contentDescription = "Link to page",
// tint = tint
// )
}
}
}

@Preview
@Composable
fun EditionScreenPreview() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.writeopia.ui.drawer

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import io.writeopia.sdk.models.span.Span
import io.writeopia.ui.components.EditionScreenForText

@Composable
fun TextToolbox(
hasSelection: Boolean,
onSpanClick: (Span) -> Unit = {},
) {
Popup(offset = IntOffset(0, -40)) {
AnimatedVisibility(
modifier = Modifier,
visible = hasSelection,
enter = fadeIn(animationSpec = tween(durationMillis = 150)),
exit = fadeOut(animationSpec = tween(durationMillis = 150))
) {
EditionScreenForText(
modifier = Modifier
.shadow(elevation = 6.dp)
.clip(MaterialTheme.shapes.medium)
.background(MaterialTheme.colorScheme.primary)
.padding(horizontal = 8.dp, vertical = 2.dp),
iconSize = 28.dp,
onSpanClick = onSpanClick,
)
}
}
}
Loading