mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2864 Multispaces | Design | Update placeholder icons (#1662)
This commit is contained in:
parent
00a7ef2a2b
commit
21a2128e03
12 changed files with 194 additions and 35 deletions
|
@ -340,7 +340,7 @@ fun VaultSpaceCardPreview() {
|
|||
subtitle = "Private space",
|
||||
onCardClicked = {},
|
||||
wallpaper = Wallpaper.Default,
|
||||
icon = SpaceIconView.Placeholder
|
||||
icon = SpaceIconView.Placeholder()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ fun VaultScreenPreview() {
|
|||
Relations.SPACE_ACCESS_TYPE to SpaceAccessType.SHARED.code.toDouble()
|
||||
)
|
||||
),
|
||||
icon = SpaceIconView.Placeholder
|
||||
icon = SpaceIconView.Placeholder()
|
||||
)
|
||||
)
|
||||
},
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.anytypeio.anytype.presentation.spaces.SpaceIconView
|
|||
fun SpaceWidgetCardPreview() {
|
||||
SpaceWidgetCard(
|
||||
onClick = {},
|
||||
icon = SpaceIconView.Placeholder,
|
||||
icon = SpaceIconView.Placeholder(),
|
||||
name = "Research",
|
||||
spaceType = PRIVATE_SPACE_TYPE,
|
||||
onSpaceShareIconClicked = {},
|
||||
|
@ -49,7 +49,7 @@ fun SpaceWidgetCardPreview() {
|
|||
fun SharedSpaceWidgetCardPreview() {
|
||||
SpaceWidgetCard(
|
||||
onClick = {},
|
||||
icon = SpaceIconView.Placeholder,
|
||||
icon = SpaceIconView.Placeholder(),
|
||||
name = "Research",
|
||||
spaceType = SHARED_SPACE_TYPE,
|
||||
onSpaceShareIconClicked = {},
|
||||
|
|
|
@ -46,4 +46,31 @@ enum class ThemeColor(
|
|||
return values().singleOrNull { it.code == string } ?: DEFAULT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class SystemColor(
|
||||
val index: Int
|
||||
) {
|
||||
YELLOW(index = 1),
|
||||
AMBER(index = 2),
|
||||
RED(index = 3),
|
||||
PINK(index = 4),
|
||||
PURPLE(index = 5),
|
||||
BLUE(index = 6),
|
||||
SKY(index = 7),
|
||||
TEAL(index = 8),
|
||||
GREEN(index = 9);
|
||||
|
||||
companion object {
|
||||
private const val MAX_INDEX = 9
|
||||
fun color(idx: Int): SystemColor {
|
||||
if (idx <= 0) {
|
||||
return YELLOW
|
||||
} else {
|
||||
val indexOfColor = idx % MAX_INDEX
|
||||
return SystemColor.entries.first { it.index == indexOfColor } ?: YELLOW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -14,11 +15,15 @@ import androidx.compose.ui.graphics.Brush
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.SystemColor
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.presentation.spaces.SpaceIconView
|
||||
|
@ -33,18 +38,31 @@ fun SpaceIconView(
|
|||
icon: SpaceIconView,
|
||||
onSpaceIconClick: () -> Unit,
|
||||
) {
|
||||
val radius = when(mainSize) {
|
||||
40.dp -> 5.dp
|
||||
48.dp -> 6.dp
|
||||
64.dp -> 8.dp
|
||||
96.dp -> 12.dp
|
||||
else -> 6.dp
|
||||
}
|
||||
|
||||
val fontSize = when(mainSize) {
|
||||
40.dp -> 24.sp
|
||||
48.dp -> 28.sp
|
||||
64.dp -> 40.sp
|
||||
96.dp -> 65.sp
|
||||
else -> 28.sp
|
||||
}
|
||||
|
||||
when (icon) {
|
||||
is SpaceIconView.Image -> {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(
|
||||
model = icon.url,
|
||||
error = painterResource(id = R.drawable.ic_home_widget_space)
|
||||
),
|
||||
painter = rememberAsyncImagePainter(model = icon.url),
|
||||
contentDescription = "Custom image space icon",
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = modifier
|
||||
.size(mainSize)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.clip(RoundedCornerShape(radius))
|
||||
.noRippleClickable {
|
||||
onSpaceIconClick.invoke()
|
||||
}
|
||||
|
@ -74,14 +92,53 @@ fun SpaceIconView(
|
|||
}
|
||||
|
||||
}
|
||||
else -> {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_home_widget_space),
|
||||
contentDescription = "Placeholder space icon",
|
||||
contentScale = ContentScale.Crop,
|
||||
is SpaceIconView.Placeholder -> {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(mainSize)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(
|
||||
color = when (icon.color) {
|
||||
SystemColor.YELLOW -> colorResource(id = R.color.palette_system_yellow)
|
||||
SystemColor.AMBER -> colorResource(id = R.color.palette_system_amber_100)
|
||||
SystemColor.RED -> colorResource(id = R.color.palette_system_red)
|
||||
SystemColor.PINK -> colorResource(id = R.color.palette_system_pink)
|
||||
SystemColor.PURPLE -> colorResource(id = R.color.palette_system_purple)
|
||||
SystemColor.BLUE -> colorResource(id = R.color.palette_system_blue)
|
||||
SystemColor.SKY -> colorResource(id = R.color.palette_system_sky)
|
||||
SystemColor.TEAL -> colorResource(id = R.color.palette_system_teal)
|
||||
SystemColor.GREEN -> colorResource(id = R.color.palette_system_green)
|
||||
},
|
||||
shape = RoundedCornerShape(radius)
|
||||
)
|
||||
.clip(RoundedCornerShape(radius))
|
||||
.noRippleClickable { onSpaceIconClick.invoke() }
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.align(
|
||||
Alignment.Center
|
||||
),
|
||||
text = icon
|
||||
.name
|
||||
.ifEmpty { stringResource(id = R.string.u) }
|
||||
.take(1)
|
||||
.uppercase(),
|
||||
style = TextStyle(
|
||||
fontSize = fontSize,
|
||||
fontWeight = FontWeight(600),
|
||||
color = colorResource(id = R.color.text_label_inversion),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(mainSize)
|
||||
.background(
|
||||
color = colorResource(id = R.color.palette_system_yellow),
|
||||
shape = RoundedCornerShape(radius)
|
||||
)
|
||||
.clip(RoundedCornerShape(radius))
|
||||
.noRippleClickable { onSpaceIconClick.invoke() }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -370,7 +370,7 @@ private fun SpaceCardItemPreview() {
|
|||
spaceName = "Architecture",
|
||||
spaceStatus = SpaceStatus.SPACE_ACTIVE,
|
||||
permissions = SpaceMemberPermissions.OWNER,
|
||||
spaceIcon = SpaceIconView.Placeholder,
|
||||
spaceIcon = SpaceIconView.Placeholder(),
|
||||
onCancelJoinRequestClicked = {},
|
||||
onLeaveSpaceClicked = {},
|
||||
onDeleteSpaceClicked = {},
|
||||
|
|
|
@ -193,7 +193,7 @@ private fun GallerySpacesScreenPreview() {
|
|||
listOf(
|
||||
GallerySpaceView(
|
||||
obj = ObjectWrapper.SpaceView(map = mapOf("name" to "Space 1")),
|
||||
icon = SpaceIconView.Placeholder
|
||||
icon = SpaceIconView.Placeholder()
|
||||
)
|
||||
),
|
||||
isNewButtonVisible = true
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<string name="space">Space</string>
|
||||
<string name="space_name">Space name</string>
|
||||
<string name="default_space">Entry space</string>
|
||||
<string name="space_settings_apply_random_gradient">Apply random gradient</string>
|
||||
<string name="space_settings_apply_random_gradient">Apply random solid color</string>
|
||||
<string name="space_settings_apply_upload_image">Upload image</string>
|
||||
<string name="delete_space">Delete space</string>
|
||||
<string name="you_can_store">You can store up to %1$s of your files on our encrypted backup node for free. If you reach the limit, files will be stored only locally.</string>
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package com.anytypeio.anytype.presentation.spaces
|
||||
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.SystemColor
|
||||
import com.anytypeio.anytype.core_models.Url
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
|
||||
sealed class SpaceIconView {
|
||||
data object Loading : SpaceIconView()
|
||||
data object Placeholder : SpaceIconView()
|
||||
data class Placeholder(
|
||||
val color: SystemColor = SystemColor.YELLOW,
|
||||
val name: String = ""
|
||||
): SpaceIconView()
|
||||
@Deprecated("To be deleted")
|
||||
class Gradient(val from: String, val to: String) : SpaceIconView()
|
||||
data class Image(val url: Url) : SpaceIconView()
|
||||
}
|
||||
|
@ -20,12 +25,19 @@ fun ObjectWrapper.Basic.spaceIcon(
|
|||
SpaceIconView.Image(builder.thumbnail(hash))
|
||||
}
|
||||
iconOption != null -> {
|
||||
iconOption?.let {
|
||||
val gradient = spaceGradientProvider.get(it)
|
||||
SpaceIconView.Gradient(gradient.from, gradient.to)
|
||||
} ?: SpaceIconView.Placeholder
|
||||
SpaceIconView.Placeholder(
|
||||
name = name.orEmpty(),
|
||||
color = iconOption?.let {
|
||||
SystemColor.color(
|
||||
idx = it.toInt()
|
||||
)
|
||||
} ?: SystemColor.YELLOW
|
||||
)
|
||||
}
|
||||
else -> SpaceIconView.Placeholder
|
||||
else -> SpaceIconView.Placeholder(
|
||||
name = name.orEmpty(),
|
||||
color = SystemColor.YELLOW
|
||||
)
|
||||
}
|
||||
|
||||
fun ObjectWrapper.SpaceView.spaceIcon(
|
||||
|
@ -37,10 +49,17 @@ fun ObjectWrapper.SpaceView.spaceIcon(
|
|||
SpaceIconView.Image(builder.medium(hash))
|
||||
}
|
||||
iconOption != null -> {
|
||||
iconOption?.let {
|
||||
val gradient = spaceGradientProvider.get(it)
|
||||
SpaceIconView.Gradient(gradient.from, gradient.to)
|
||||
} ?: SpaceIconView.Placeholder
|
||||
SpaceIconView.Placeholder(
|
||||
name = name.orEmpty(),
|
||||
color = iconOption?.let {
|
||||
SystemColor.color(
|
||||
idx = it.toInt()
|
||||
)
|
||||
} ?: SystemColor.YELLOW
|
||||
)
|
||||
}
|
||||
else -> SpaceIconView.Placeholder
|
||||
else -> SpaceIconView.Placeholder(
|
||||
name = name.orEmpty(),
|
||||
color = SystemColor.YELLOW
|
||||
)
|
||||
}
|
|
@ -275,7 +275,7 @@ class HomeScreenViewModelTest {
|
|||
|
||||
private val defaultSpaceWidgetView = WidgetView.SpaceWidget.View(
|
||||
space = StubSpaceView(),
|
||||
icon = SpaceIconView.Placeholder,
|
||||
icon = SpaceIconView.Placeholder(),
|
||||
type = UNKNOWN_SPACE_TYPE,
|
||||
membersCount = 0
|
||||
)
|
||||
|
@ -284,7 +284,7 @@ class HomeScreenViewModelTest {
|
|||
|
||||
private val secondSpaceWidgetView = WidgetView.SpaceWidget.View(
|
||||
space = StubSpaceView(),
|
||||
icon = SpaceIconView.Placeholder,
|
||||
icon = SpaceIconView.Placeholder(),
|
||||
type = UNKNOWN_SPACE_TYPE,
|
||||
membersCount = 0
|
||||
)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.anytypeio.anytype.presentation.util
|
||||
|
||||
import com.anytypeio.anytype.core_models.SystemColor
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class SystemColorTest {
|
||||
|
||||
@Test
|
||||
fun `should return expected system color`() {
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.YELLOW,
|
||||
actual = SystemColor.color(
|
||||
idx = 0
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.YELLOW,
|
||||
actual = SystemColor.color(
|
||||
idx = 1
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.AMBER,
|
||||
actual = SystemColor.color(
|
||||
idx = 2
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.YELLOW,
|
||||
actual = SystemColor.color(
|
||||
idx = 10
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.AMBER,
|
||||
actual = SystemColor.color(
|
||||
idx = 11
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = SystemColor.YELLOW,
|
||||
actual = SystemColor.color(
|
||||
idx = 19
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -210,7 +210,7 @@ fun RemoteStorageScreen(
|
|||
.height(48.dp)
|
||||
) {
|
||||
SpaceIconView(
|
||||
icon = data.spaceIcon ?: SpaceIconView.Placeholder,
|
||||
icon = data.spaceIcon ?: SpaceIconView.Placeholder(),
|
||||
onSpaceIconClick = {},
|
||||
mainSize = 48.dp,
|
||||
gradientSize = 36.dp
|
||||
|
|
|
@ -18,7 +18,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -310,7 +309,7 @@ fun SpaceSettingsScreenPreview() {
|
|||
createdBy = "1235",
|
||||
network = "332311313131flsdklfksdlkfksdlkfksdlkflasd324213432432",
|
||||
name = "Dream team",
|
||||
icon = SpaceIconView.Placeholder,
|
||||
icon = SpaceIconView.Placeholder(),
|
||||
isDeletable = true,
|
||||
spaceType = DEFAULT_SPACE_TYPE,
|
||||
permissions = SpaceMemberPermissions.OWNER,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue