Friends Screen + fix string resources format
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
4612f88c69
commit
e29c5d7152
@ -0,0 +1,48 @@
|
|||||||
|
package fr.iut.alldev.allin.ui.friends
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import fr.iut.alldev.allin.data.model.User
|
||||||
|
import fr.iut.alldev.allin.ui.core.AllInLoading
|
||||||
|
import fr.iut.alldev.allin.ui.friends.components.FriendsScreenContent
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FriendsScreen(
|
||||||
|
viewModel: FriendsScreenViewModel = hiltViewModel()
|
||||||
|
) {
|
||||||
|
var search by remember { viewModel.search }
|
||||||
|
val state by remember { viewModel.state }
|
||||||
|
|
||||||
|
when (val s = state) {
|
||||||
|
is FriendsScreenViewModel.State.Loaded -> {
|
||||||
|
var deleted by remember { mutableStateOf(emptyList<User>()) }
|
||||||
|
val filteredFriends = remember(search) {
|
||||||
|
s.friends.filter {
|
||||||
|
it.username.contains(search, ignoreCase = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendsScreenContent(
|
||||||
|
friends = filteredFriends,
|
||||||
|
deleted = deleted,
|
||||||
|
search = search,
|
||||||
|
setSearch = { search = it },
|
||||||
|
onToggleDeleteFriend = {
|
||||||
|
deleted = if (deleted.contains(it)) {
|
||||||
|
deleted - it
|
||||||
|
} else {
|
||||||
|
deleted + it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendsScreenViewModel.State.Loading -> {
|
||||||
|
AllInLoading(visible = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
package fr.iut.alldev.allin.ui.friends
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import fr.iut.alldev.allin.data.model.User
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class FriendsScreenViewModel @Inject constructor(
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
val search by lazy { mutableStateOf("") }
|
||||||
|
val state by lazy { mutableStateOf<State>(State.Loading) }
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
state.value = State.Loaded(mockFriends)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class State {
|
||||||
|
data object Loading: State()
|
||||||
|
|
||||||
|
data class Loaded(val friends: List<User>): State()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mockFriends by lazy {
|
||||||
|
listOf(
|
||||||
|
User(
|
||||||
|
id = "1",
|
||||||
|
username = "Owen",
|
||||||
|
email = "",
|
||||||
|
coins = 8533
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "2",
|
||||||
|
username = "Dave",
|
||||||
|
email = "",
|
||||||
|
coins = 6942
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "3",
|
||||||
|
username = "Lucas",
|
||||||
|
email = "",
|
||||||
|
coins = 3333
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "4",
|
||||||
|
username = "Louison",
|
||||||
|
email = "",
|
||||||
|
coins = 1970
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "5",
|
||||||
|
username = "Imri",
|
||||||
|
email = "",
|
||||||
|
coins = 1
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "12",
|
||||||
|
username = "Owen",
|
||||||
|
email = "",
|
||||||
|
coins = 8533
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "22",
|
||||||
|
username = "Dave",
|
||||||
|
email = "",
|
||||||
|
coins = 6942
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "32",
|
||||||
|
username = "Lucas",
|
||||||
|
email = "",
|
||||||
|
coins = 3333
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "42",
|
||||||
|
username = "Louison",
|
||||||
|
email = "",
|
||||||
|
coins = 1970
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "52",
|
||||||
|
username = "Imri",
|
||||||
|
email = "",
|
||||||
|
coins = 1
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "13",
|
||||||
|
username = "Owen",
|
||||||
|
email = "",
|
||||||
|
coins = 8533
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "23",
|
||||||
|
username = "Dave",
|
||||||
|
email = "",
|
||||||
|
coins = 6942
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "33",
|
||||||
|
username = "Lucas",
|
||||||
|
email = "",
|
||||||
|
coins = 3333
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "43",
|
||||||
|
username = "Louison",
|
||||||
|
email = "",
|
||||||
|
coins = 1970
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "53",
|
||||||
|
username = "Imri",
|
||||||
|
email = "",
|
||||||
|
coins = 1
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "14",
|
||||||
|
username = "Owen",
|
||||||
|
email = "",
|
||||||
|
coins = 8533
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "24",
|
||||||
|
username = "Dave",
|
||||||
|
email = "",
|
||||||
|
coins = 6942
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "34",
|
||||||
|
username = "Lucas",
|
||||||
|
email = "",
|
||||||
|
coins = 3333
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "44",
|
||||||
|
username = "Louison",
|
||||||
|
email = "",
|
||||||
|
coins = 1970
|
||||||
|
),
|
||||||
|
User(
|
||||||
|
id = "54",
|
||||||
|
username = "Imri",
|
||||||
|
email = "",
|
||||||
|
coins = 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package fr.iut.alldev.allin.ui.friends.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Search
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import fr.iut.alldev.allin.R
|
||||||
|
import fr.iut.alldev.allin.data.model.User
|
||||||
|
import fr.iut.alldev.allin.ext.asPaddingValues
|
||||||
|
import fr.iut.alldev.allin.theme.AllInColorToken
|
||||||
|
import fr.iut.alldev.allin.theme.AllInTheme
|
||||||
|
import fr.iut.alldev.allin.ui.core.AllInTextField
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FriendsScreenContent(
|
||||||
|
friends: List<User>,
|
||||||
|
deleted: List<User>,
|
||||||
|
search: String,
|
||||||
|
onToggleDeleteFriend: (User) -> Unit,
|
||||||
|
setSearch: (String) -> Unit,
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentPadding = WindowInsets.navigationBars.asPaddingValues(start = 24.dp, end = 24.dp, top = 18.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(11.dp),
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.friends_title),
|
||||||
|
style = AllInTheme.typography.h1,
|
||||||
|
color = AllInColorToken.allInGrey,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
stickyHeader {
|
||||||
|
AllInTextField(
|
||||||
|
value = search,
|
||||||
|
onValueChange = setSearch,
|
||||||
|
leadingIcon = rememberVectorPainter(image = Icons.Default.Search),
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
Brush.verticalGradient(
|
||||||
|
0.5f to AllInTheme.colors.mainSurface,
|
||||||
|
1f to Color.Transparent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items(friends) {
|
||||||
|
FriendsScreenLine(
|
||||||
|
username = it.username,
|
||||||
|
isFriend = it !in deleted,
|
||||||
|
toggleIsFriend = { onToggleDeleteFriend(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun FriendsScreenContentPreview() {
|
||||||
|
AllInTheme {
|
||||||
|
FriendsScreenContent(
|
||||||
|
friends = emptyList(),
|
||||||
|
deleted = emptyList(),
|
||||||
|
search = "",
|
||||||
|
setSearch = {},
|
||||||
|
onToggleDeleteFriend = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package fr.iut.alldev.allin.ui.friends.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import fr.iut.alldev.allin.R
|
||||||
|
import fr.iut.alldev.allin.theme.AllInColorToken
|
||||||
|
import fr.iut.alldev.allin.theme.AllInTheme
|
||||||
|
import fr.iut.alldev.allin.ui.core.AllInButton
|
||||||
|
import fr.iut.alldev.allin.ui.core.ProfilePicture
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FriendsScreenLine(
|
||||||
|
username: String,
|
||||||
|
isFriend: Boolean,
|
||||||
|
toggleIsFriend: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
ProfilePicture(
|
||||||
|
size = 50.dp
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = username,
|
||||||
|
color = AllInTheme.colors.onBackground2,
|
||||||
|
style = AllInTheme.typography.sm2,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
fontSize = 15.sp,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
AllInButton(
|
||||||
|
color = if (isFriend) {
|
||||||
|
AllInTheme.colors.background
|
||||||
|
} else {
|
||||||
|
AllInColorToken.allInPurple
|
||||||
|
},
|
||||||
|
text = if (isFriend) {
|
||||||
|
stringResource(id = R.string.generic_delete)
|
||||||
|
} else {
|
||||||
|
stringResource(id = R.string.generic_add)
|
||||||
|
},
|
||||||
|
textColor = if (isFriend) {
|
||||||
|
AllInTheme.colors.onBackground
|
||||||
|
} else {
|
||||||
|
AllInColorToken.white
|
||||||
|
},
|
||||||
|
isSmall = true,
|
||||||
|
textStyle = AllInTheme.typography.sm2,
|
||||||
|
onClick = toggleIsFriend,
|
||||||
|
modifier = Modifier.weight(.5f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun FriendsScreenLinePreview() {
|
||||||
|
AllInTheme {
|
||||||
|
FriendsScreenLine(
|
||||||
|
username = "Random",
|
||||||
|
isFriend = false,
|
||||||
|
toggleIsFriend = { }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun FriendsScreenLineIsFriendPreview() {
|
||||||
|
AllInTheme {
|
||||||
|
FriendsScreenLine(
|
||||||
|
username = "Random",
|
||||||
|
isFriend = true,
|
||||||
|
toggleIsFriend = { }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue