Skip to content

Commit

Permalink
add notifications with snackbar
Browse files Browse the repository at this point in the history
  • Loading branch information
avan1235 committed Feb 18, 2024
1 parent 83b7ee1 commit 799e9bf
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
44 changes: 36 additions & 8 deletions composeApp/src/commonMain/kotlin/in/procyk/shin/App.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.*
import `in`.procyk.shin.createHttpClient
import `in`.procyk.shin.ui.ShortenRequest
import `in`.procyk.shin.ui.ShortenResponse
import `in`.procyk.shin.ui.theme.ShinTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

@Composable
fun ShinApp() {
val client = remember { createHttpClient() }
ShinTheme {
var shortenedUrl by remember<MutableState<String?>> { mutableStateOf(null) }
Column(
modifier = Modifier
.fillMaxSize()
.onKeyEvent { event -> event.isEscDown.also { if (it) shortenedUrl = null } },
verticalArrangement = Arrangement.Center,
val snackbarHostState = remember { SnackbarHostState() }
val snackbarHostStateScope = rememberCoroutineScope()
Scaffold(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
) {
ShortenRequest(client, onResponse = { shortenedUrl = it })
ShortenResponse(shortenedUrl)
var shortenedUrl by remember<MutableState<String?>> { mutableStateOf(null) }
Column(
modifier = Modifier
.fillMaxSize()
.onKeyEvent { event -> event.isEscDown.also { if (it) shortenedUrl = null } },
verticalArrangement = Arrangement.Center,
) {
ShortenRequest(
client = client,
onResponse = { shortenedUrl = it },
onError = { snackbarHostStateScope.showErrorSnackbarNotification(snackbarHostState, it) })
ShortenResponse(shortenedUrl)
}
}
}
}

private fun CoroutineScope.showErrorSnackbarNotification(
snackbarHostState: SnackbarHostState,
message: String,
) {
launch {
snackbarHostState.showSnackbar(
message = message,
withDismissAction = true,
duration = SnackbarDuration.Short,
)
}
}

private val KeyEvent.isEscDown: Boolean
get() = key == Key.Escape && type == KeyEventType.KeyDown
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import kotlinx.coroutines.launch
internal fun ShortenRequest(
client: HttpClient,
onResponse: (String) -> Unit,
onError: (String) -> Unit,
space: Dp = 8.dp,
) {
BoxWithConstraints {
Expand All @@ -42,7 +43,13 @@ internal fun ShortenRequest(
),
horizontalAlignment = Alignment.CenterHorizontally,
) {
ShortenRequestElements(client, onResponse, fillMaxWidth = true, maxTextFieldWidth = maxWidth / 2)
ShortenRequestElements(
client = client,
onResponse = onResponse,
onError = onError,
fillMaxWidth = true,
maxTextFieldWidth = maxWidth / 2
)
}
} else {
Row(
Expand All @@ -53,7 +60,13 @@ internal fun ShortenRequest(
),
verticalAlignment = Alignment.Bottom,
) {
ShortenRequestElements(client, onResponse, fillMaxWidth = false, maxTextFieldWidth = maxWidth / 2)
ShortenRequestElements(
client = client,
onResponse = onResponse,
onError = onError,
fillMaxWidth = false,
maxTextFieldWidth = maxWidth / 2
)
}
}
}
Expand All @@ -63,6 +76,7 @@ internal fun ShortenRequest(
private fun ShortenRequestElements(
client: HttpClient,
onResponse: (String) -> Unit,
onError: (String) -> Unit,
fillMaxWidth: Boolean,
maxTextFieldWidth: Dp,
) {
Expand Down Expand Up @@ -91,7 +105,7 @@ private fun ShortenRequestElements(
.applyIf(!fillMaxWidth) { widthIn(max = maxTextFieldWidth) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = { client.askForShortenedUrl(scope, url, shortenedProtocol, onResponse) }
onDone = { client.askForShortenedUrl(scope, url, shortenedProtocol, onResponse, onError) }
),
singleLine = true,
shape = RoundedCornerShape(12.dp),
Expand All @@ -101,7 +115,7 @@ private fun ShortenRequestElements(
.height(56.dp)
.applyIf(fillMaxWidth) { fillMaxWidth() },
shape = RoundedCornerShape(12.dp),
onClick = { client.askForShortenedUrl(scope, url, shortenedProtocol, onResponse) }
onClick = { client.askForShortenedUrl(scope, url, shortenedProtocol, onResponse, onError) }
) {
Text(
text = "Shorten",
Expand Down Expand Up @@ -164,12 +178,14 @@ private fun HttpClient.askForShortenedUrl(
url: String,
shortenedProtocol: ShortenedProtocol,
onResponse: (String) -> Unit,
onError: (String) -> Unit,
): Job = scope.launch {
try {
post<Shorten>(Shorten(shortenedProtocol.buildUrl(url)))
.takeIf { it.status == HttpStatusCode.OK }
?.bodyAsText()
?.let(onResponse)
} catch (_: Exception) {
onError("Cannot connect to Shin. Try again later…")
}
}

0 comments on commit 799e9bf

Please sign in to comment.