Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting options #58

Merged
merged 5 commits into from
Jul 1, 2023
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
@@ -1,5 +1,6 @@
package br.com.leandroferreira.app_sample.navigation

import android.content.Context
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -11,17 +12,17 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import br.com.leandroferreira.app_sample.screens.menu.NotesUseCase
import br.com.leandroferreira.app_sample.screens.menu.ui.screen.ChooseNoteScreen
import br.com.leandroferreira.app_sample.screens.menu.viewmodel.ChooseNoteViewModel
import br.com.leandroferreira.app_sample.screens.menu.NotesUseCase
import br.com.leandroferreira.app_sample.screens.note.NoteDetailsScreen
import br.com.leandroferreira.app_sample.screens.note.NoteDetailsViewModel
import br.com.leandroferreira.app_sample.screens.note.NoteDetailsViewModelFactory
import br.com.leandroferreira.app_sample.theme.ApplicationComposeTheme
import com.github.leandroborgesferreira.storyteller.video.VideoFrameConfig
import com.github.leandroborgesferreira.storyteller.manager.StoryTellerManager
import com.github.leandroborgesferreira.storyteller.persistence.database.StoryTellerDatabase
import com.github.leandroborgesferreira.storyteller.persistence.repository.DocumentRepositoryImpl
import com.github.leandroborgesferreira.storyteller.video.VideoFrameConfig

class NavigationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -40,6 +41,10 @@ fun NavigationGraph() {
val navController = rememberNavController()
val context = LocalContext.current
val database = StoryTellerDatabase.database(context)
val sharedPreferences = context.getSharedPreferences(
"br.com.leandroferreira.storyteller.preferences",
Context.MODE_PRIVATE
)

ApplicationComposeTheme {

Expand All @@ -50,7 +55,7 @@ fun NavigationGraph() {
database.storyUnitDao()
)

val notesUseCase = NotesUseCase(repository)
val notesUseCase = NotesUseCase(repository, sharedPreferences)
val chooseNoteViewModel = ChooseNoteViewModel(notesUseCase)

ChooseNoteScreen(chooseNoteViewModel = chooseNoteViewModel) { noteId ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
package br.com.leandroferreira.app_sample.screens.menu

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import br.com.leandroferreira.app_sample.data.supermarketList
import br.com.leandroferreira.app_sample.data.travelHistory
import com.github.leandroborgesferreira.storyteller.model.document.Document
import com.github.leandroborgesferreira.storyteller.persistence.repository.DocumentRepositoryImpl
import com.github.leandroborgesferreira.storyteller.persistence.sorting.OrderBy
import com.github.leandroborgesferreira.storyteller.persistence.sorting.toEntityField
import java.util.Date
import java.util.UUID

class NotesUseCase(private val documentRepository: DocumentRepositoryImpl) {
class NotesUseCase(
private val documentRepository: DocumentRepositoryImpl,
private val sharedPreferences: SharedPreferences
) {

suspend fun loadDocuments(): List<Document> = documentRepository.loadDocuments()
fun saveDocumentSortingPref(orderBy: OrderBy) {
sharedPreferences.edit()
.run { putString(ORDER_BY_PREFERENCE, orderBy.type.toEntityField()) }
.commit()
}

suspend fun loadDocuments(): List<Document> =
sharedPreferences
.getString(ORDER_BY_PREFERENCE, OrderBy.CREATE.type.toEntityField())
?.let { orderBy -> documentRepository.loadDocuments(orderBy) }!!

suspend fun mockData(context: Context) {
documentRepository.saveDocument(
Expand All @@ -33,4 +49,8 @@ class NotesUseCase(private val documentRepository: DocumentRepositoryImpl) {
)
)
}

companion object {
private const val ORDER_BY_PREFERENCE = "order_by_preference"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,12 @@ private fun Content(
) {
Notes(chooseNoteViewModel = chooseNoteViewModel, navigateToNote = navigateToNote)

ConfigurationsMenu(editState = editState, chooseNoteViewModel)
ConfigurationsMenu(
editState = editState,
listOptionClick = chooseNoteViewModel::listArrangementSelected,
gridOptionClick = chooseNoteViewModel::gridArrangementSelected,
sortingSelected = chooseNoteViewModel::sortingSelected
)
}
}

Expand Down Expand Up @@ -170,7 +175,7 @@ private fun Notes(chooseNoteViewModel: ChooseNoteViewModel, navigateToNote: (Str
private fun LazyGridNotes(documents: List<DocumentCard>, onDocumentClick: (String) -> Unit) {
LazyVerticalStaggeredGrid(
modifier = Modifier.padding(6.dp),
columns = StaggeredGridCells.Adaptive(minSize = 200.dp),
columns = StaggeredGridCells.Adaptive(minSize = 150.dp),
horizontalArrangement = Arrangement.spacedBy(6.dp),
content = {
items(documents) { document ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package br.com.leandroferreira.app_sample.screens.menu.ui.screen

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
Expand All @@ -11,27 +10,38 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Dashboard
import androidx.compose.material.icons.outlined.List
import androidx.compose.material3.Divider
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.composed
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import br.com.leandroferreira.app_sample.R
import br.com.leandroferreira.app_sample.screens.menu.viewmodel.ChooseNoteViewModel
import br.com.leandroferreira.app_sample.views.SlideInBox
import com.github.leandroborgesferreira.storyteller.persistence.sorting.OrderBy

private const val INNER_PADDING = 3

@Composable
internal fun BoxScope.ConfigurationsMenu(editState: Boolean, viewModel: ChooseNoteViewModel) {
internal fun BoxScope.ConfigurationsMenu(
editState: Boolean,
listOptionClick: () -> Unit,
gridOptionClick: () -> Unit,
sortingSelected: (OrderBy) -> Unit,
) {
// Todo: Extract to a global use function
SlideInBox(
modifier = Modifier.align(Alignment.BottomCenter),
Expand All @@ -56,17 +66,9 @@ internal fun BoxScope.ConfigurationsMenu(editState: Boolean, viewModel: ChooseNo
.background(MaterialTheme.colorScheme.primary)
.padding(16.dp),
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "Ordering",
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onPrimary
)

ArrangementOptions(
listOptionClick = viewModel::listArrangementSelected,
gridOptionClick = viewModel::gridArrangementSelected,
)
ArrangementSection(listOptionClick, gridOptionClick)

SortingSection(sortingSelected = sortingSelected)

Spacer(modifier = Modifier.height(90.dp))
}
Expand All @@ -80,37 +82,122 @@ internal fun BoxScope.ConfigurationsMenu(editState: Boolean, viewModel: ChooseNo
}
}

@Composable
private fun SectionText(text: String) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp, bottom = 6.dp),
text = text,
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onPrimary
)
}

@Composable
private fun ArrangementOptions(listOptionClick: () -> Unit, gridOptionClick: () -> Unit) {
Row(modifier = Modifier.fillMaxWidth()) {
Image(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(INNER_PADDING.dp)
) {
Icon(
modifier = Modifier
.orderConfigModifier(clickable = gridOptionClick)
.weight(1F),
imageVector = Icons.Outlined.Dashboard,
contentDescription = stringResource(R.string.staggered_card)
contentDescription = stringResource(R.string.staggered_card),
tint = MaterialTheme.colorScheme.onPrimary
)

Image(
Spacer(modifier = Modifier.width(8.dp))

Icon(
modifier = Modifier
.orderConfigModifier(clickable = listOptionClick)
.weight(1F),
imageVector = Icons.Outlined.List,
contentDescription = stringResource(R.string.note_list)
contentDescription = stringResource(R.string.note_list),
tint = MaterialTheme.colorScheme.onPrimary
)
}
}

@Composable
private fun ArrangementSection(listOptionClick: () -> Unit, gridOptionClick: () -> Unit) {
SectionText(text = stringResource(R.string.arrangement))

ArrangementOptions(
listOptionClick = listOptionClick,
gridOptionClick = gridOptionClick,
)
}

@Composable
private fun SortingSection(sortingSelected: (OrderBy) -> Unit) {
SectionText(text = stringResource(R.string.sorting))
val optionStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.onPrimary,
fontWeight = FontWeight.Bold
)

Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = INNER_PADDING.dp)
.clip(RoundedCornerShape(6.dp))
.background(MaterialTheme.colorScheme.secondary)
) {
Text(
modifier = Modifier
.clickable { sortingSelected(OrderBy.UPDATE) }
.sortingOptionModifier(),
text = stringResource(R.string.last_updated),
style = optionStyle,
)

Divider(color = MaterialTheme.colorScheme.primary)

Text(
modifier = Modifier
.clickable { sortingSelected(OrderBy.CREATE) }
.sortingOptionModifier(),
text = stringResource(R.string.last_created),
style = optionStyle,
)

Divider(color = MaterialTheme.colorScheme.primary)

Text(
modifier = Modifier
.clickable { sortingSelected(OrderBy.NAME) }
.sortingOptionModifier(),
text = stringResource(R.string.name),
style = optionStyle,
)
}
}

private fun Modifier.sortingOptionModifier(): Modifier = fillMaxWidth().padding(12.dp)

private fun Modifier.orderConfigModifier(clickable: () -> Unit): Modifier =
padding(8.dp)
.clip(RoundedCornerShape(6.dp))
.background(Color.Cyan)
.clickable(onClick = clickable)
.padding(6.dp)
composed {
clip(RoundedCornerShape(6.dp))
.background(MaterialTheme.colorScheme.secondary)
.clickable(onClick = clickable)
.padding(6.dp)
}

@Preview
@Composable
private fun ConfigurationsMenu_Preview() {
Box(modifier = Modifier.fillMaxWidth()) {
ConfigurationsMenu(true, {}, {}, {})
}
}

@Preview
@Composable
fun ArrangementOptions_Preview() {
private fun ArrangementOptions_Preview() {
ArrangementOptions({}, {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import br.com.leandroferreira.app_sample.screens.menu.NotesUseCase
import br.com.leandroferreira.app_sample.screens.menu.ui.dto.DocumentCard
import br.com.leandroferreira.app_sample.utils.ResultData
import com.github.leandroborgesferreira.storyteller.parse.PreviewParser
import com.github.leandroborgesferreira.storyteller.persistence.sorting.OrderBy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -30,19 +31,23 @@ class ChooseNoteViewModel(
fun requestDocuments() {
if (documentsState.value !is ResultData.Complete) {
viewModelScope.launch(Dispatchers.IO) {
_documentsState.value = ResultData.Loading()
refreshDocuments()
}
}
}

try {
val data = notesUseCase.loadDocuments()
.map { document ->
document.toUiCard(previewParser)
}
private suspend fun refreshDocuments() {
_documentsState.value = ResultData.Loading()

_documentsState.value = ResultData.Complete(data)
} catch (e: Exception) {
_documentsState.value = ResultData.Error(e)
try {
val data = notesUseCase.loadDocuments()
.map { document ->
document.toUiCard(previewParser)
}
}

_documentsState.value = ResultData.Complete(data)
} catch (e: Exception) {
_documentsState.value = ResultData.Error(e)
}
}

Expand All @@ -67,4 +72,10 @@ class ChooseNoteViewModel(
_notesArrangement.value = NotesArrangement.GRID
}

fun sortingSelected(orderBy: OrderBy) {
viewModelScope.launch {
notesUseCase.saveDocumentSortingPref(orderBy)
refreshDocuments()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package br.com.leandroferreira.app_sample.theme
import androidx.compose.ui.graphics.Color

val ORANGE = Color(0xFFF2994A)
val DARK_ORANGE = Color(0xFFF3AA5B)
val BACKGROUND_VARIATION = Color(0xFFFAF8F2)
val BACKGROUND_VARIATION_DARK = Color.DarkGray
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color

private val DarkColorPalette = darkColorScheme(
primary = ORANGE,
secondary = ORANGE,
secondary = DARK_ORANGE,
onPrimary = Color.White,
onSecondary = Color.White,
onBackground = Color.White,
Expand All @@ -18,7 +18,7 @@ private val DarkColorPalette = darkColorScheme(

private val LightColorPalette = lightColorScheme(
primary = ORANGE,
secondary = ORANGE,
secondary = DARK_ORANGE,
onPrimary = Color.White,
onSecondary = Color.White,
onBackground = Color.Black,
Expand Down
Loading