Skip to content

Commit

Permalink
use toast instead of screen for success message
Browse files Browse the repository at this point in the history
  • Loading branch information
danielyrovas committed Apr 22, 2024
1 parent dd42515 commit f39582b
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 283 deletions.
6 changes: 5 additions & 1 deletion app/src/main/java/org/yrovas/linklater/AppComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.yrovas.linklater.data.remote.LinkDingAPI
import org.yrovas.linklater.domain.BookmarkAPI
import org.yrovas.linklater.domain.BookmarkDataSource
import org.yrovas.linklater.domain.TagDataSource
import org.yrovas.linklater.ui.activity.AppActivity
import org.yrovas.linklater.ui.common.DestinationHost

const val TAG = "DEBUG/create"
Expand All @@ -53,7 +54,10 @@ class ApplicationScope(private val context: Context) {
dispatcher: CoroutineDispatcher = Dispatchers.Main,
job: suspend () -> Unit,
) {
context.launch(dispatcher, job)
(context as AppActivity).launch(dispatcher, job)
}
fun showSnackbar( message: String ) {
(context as AppActivity).showSnackbar(message)
}
}

Expand Down
20 changes: 6 additions & 14 deletions app/src/main/java/org/yrovas/linklater/Utils.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package org.yrovas.linklater

import android.app.Activity
import android.content.*
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.widget.Toast
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.datetime.Instant
import org.yrovas.linklater.domain.APIError
import org.yrovas.linklater.ui.activity.AppActivity
import kotlin.math.abs

fun checkURL(url: String) = url.contains(Regex("^https?://.+[.].+"))
fun checkBookmarkAPIToken(token: String) = token.length in 10..120

