Skip to content
Open
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
10 changes: 5 additions & 5 deletions app/src/main/kotlin/com/hippo/ehviewer/ui/ComposeDefault.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.hippo.ehviewer.ui.i18n.LocalStrings
import com.hippo.ehviewer.ui.i18n.Strings
import com.hippo.ehviewer.ui.screen.SnackbarContext
import com.hippo.ehviewer.ui.screen.implicit
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LocalGlobalDialogState
Expand All @@ -23,18 +23,18 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.CoroutineScope

@Composable
inline fun <R> AnimatedVisibilityScope.Screen(
inline fun AnimatedVisibilityScope.Screen(
navigator: DestinationsNavigator,
block: @Composable context(Strings, MainActivity, SnackbarHostState, DialogState, SharedTransitionScope, TransitionsVisibilityScope, DestinationsNavigator, CoroutineScope)
() -> R,
block: @Composable context(Strings, MainActivity, SnackbarContext, DialogState, SharedTransitionScope, TransitionsVisibilityScope, DestinationsNavigator, CoroutineScope)
() -> Unit,
) = Box(modifier = Modifier.fillMaxSize()) {
val dialogState = with(LocalGlobalDialogState.current) { rememberLocal() }
with(NoopTransitionsVisibilityScope) {
togetherWith(implicit<AnimatedVisibilityScope>()) {
block(
LocalStrings.current,
with(LocalContext.current) { remember { findActivity() } },
LocalSnackBarHostState.current,
LocalSnackbarContext.current,
dialogState,
LocalSharedTransitionScope.current,
this,
Expand Down
22 changes: 11 additions & 11 deletions app/src/main/kotlin/com/hippo/ehviewer/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ShapeDefaults
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
Expand Down Expand Up @@ -130,6 +129,7 @@ import com.hippo.ehviewer.ui.destinations.SignInScreenDestination
import com.hippo.ehviewer.ui.destinations.SubscriptionScreenDestination
import com.hippo.ehviewer.ui.destinations.ToplistScreenDestination
import com.hippo.ehviewer.ui.destinations.WhatshotScreenDestination
import com.hippo.ehviewer.ui.screen.SnackbarContext
import com.hippo.ehviewer.ui.screen.asDst
import com.hippo.ehviewer.ui.screen.asDstWith
import com.hippo.ehviewer.ui.screen.navWithUrl
Expand Down Expand Up @@ -220,7 +220,7 @@ class MainActivity : EhActivity() {
val configuration = LocalConfiguration.current
val navDrawerState = rememberDrawerState(DrawerValue.Closed)
val sideSheetState = rememberDrawerState2(DrawerValue.Closed)
val snackbarState = remember { SnackbarHostState() }
val snackbar = remember { SnackbarContext() }
val scope = rememberCoroutineScope()
val navController = rememberNavController()
val navigator = navController.rememberDestinationsNavigator()
Expand Down Expand Up @@ -260,10 +260,10 @@ class MainActivity : EhActivity() {
}
}
}.onFailure {
snackbarState.showSnackbar(getString(R.string.update_failed, it.displayString()))
snackbar.showSnackbar(getString(R.string.update_failed, it.displayString()))
}
} else {
snackbarState.showSnackbar(noNetwork)
snackbar.showSnackbar(noNetwork)
}
}
}
Expand Down Expand Up @@ -321,7 +321,7 @@ class MainActivity : EhActivity() {

LaunchedEffect(Unit) {
tipFlow.collectLatest {
snackbarState.showSnackbar(it)
snackbar.showSnackbar(it)
}
}
val warning = stringResource(R.string.metered_network_warning)
Expand All @@ -331,13 +331,13 @@ class MainActivity : EhActivity() {
LaunchedEffect(Unit) {
if (connectivityManager.isActiveNetworkMetered) {
if (isAtLeastQ) {
val ret = snackbarState.showSnackbar(warning, settings, true)
val ret = snackbar.showSnackbar(warning, settings, true)
if (ret == SnackbarResult.ActionPerformed) {
val panelIntent = Intent(android.provider.Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
startActivity(panelIntent)
}
} else {
snackbarState.showSnackbar(warning)
snackbar.showSnackbar(warning)
}
}
}
Expand All @@ -360,7 +360,7 @@ class MainActivity : EhActivity() {
launch = { navigator.navigate(ProgressScreenDestination(result2.gid, result2.pToken, result2.page)) }
}
launch?.let {
val ret = snackbarState.showSnackbar(snackMessage, snackAction, true)
val ret = snackbar.showSnackbar(snackMessage, snackAction, true)
if (ret == SnackbarResult.ActionPerformed) it()
}
}
Expand All @@ -379,14 +379,14 @@ class MainActivity : EhActivity() {
LocalNavDrawerState provides navDrawerState,
LocalSideSheetState provides sideSheetState,
LocalDrawerHandle provides drawerHandle,
LocalSnackBarHostState provides snackbarState,
LocalSnackbarContext provides snackbar,
LocalSnackBarFabPadding provides animateDpAsState(snackbarFabPadding, label = "SnackbarFabPadding"),
LocalWindowSizeClass provides adaptiveInfo.windowSizeClass,
) {
Scaffold(
snackbarHost = {
SnackbarHost(
hostState = snackbarState,
hostState = snackbar.state,
modifier = Modifier.onGloballyPositioned {
with(density) {
snackbarFabPadding = it.size.height.toDp()
Expand Down Expand Up @@ -560,10 +560,10 @@ class MainActivity : EhActivity() {
}
}

val LocalSnackbarContext = compositionLocalOf<SnackbarContext> { error("CompositionLocal LocalSnackbarContext not present!") }
val LocalNavDrawerState = compositionLocalOf<DrawerState> { error("CompositionLocal LocalNavDrawerState not present!") }
val LocalSideSheetState = compositionLocalOf<DrawerState2> { error("CompositionLocal LocalSideSheetState not present!") }
val LocalDrawerHandle = compositionLocalOf<SnapshotStateList<Int>> { error("CompositionLocal LocalDrawerHandle not present!") }
val LocalSnackBarHostState = compositionLocalOf<SnackbarHostState> { error("CompositionLocal LocalSnackBarHostState not present!") }
val LocalSnackBarFabPadding = compositionLocalOf<State<Dp>> { error("CompositionLocal LocalSnackBarFabPadding not present!") }
val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> { error("CompositionLocal LocalSharedTransitionScope not present!") }

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/kotlin/com/hippo/ehviewer/ui/main/AvatarIcon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
Expand Down Expand Up @@ -48,6 +47,7 @@ import com.hippo.ehviewer.client.parser.HomeParser
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.ui.i18n.Strings
import com.hippo.ehviewer.ui.login.refreshAccountInfo
import com.hippo.ehviewer.ui.screen.SnackbarContext
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.util.displayString
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
Expand Down Expand Up @@ -81,7 +81,7 @@ private val limitFlow: StateFlow<Result> = refreshEvent.conflate()
.let { src -> merge(src, invalidateEvent.map { none() }) }
.stateIn(limitScope, SharingStarted.Eagerly, none())

context(CoroutineScope, DialogState, SnackbarHostState, DestinationsNavigator, Strings)
context(CoroutineScope, DialogState, SnackbarContext, DestinationsNavigator, Strings)
@Composable
fun AvatarIcon() {
val hasSignedIn by Settings.hasSignedIn.collectAsState()
Expand Down
46 changes: 22 additions & 24 deletions app/src/main/kotlin/com/hippo/ehviewer/ui/reader/PageActions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import android.os.Environment
import android.provider.MediaStore
import android.webkit.MimeTypeMap
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.material3.SnackbarHostState
import androidx.core.content.FileProvider
import com.hippo.ehviewer.BuildConfig.APPLICATION_ID
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.gallery.Page
import com.hippo.ehviewer.gallery.PageLoader
import com.hippo.ehviewer.ui.screen.SnackbarContext
import com.hippo.ehviewer.util.AppConfig
import com.hippo.ehviewer.util.FileUtils
import com.hippo.ehviewer.util.awaitActivityResult
Expand All @@ -28,9 +28,9 @@ import com.hippo.ehviewer.util.requestPermission
import com.hippo.files.toOkioPath
import eu.kanade.tachiyomi.util.system.logcat
import java.io.File
import kotlinx.coroutines.CoroutineScope
import kotlinx.datetime.Clock
import moe.tarsin.coroutines.runSuspendCatching
import okio.Path.Companion.toOkioPath
import splitties.systemservices.clipboardManager

context(PageLoader)
Expand All @@ -41,14 +41,14 @@ private fun Context.provideImage(index: Int): Uri? {
return FileProvider.getUriForFile(this, "$APPLICATION_ID.fileprovider", file.toFile())
}

context(SnackbarHostState, Context, PageLoader)
suspend fun shareImage(page: Page, info: GalleryInfo? = null) {
context(SnackbarContext, CoroutineScope, Context, PageLoader)
fun shareImage(page: Page, info: GalleryInfo? = null) {
val error = getString(R.string.error_cant_save_image)
val share = getString(R.string.share_image)
val noActivity = getString(R.string.error_cant_find_activity)
val uri = provideImage(page.index)
if (uri == null) {
showSnackbar(error)
launchSnackbar(error)
return
}
val intent = Intent(Intent.ACTION_SEND).apply {
Expand All @@ -61,35 +61,33 @@ suspend fun shareImage(page: Page, info: GalleryInfo? = null) {
}
try {
startActivity(Intent.createChooser(intent, share))
} catch (e: Throwable) {
showSnackbar(noActivity)
} catch (_: Throwable) {
launchSnackbar(noActivity)
}
}

context(SnackbarHostState, Context, PageLoader)
suspend fun copy(page: Page) {
context(SnackbarContext, CoroutineScope, Context, PageLoader)
fun copy(page: Page) {
val error = getString(R.string.error_cant_save_image)
val copied = getString(R.string.copied_to_clipboard)
val uri = provideImage(page.index)
if (uri == null) {
showSnackbar(error)
launchSnackbar(error)
return
}
val clipData = ClipData.newUri(contentResolver, "ehviewer", uri)
clipboardManager.setPrimaryClip(clipData)
if (!isAtLeastT) {
showSnackbar(copied)
}
if (!isAtLeastT) launchSnackbar(copied)
}

context(SnackbarHostState, Context, PageLoader)
context(SnackbarContext, CoroutineScope, Context, PageLoader)
suspend fun save(page: Page) {
val granted = isAtLeastQ || requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
val cannotSave = getString(R.string.error_cant_save_image)
if (granted) {
val filename = getImageFilename(page.index)
if (filename == null) {
showSnackbar(cannotSave)
launchSnackbar(cannotSave)
return
}
val extension = FileUtils.getExtensionFromFilename(filename)
Expand All @@ -108,7 +106,7 @@ suspend fun save(page: Page) {
val path = File(dir, AppConfig.APP_DIRNAME)
realPath = path.toString()
if (!FileUtils.ensureDirectory(path)) {
showSnackbar(cannotSave)
launchSnackbar(cannotSave)
return
}
values.put(MediaStore.MediaColumns.DATA, realPath + File.separator + filename)
Expand All @@ -121,26 +119,26 @@ suspend fun save(page: Page) {
} catch (e: Exception) {
e.logcat(e)
}
showSnackbar(cannotSave)
launchSnackbar(cannotSave)
} else if (isAtLeastQ) {
val contentValues = ContentValues()
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
contentResolver.update(imageUri, contentValues, null, null)
}
showSnackbar(getString(R.string.image_saved, realPath + File.separator + filename))
launchSnackbar(getString(R.string.image_saved, realPath + File.separator + filename))
} else {
showSnackbar(cannotSave)
launchSnackbar(cannotSave)
}
} else {
showSnackbar(getString(R.string.permission_denied))
launchSnackbar(getString(R.string.permission_denied))
}
}

context(SnackbarHostState, Context, PageLoader)
context(SnackbarContext, CoroutineScope, Context, PageLoader)
suspend fun saveTo(page: Page) {
val filename = getImageFilename(page.index)
if (filename == null) {
showSnackbar(getString(R.string.error_cant_save_image))
launchSnackbar(getString(R.string.error_cant_save_image))
return
}
val extension = FileUtils.getExtensionFromFilename(filename)
Expand All @@ -149,10 +147,10 @@ suspend fun saveTo(page: Page) {
val uri = awaitActivityResult(ActivityResultContracts.CreateDocument(mimeType), filename)
if (uri != null) {
save(index, uri.toOkioPath())
showSnackbar(getString(R.string.image_saved, uri.displayPath))
launchSnackbar(getString(R.string.image_saved, uri.displayPath))
}
}.onFailure {
it.logcat(it)
showSnackbar(getString(R.string.error_cant_find_activity))
launchSnackbar(getString(R.string.error_cant_find_activity))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -72,6 +71,7 @@ import com.hippo.ehviewer.gallery.useArchivePageLoader
import com.hippo.ehviewer.gallery.useEhPageLoader
import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.screen.SnackbarContext
import com.hippo.ehviewer.ui.theme.EhTheme
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.DialogState
Expand Down Expand Up @@ -173,7 +173,7 @@ fun AnimatedVisibilityScope.ReaderScreen(args: ReaderScreenArgs, navigator: Dest
}
}

context(MainActivity, SnackbarHostState, DialogState, CoroutineScope)
context(MainActivity, SnackbarContext, DialogState, CoroutineScope)
@Composable
fun AnimatedVisibilityScope.ReaderScreen(pageLoader: PageLoader, info: BaseGalleryInfo?) {
ConfigureKeepScreenOn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: Destinat
userComment = TextFieldValue()
commentId = -1L
comments = it
showSnackbar(msg)
launchSnackbar(msg)
}.onFailure {
val text = if (commentId != -1L) editCommentFail else commentFail
showSnackbar(text + "\n" + it.displayString())
launchSnackbar(text + "\n" + it.displayString())
}
}

Expand All @@ -233,7 +233,7 @@ fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: Destinat
awaitConfirmationOrCancel { Text(text = stringResource(R.string.filter_the_commenter, commenter)) }
Filter(FilterMode.COMMENTER, commenter).remember()
comments = comments.copy(comments = comments.comments.filterNot { it.user == commenter })
showSnackbar(filterAdded)
launchSnackbar(filterAdded)
}

suspend fun showCommentVoteStatus(comment: GalleryComment) {
Expand Down Expand Up @@ -346,15 +346,15 @@ fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: Destinat
refreshComment(true)
}
}.onSuccess { result ->
showSnackbar(
launchSnackbar(
if (isUp) {
if (0 != result.vote) voteUpSucceed else cancelVoteUpSucceed
} else {
if (0 != result.vote) voteDownSucceed else cancelVoteDownSucceed
},
)
}.onFailure {
showSnackbar(voteFailed)
launchSnackbar(voteFailed)
}
}

Expand Down
Loading