Expand Down Expand Up @@ -85,18 +81,14 @@ fun Context.getAppVersion(): String {
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
annotation class ThemePreview

fun Context.launch(dispatcher: CoroutineDispatcher = Dispatchers.Main, job: suspend () -> Unit) {
(this as AppActivity).launch(dispatcher, job)
}

fun String.intoTags(): List<String> =
split(" ").filter { it.isNotBlank() }.distinct()

suspend fun SnackbarHostState.show(error: APIError) {
when (error) {
APIError.NO_CONNECTION -> showSnackbar("Could not connect to LinkDing ")
APIError.NO_CONNECTION -> showSnackbar("Could not connect to LinkDing")
APIError.INCORRECT_AUTH -> showSnackbar("Invalid Token")
APIError.INCORRECT_ENDPOINT -> showSnackbar("Invalid API Endpoint")
APIError.NO_AUTH_PROVIDED -> {}
APIError.NO_AUTH_PROVIDED -> showSnackbar("No authentication provided")
}
}
20 changes: 15 additions & 5 deletions app/src/main/java/org/yrovas/linklater/ui/activity/AppActivity.kt
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
package org.yrovas.linklater.ui.activity

import android.content.Context
import android.content.Intent
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.remember
import androidx.lifecycle.lifecycleScope
import com.ramcosta.composedestinations.spec.NavHostGraphSpec
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.launch
import org.yrovas.linklater.AppComponent
import org.yrovas.linklater.create
import org.yrovas.linklater.data.local.Prefs
import org.yrovas.linklater.ui.theme.AppTheme

fun Context.launch(
dispatcher: CoroutineDispatcher = Dispatchers.Main,
job: suspend () -> Unit,
) {
(this as AppActivity).launch(dispatcher, job)
}

abstract class AppActivity : ComponentActivity() {

private val component by lazy(LazyThreadSafetyMode.NONE) {
Log.d("DEBUG/create", "AppComponent: CREATE")
AppComponent::class.create(this)
}

private val snackState: SnackbarHostState by lazy { SnackbarHostState() }

fun launch(dispatcher: CoroutineDispatcher = Dispatchers.Main, job: suspend () -> Unit) {
lifecycleScope.launch(dispatcher) { job() }
}

fun showSnackbar(message: String) {
launch { snackState.showSnackbar(message) }
}

protected fun setContent(navGraph: NavHostGraphSpec) {
StrictMode.setVmPolicy(
VmPolicy.Builder(StrictMode.getVmPolicy())
Expand All @@ -47,7 +58,6 @@ abstract class AppActivity : ComponentActivity() {
)
}
setContent {
val snackState = remember { SnackbarHostState() }
AppTheme {
destinationHost(navGraph, snackState)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -45,17 +43,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.launch
import org.yrovas.linklater.checkBookmarkAPIToken
import org.yrovas.linklater.checkURL
import org.yrovas.linklater.getAppVersion
import org.yrovas.linklater.openUri
import org.yrovas.linklater.show
import org.yrovas.linklater.ui.common.Frame
import org.yrovas.linklater.ui.common.Icon
import org.yrovas.linklater.ui.common.TextPreference
import org.yrovas.linklater.ui.state.PreferencesScreenState
import org.yrovas.linklater.ui.state.PreferencesScreenState.Effect
import org.yrovas.linklater.ui.state.PreferencesScreenState.Event
import org.yrovas.linklater.ui.theme.padding

Expand All @@ -70,23 +65,6 @@ fun PreferencesScreen(
@Suppress("NAME_SHADOWING") val state = viewModel { state() }

val defaultBookmark by state.defaultBookmark.collectAsState()
val scope = rememberCoroutineScope()

LaunchedEffect(true) {
scope.launch {
state.effect.collect { effect ->
when (effect) {
is Effect.RefreshError -> {
snackState.show(effect.error)
}

Effect.RefreshComplete -> {
snackState.showSnackbar("Refresh Completed")
}
}
}
}
}

Frame(
page = "Preferences",
Expand Down Expand Up @@ -154,7 +132,9 @@ fun PreferencesScreen(
}
},
state = state.bookmarkEndpoint.collectAsState(),
onSave = { state.saveBookmarkURL(it) },
onSave = {
state.sendEvent(Event.SaveEndpoint(url = it))
},
onCheck = { checkURL(it) },
)
TextPreference(
Expand All @@ -176,7 +156,7 @@ fun PreferencesScreen(
}
},
state = state.bookmarkAPIToken.collectAsState(),
onSave = { state.saveBookmarkAPIToken(it) },
onSave = { state.sendEvent(Event.SaveToken(it)) },
onCheck = { checkBookmarkAPIToken(it) },
)
Spacer(modifier = Modifier.height(padding.double))
Expand All @@ -185,19 +165,21 @@ fun PreferencesScreen(
icon = Icons.Default.Tag,
name = "Tags",
state = state.tag_names.collectAsState(),
onSave = { state.saveDefaultBookmark(tag_names = it) },
onSave = {
state.sendEvent(Event.SaveDefaults(tag_names = it))
},
)
StyledCheckPreference(name = "Unread",
icon = Icons.Default.Visibility,
checked = defaultBookmark.unread,
onCheckedChange = {
state.saveDefaultBookmark(unread = it)
state.sendEvent(Event.SaveDefaults(unread = it))
})
StyledCheckPreference(name = "Shared",
icon = Icons.Default.Public,
checked = defaultBookmark.shared,
onCheckedChange = {
state.saveDefaultBookmark(shared = it)
state.sendEvent(Event.SaveDefaults(shared = it))
})

Spacer(modifier = Modifier.weight(1F))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ package org.yrovas.linklater.ui.screens

import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.delay
import org.yrovas.linklater.onBackPressed
import org.yrovas.linklater.ui.activity.AppActivity
import org.yrovas.linklater.ui.activity.SaveBookmarkActivity
import org.yrovas.linklater.ui.activity.SaveBookmarkActivityGraph
import org.yrovas.linklater.ui.state.SaveBookmarkScreenState
import org.yrovas.linklater.ui.state.SaveBookmarkScreenState.Event

@Destination<SaveBookmarkActivityGraph>(start = true)
@Composable
Expand All @@ -28,14 +29,15 @@ fun SaveBookmarkActivityScreen(
LaunchedEffect(true) {
val url = (context as SaveBookmarkActivity).extractURL()
Log.d("DEBUG/nav", "Extracting Intent URL: $url")
state.updateBookmark(url = url)
state.sendEvent(Event.UpdateBookmark(url = url))
}

SaveBookmarkScreen(nav = nav,
snackState = snackState,
state = saveBookmarkScreenState,
back = { context.onBackPressed() },
onSubmitSuccess = suspend {
delay(1000)
Toast.makeText(context, "Saved Bookmark", Toast.LENGTH_SHORT).show()
(context as AppActivity).finish()
})
}
Loading

0 comments on commit f39582b

Please sign in to comment.