chore: update MIUIX
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 0.4.1
|
||||||
|
|
||||||
|
- 依赖: 同步 submodule/miuix
|
||||||
|
- 改进: 补全 haptic feedback
|
||||||
|
- 新增: 设备支持多个 IP, 自动选择延迟最低的路径
|
||||||
|
- 新增: 主页允许调整卡片顺序
|
||||||
|
|
||||||
## 0.4.0
|
## 0.4.0
|
||||||
|
|
||||||
- 依赖: scrcpy 升级至 v4.0
|
- 依赖: scrcpy 升级至 v4.0
|
||||||
|
|||||||
@@ -2,32 +2,14 @@ package io.github.miuzarte.scrcpyforandroid.pages
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.BlendMode
|
import androidx.compose.ui.graphics.BlendMode
|
||||||
@@ -40,6 +22,7 @@ import androidx.compose.ui.layout.onSizeChanged
|
|||||||
import androidx.compose.ui.layout.positionInWindow
|
import androidx.compose.ui.layout.positionInWindow
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -53,31 +36,20 @@ import io.github.miuzarte.scrcpyforandroid.R
|
|||||||
import io.github.miuzarte.scrcpyforandroid.pages.effect.BgEffectBackground
|
import io.github.miuzarte.scrcpyforandroid.pages.effect.BgEffectBackground
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.AppUpdateChecker
|
import io.github.miuzarte.scrcpyforandroid.services.AppUpdateChecker
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
||||||
|
import io.github.miuzarte.scrcpyforandroid.ui.contextClick
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import top.yukonga.miuix.kmp.basic.Card
|
import top.yukonga.miuix.kmp.basic.*
|
||||||
import top.yukonga.miuix.kmp.basic.CardDefaults
|
import top.yukonga.miuix.kmp.blur.*
|
||||||
import top.yukonga.miuix.kmp.basic.Icon
|
|
||||||
import top.yukonga.miuix.kmp.basic.IconButton
|
|
||||||
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
|
|
||||||
import top.yukonga.miuix.kmp.basic.Scaffold
|
|
||||||
import top.yukonga.miuix.kmp.basic.SmallTopAppBar
|
|
||||||
import top.yukonga.miuix.kmp.basic.Text
|
|
||||||
import top.yukonga.miuix.kmp.blur.BlendColorEntry
|
|
||||||
import top.yukonga.miuix.kmp.blur.BlurBlendMode
|
|
||||||
import top.yukonga.miuix.kmp.blur.BlurColors
|
|
||||||
import top.yukonga.miuix.kmp.blur.BlurDefaults
|
|
||||||
import top.yukonga.miuix.kmp.blur.isRenderEffectSupported
|
|
||||||
import top.yukonga.miuix.kmp.blur.layerBackdrop
|
|
||||||
import top.yukonga.miuix.kmp.blur.rememberLayerBackdrop
|
|
||||||
import top.yukonga.miuix.kmp.blur.textureBlur
|
|
||||||
import top.yukonga.miuix.kmp.preference.ArrowPreference
|
import top.yukonga.miuix.kmp.preference.ArrowPreference
|
||||||
|
import top.yukonga.miuix.kmp.shader.isRenderEffectSupported
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles
|
||||||
import java.util.Locale.getDefault
|
import java.util.Locale.getDefault
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun AboutScreen() {
|
internal fun AboutScreen() {
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
val navigator = LocalRootNavigator.current
|
val navigator = LocalRootNavigator.current
|
||||||
val enableBlur = LocalEnableBlur.current
|
val enableBlur = LocalEnableBlur.current
|
||||||
val blurBackdrop = rememberBlurBackdrop(enableBlur)
|
val blurBackdrop = rememberBlurBackdrop(enableBlur)
|
||||||
@@ -115,7 +87,12 @@ internal fun AboutScreen() {
|
|||||||
titleColor = colorScheme.onSurface.copy(alpha = scrollProgress),
|
titleColor = colorScheme.onSurface.copy(alpha = scrollProgress),
|
||||||
defaultWindowInsetsPadding = false,
|
defaultWindowInsetsPadding = false,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = navigator.pop) {
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
|
navigator.pop()
|
||||||
|
},
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.AutoMirrored.Rounded.ArrowBack,
|
Icons.AutoMirrored.Rounded.ArrowBack,
|
||||||
contentDescription = stringResource(R.string.cd_back),
|
contentDescription = stringResource(R.string.cd_back),
|
||||||
@@ -356,7 +333,7 @@ private fun AboutContent(
|
|||||||
detectTapGestures(
|
detectTapGestures(
|
||||||
onDoubleTap = {
|
onDoubleTap = {
|
||||||
isOs3Effect = !isOs3Effect
|
isOs3Effect = !isOs3Effect
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onSizeChanged { onLogoHeightChanged(it.height) }
|
.onSizeChanged { onLogoHeightChanged(it.height) }
|
||||||
@@ -387,7 +364,7 @@ private fun AboutContent(
|
|||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
context.startActivity(
|
context.startActivity(
|
||||||
Intent(Intent.ACTION_VIEW, AppUpdateChecker.REPO_URL.toUri())
|
Intent(Intent.ACTION_VIEW, AppUpdateChecker.REPO_URL.toUri()),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -407,7 +384,7 @@ private fun AboutContent(
|
|||||||
Intent(
|
Intent(
|
||||||
Intent.ACTION_VIEW,
|
Intent.ACTION_VIEW,
|
||||||
releasesUrl.toUri(),
|
releasesUrl.toUri(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -427,7 +404,7 @@ private fun AboutContent(
|
|||||||
Intent(
|
Intent(
|
||||||
Intent.ACTION_VIEW,
|
Intent.ACTION_VIEW,
|
||||||
"https://www.apache.org/licenses/LICENSE-2.0.txt".toUri(),
|
"https://www.apache.org/licenses/LICENSE-2.0.txt".toUri(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -451,7 +428,7 @@ private fun AboutContent(
|
|||||||
Intent(
|
Intent(
|
||||||
Intent.ACTION_VIEW,
|
Intent.ACTION_VIEW,
|
||||||
repo.toUri(),
|
repo.toUri(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ fun FileManagerScreen(
|
|||||||
}
|
}
|
||||||
if (showPathDialog) {
|
if (showPathDialog) {
|
||||||
PathJumpDialog(
|
PathJumpDialog(
|
||||||
show = true,
|
show = showPathDialog,
|
||||||
path = pathInput,
|
path = pathInput,
|
||||||
onPathChange = { pathInput = it },
|
onPathChange = { pathInput = it },
|
||||||
onDismissRequest = { showPathDialog = false },
|
onDismissRequest = { showPathDialog = false },
|
||||||
@@ -370,7 +370,7 @@ fun FileManagerScreen(
|
|||||||
}
|
}
|
||||||
if (showCreateFolderDialog) {
|
if (showCreateFolderDialog) {
|
||||||
CreateFolderDialog(
|
CreateFolderDialog(
|
||||||
show = true,
|
show = showCreateFolderDialog,
|
||||||
folderName = newFolderName,
|
folderName = newFolderName,
|
||||||
onFolderNameChange = { newFolderName = it },
|
onFolderNameChange = { newFolderName = it },
|
||||||
onDismissRequest = { showCreateFolderDialog = false },
|
onDismissRequest = { showCreateFolderDialog = false },
|
||||||
|
|||||||
@@ -26,28 +26,15 @@ import androidx.compose.material.icons.rounded.Devices
|
|||||||
import androidx.compose.material.icons.rounded.Folder
|
import androidx.compose.material.icons.rounded.Folder
|
||||||
import androidx.compose.material.icons.rounded.Settings
|
import androidx.compose.material.icons.rounded.Settings
|
||||||
import androidx.compose.material.icons.rounded.Terminal
|
import androidx.compose.material.icons.rounded.Terminal
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
|
||||||
import androidx.compose.runtime.mutableLongStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.runtime.staticCompositionLocalOf
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -64,44 +51,16 @@ import io.github.miuzarte.scrcpyforandroid.R
|
|||||||
import io.github.miuzarte.scrcpyforandroid.constants.UiMotion
|
import io.github.miuzarte.scrcpyforandroid.constants.UiMotion
|
||||||
import io.github.miuzarte.scrcpyforandroid.nativecore.NativeAdbService
|
import io.github.miuzarte.scrcpyforandroid.nativecore.NativeAdbService
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.AppRuntime
|
import io.github.miuzarte.scrcpyforandroid.services.*
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.AppScreenOn
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.AppUpdateChecker
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.ConnectionController
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.ConnectionStateStore
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.DeviceAdbAutoReconnectManager
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.DeviceAdbConnectionCoordinator
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.EventLogger
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.LocalSnackbarController
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.SnackbarController
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.storage.AppSettings
|
import io.github.miuzarte.scrcpyforandroid.storage.AppSettings
|
||||||
import io.github.miuzarte.scrcpyforandroid.storage.Settings
|
import io.github.miuzarte.scrcpyforandroid.storage.Settings
|
||||||
import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings
|
import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings
|
||||||
import io.github.miuzarte.scrcpyforandroid.storage.Storage.quickDevices
|
import io.github.miuzarte.scrcpyforandroid.storage.Storage.quickDevices
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar
|
import io.github.miuzarte.scrcpyforandroid.ui.*
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableFloatingBottomBar
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableFloatingBottomBarBlur
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.component.FloatingBottomBar
|
import io.github.miuzarte.scrcpyforandroid.ui.component.FloatingBottomBar
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.component.FloatingBottomBarItem
|
import io.github.miuzarte.scrcpyforandroid.ui.component.FloatingBottomBarItem
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.createThemeController
|
import kotlinx.coroutines.*
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
import top.yukonga.miuix.kmp.basic.*
|
||||||
import kotlinx.coroutines.CancellationException
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import top.yukonga.miuix.kmp.basic.Icon
|
|
||||||
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
|
|
||||||
import top.yukonga.miuix.kmp.basic.NavigationBar
|
|
||||||
import top.yukonga.miuix.kmp.basic.NavigationBarItem
|
|
||||||
import top.yukonga.miuix.kmp.basic.Scaffold
|
|
||||||
import top.yukonga.miuix.kmp.basic.SnackbarHost
|
|
||||||
import top.yukonga.miuix.kmp.basic.SnackbarHostState
|
|
||||||
import top.yukonga.miuix.kmp.basic.Text
|
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -147,18 +106,19 @@ private enum class MainBottomTabDestination(
|
|||||||
Settings(labelResId = R.string.main_tab_settings, icon = Icons.Rounded.Settings);
|
Settings(labelResId = R.string.main_tab_settings, icon = Icons.Rounded.Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface RootScreen : NavKey {
|
sealed interface RootScreen: NavKey {
|
||||||
data object Home : RootScreen
|
data object Home: RootScreen
|
||||||
data object Advanced : RootScreen
|
data object Advanced: RootScreen
|
||||||
data object About : RootScreen
|
data object About: RootScreen
|
||||||
data object VirtualButtonOrder : RootScreen
|
data object VirtualButtonOrder: RootScreen
|
||||||
data object FullscreenControl : RootScreen // compatibility mode
|
data object FullscreenControl: RootScreen // compatibility mode
|
||||||
data class ScrcpyOptionRecord(val profileId: String) : RootScreen
|
data class ScrcpyOptionRecord(val profileId: String): RootScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen() {
|
fun MainScreen() {
|
||||||
// Environment
|
// Environment
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val appContext = context.applicationContext
|
val appContext = context.applicationContext
|
||||||
val activity = remember(context) { context as? Activity }
|
val activity = remember(context) { context as? Activity }
|
||||||
@@ -186,7 +146,8 @@ fun MainScreen() {
|
|||||||
val tabs = remember { MainBottomTabDestination.entries }
|
val tabs = remember { MainBottomTabDestination.entries }
|
||||||
val pagerState = rememberPagerState(
|
val pagerState = rememberPagerState(
|
||||||
initialPage = MainBottomTabDestination.Devices.ordinal,
|
initialPage = MainBottomTabDestination.Devices.ordinal,
|
||||||
pageCount = { tabs.size })
|
pageCount = { tabs.size },
|
||||||
|
)
|
||||||
var selectedTabIndex by rememberSaveable {
|
var selectedTabIndex by rememberSaveable {
|
||||||
mutableIntStateOf(MainBottomTabDestination.Devices.ordinal)
|
mutableIntStateOf(MainBottomTabDestination.Devices.ordinal)
|
||||||
}
|
}
|
||||||
@@ -204,11 +165,14 @@ fun MainScreen() {
|
|||||||
|
|
||||||
// Scroll behaviors
|
// Scroll behaviors
|
||||||
val devicesPageScrollBehavior = MiuixScrollBehavior(
|
val devicesPageScrollBehavior = MiuixScrollBehavior(
|
||||||
canScroll = { currentTab == MainBottomTabDestination.Devices })
|
canScroll = { currentTab == MainBottomTabDestination.Devices },
|
||||||
|
)
|
||||||
val terminalPageScrollBehavior = MiuixScrollBehavior(
|
val terminalPageScrollBehavior = MiuixScrollBehavior(
|
||||||
canScroll = { currentTab == MainBottomTabDestination.Terminal })
|
canScroll = { currentTab == MainBottomTabDestination.Terminal },
|
||||||
|
)
|
||||||
val settingsPageScrollBehavior = MiuixScrollBehavior(
|
val settingsPageScrollBehavior = MiuixScrollBehavior(
|
||||||
canScroll = { currentTab == MainBottomTabDestination.Settings })
|
canScroll = { currentTab == MainBottomTabDestination.Settings },
|
||||||
|
)
|
||||||
val advancedPageScrollBehavior = MiuixScrollBehavior(
|
val advancedPageScrollBehavior = MiuixScrollBehavior(
|
||||||
canScroll = {
|
canScroll = {
|
||||||
when (currentRootScreen) {
|
when (currentRootScreen) {
|
||||||
@@ -217,7 +181,8 @@ fun MainScreen() {
|
|||||||
is RootScreen.ScrcpyOptionRecord -> true
|
is RootScreen.ScrcpyOptionRecord -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
// Navigation helpers
|
// Navigation helpers
|
||||||
val rootNavigator = remember {
|
val rootNavigator = remember {
|
||||||
@@ -336,13 +301,13 @@ fun MainScreen() {
|
|||||||
|
|
||||||
// Side-effect launchers and composition locals
|
// Side-effect launchers and composition locals
|
||||||
val picker = rememberLauncherForActivityResult(
|
val picker = rememberLauncherForActivityResult(
|
||||||
ActivityResultContracts.OpenDocument()
|
ActivityResultContracts.OpenDocument(),
|
||||||
) { uri: Uri? ->
|
) { uri: Uri? ->
|
||||||
if (uri == null) return@rememberLauncherForActivityResult
|
if (uri == null) return@rememberLauncherForActivityResult
|
||||||
runCatching {
|
runCatching {
|
||||||
context.contentResolver.takePersistableUriPermission(
|
context.contentResolver.takePersistableUriPermission(
|
||||||
uri,
|
uri,
|
||||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
Intent.FLAG_GRANT_READ_URI_PERMISSION,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
asBundle = asBundle.copy(customServerUri = uri.toString())
|
asBundle = asBundle.copy(customServerUri = uri.toString())
|
||||||
@@ -353,13 +318,13 @@ fun MainScreen() {
|
|||||||
arrayOf(
|
arrayOf(
|
||||||
"application/java-archive",
|
"application/java-archive",
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
"*/*"
|
"*/*",
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val terminalFontDocumentPicker = rememberLauncherForActivityResult(
|
val terminalFontDocumentPicker = rememberLauncherForActivityResult(
|
||||||
ActivityResultContracts.OpenDocument()
|
ActivityResultContracts.OpenDocument(),
|
||||||
) { uri: Uri? ->
|
) { uri: Uri? ->
|
||||||
if (uri == null) return@rememberLauncherForActivityResult
|
if (uri == null) return@rememberLauncherForActivityResult
|
||||||
taskScope.launch {
|
taskScope.launch {
|
||||||
@@ -392,7 +357,7 @@ fun MainScreen() {
|
|||||||
"application/x-font-ttf",
|
"application/x-font-ttf",
|
||||||
"application/x-font-otf",
|
"application/x-font-otf",
|
||||||
"*/*",
|
"*/*",
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +503,10 @@ fun MainScreen() {
|
|||||||
tabs.forEach { tab ->
|
tabs.forEach { tab ->
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
selected = currentTab == tab,
|
selected = currentTab == tab,
|
||||||
onClick = { navigateToTab(tab) },
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
|
navigateToTab(tab)
|
||||||
|
},
|
||||||
icon = tab.icon,
|
icon = tab.icon,
|
||||||
label = stringResource(tab.labelResId),
|
label = stringResource(tab.labelResId),
|
||||||
)
|
)
|
||||||
@@ -577,7 +545,7 @@ fun MainScreen() {
|
|||||||
Modifier.layerBackdrop(glassBackdrop)
|
Modifier.layerBackdrop(glassBackdrop)
|
||||||
} else {
|
} else {
|
||||||
Modifier
|
Modifier
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
beyondViewportPageCount = 1,
|
beyondViewportPageCount = 1,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextRange
|
import androidx.compose.ui.text.TextRange
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
@@ -47,6 +48,7 @@ import io.github.miuzarte.scrcpyforandroid.storage.Storage.scrcpyOptions
|
|||||||
import io.github.miuzarte.scrcpyforandroid.storage.Storage.scrcpyProfiles
|
import io.github.miuzarte.scrcpyforandroid.storage.Storage.scrcpyProfiles
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar
|
import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
||||||
|
import io.github.miuzarte.scrcpyforandroid.ui.contextClick
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -124,6 +126,8 @@ private fun RecordPreferencesPage(
|
|||||||
val taskScope = remember { CoroutineScope(SupervisorJob() + Dispatchers.IO) }
|
val taskScope = remember { CoroutineScope(SupervisorJob() + Dispatchers.IO) }
|
||||||
val currentSession by scrcpy.currentSessionState.collectAsState()
|
val currentSession by scrcpy.currentSessionState.collectAsState()
|
||||||
|
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
|
|
||||||
val soBundleShared by scrcpyOptions.bundleState.collectAsState()
|
val soBundleShared by scrcpyOptions.bundleState.collectAsState()
|
||||||
val scrcpyProfilesState by scrcpyProfiles.state.collectAsState()
|
val scrcpyProfilesState by scrcpyProfiles.state.collectAsState()
|
||||||
val sourceBundle = remember(profileId, soBundleShared, scrcpyProfilesState) {
|
val sourceBundle = remember(profileId, soBundleShared, scrcpyProfilesState) {
|
||||||
@@ -269,6 +273,7 @@ private fun RecordPreferencesPage(
|
|||||||
TextButton(
|
TextButton(
|
||||||
text = entry.value,
|
text = entry.value,
|
||||||
onClick = {
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
draftTemplate = draftTemplate.replaceSelection(entry.value)
|
draftTemplate = draftTemplate.replaceSelection(entry.value)
|
||||||
},
|
},
|
||||||
insideMargin = PaddingValues(horizontal = 10.dp, vertical = 8.dp),
|
insideMargin = PaddingValues(horizontal = 10.dp, vertical = 8.dp),
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import io.github.miuzarte.scrcpyforandroid.models.ScrcpyOptions.NewDisplay
|
|||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.LazyColumn
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.LazyColumn
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.OverlaySpinnerWithFallback
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.OverlaySpinnerWithFallback
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.ReorderableList
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.ReorderableList
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperSlider
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.ArrowSlider
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.ClientOptions
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.ClientOptions
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
||||||
@@ -117,7 +117,6 @@ internal fun ScrcpyAllOptionsScreen(
|
|||||||
val blurBackdrop = rememberBlurBackdrop(LocalEnableBlur.current)
|
val blurBackdrop = rememberBlurBackdrop(LocalEnableBlur.current)
|
||||||
val blurActive = blurBackdrop != null
|
val blurActive = blurBackdrop != null
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var showProfileMenu by rememberSaveable { mutableStateOf(false) }
|
|
||||||
var showManageProfilesSheet by rememberSaveable { mutableStateOf(false) }
|
var showManageProfilesSheet by rememberSaveable { mutableStateOf(false) }
|
||||||
val qdBundleShared by quickDevices.bundleState.collectAsState()
|
val qdBundleShared by quickDevices.bundleState.collectAsState()
|
||||||
val soBundleShared by scrcpyOptions.bundleState.collectAsState()
|
val soBundleShared by scrcpyOptions.bundleState.collectAsState()
|
||||||
@@ -235,7 +234,6 @@ internal fun ScrcpyAllOptionsScreen(
|
|||||||
text = stringResource(R.string.scrcpyopt_manage_profiles),
|
text = stringResource(R.string.scrcpyopt_manage_profiles),
|
||||||
onClick = {
|
onClick = {
|
||||||
showManageProfilesSheet = true
|
showManageProfilesSheet = true
|
||||||
showProfileMenu = false
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -957,7 +955,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
},
|
},
|
||||||
enabled = soBundle.audio,
|
enabled = soBundle.audio,
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_screen_off_timeout),
|
title = stringResource(R.string.scrcpyopt_screen_off_timeout),
|
||||||
summary = "--screen-off-timeout",
|
summary = "--screen-off-timeout",
|
||||||
value = screenOffTimeoutPresetIndex.toFloat(),
|
value = screenOffTimeoutPresetIndex.toFloat(),
|
||||||
@@ -1103,7 +1101,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_audio_bitrate),
|
title = stringResource(R.string.scrcpyopt_audio_bitrate),
|
||||||
summary = "--audio-bit-rate",
|
summary = "--audio-bit-rate",
|
||||||
value = ScrcpyPresets.AudioBitRate
|
value = ScrcpyPresets.AudioBitRate
|
||||||
@@ -1148,7 +1146,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_video_bitrate),
|
title = stringResource(R.string.scrcpyopt_video_bitrate),
|
||||||
summary = "--video-bit-rate",
|
summary = "--video-bit-rate",
|
||||||
value = soBundle.videoBitRate / 1_000_000f,
|
value = soBundle.videoBitRate / 1_000_000f,
|
||||||
@@ -1242,7 +1240,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_min_size_alignment),
|
title = stringResource(R.string.scrcpyopt_min_size_alignment),
|
||||||
summary = "--min-size-alignment",
|
summary = "--min-size-alignment",
|
||||||
value = minSizeAlignmentPresetIndex.toFloat(),
|
value = minSizeAlignmentPresetIndex.toFloat(),
|
||||||
@@ -1265,17 +1263,17 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
inputFilter = { it.filter(Char::isDigit) },
|
inputFilter = { it.filter(Char::isDigit) },
|
||||||
inputValueRange = 1f..16f,
|
inputValueRange = 1f..16f,
|
||||||
onInputConfirm = { raw ->
|
onInputConfirm = { raw ->
|
||||||
val parsed = raw.toIntOrNull() ?: return@SuperSlider
|
val parsed = raw.toIntOrNull() ?: return@ArrowSlider
|
||||||
if (parsed and (parsed - 1) != 0) {
|
if (parsed and (parsed - 1) != 0) {
|
||||||
AppRuntime.snackbar(R.string.scrcpyopt_min_size_alignment_invalid)
|
AppRuntime.snackbar(R.string.scrcpyopt_min_size_alignment_invalid)
|
||||||
return@SuperSlider
|
return@ArrowSlider
|
||||||
}
|
}
|
||||||
soBundle = soBundle.copy(
|
soBundle = soBundle.copy(
|
||||||
minSizeAlignment = parsed
|
minSizeAlignment = parsed
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_max_size),
|
title = stringResource(R.string.scrcpyopt_max_size),
|
||||||
summary = "--max-size",
|
summary = "--max-size",
|
||||||
value = maxSizePresetIndex.toFloat(),
|
value = maxSizePresetIndex.toFloat(),
|
||||||
@@ -1306,7 +1304,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_max_fps),
|
title = stringResource(R.string.scrcpyopt_max_fps),
|
||||||
summary = "--max-fps",
|
summary = "--max-fps",
|
||||||
value = maxFpsPresetIndex.toFloat(),
|
value = maxFpsPresetIndex.toFloat(),
|
||||||
@@ -1498,7 +1496,7 @@ internal fun ScrcpyAllOptionsPage(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(all = UiSpacing.Large),
|
.padding(all = UiSpacing.Large),
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.scrcpyopt_camera_fps),
|
title = stringResource(R.string.scrcpyopt_camera_fps),
|
||||||
summary = "--camera-fps",
|
summary = "--camera-fps",
|
||||||
value = cameraFpsPresetIndex.toFloat(),
|
value = cameraFpsPresetIndex.toFloat(),
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import io.github.miuzarte.scrcpyforandroid.constants.UiSpacing
|
|||||||
import io.github.miuzarte.scrcpyforandroid.nativecore.DirectAdbTransport
|
import io.github.miuzarte.scrcpyforandroid.nativecore.DirectAdbTransport
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.LazyColumn
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.LazyColumn
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SectionSmallTitle
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.SectionSmallTitle
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperSlider
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.ArrowSlider
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
||||||
import io.github.miuzarte.scrcpyforandroid.services.AppRuntime
|
import io.github.miuzarte.scrcpyforandroid.services.AppRuntime
|
||||||
@@ -459,7 +459,7 @@ fun SettingsPage(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_preview_card_height),
|
title = stringResource(R.string.pref_title_preview_card_height),
|
||||||
summary = stringResource(R.string.pref_summary_preview_card_height),
|
summary = stringResource(R.string.pref_summary_preview_card_height),
|
||||||
value = asBundle.devicePreviewCardHeightDp.toFloat(),
|
value = asBundle.devicePreviewCardHeightDp.toFloat(),
|
||||||
@@ -598,7 +598,7 @@ fun SettingsPage(
|
|||||||
stringResource(R.string.dock_display_on) +
|
stringResource(R.string.dock_display_on) +
|
||||||
stringResource(fullscreenVirtualButtonDock.directionLabelResId),
|
stringResource(fullscreenVirtualButtonDock.directionLabelResId),
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_virtual_button_height),
|
title = stringResource(R.string.pref_title_virtual_button_height),
|
||||||
value = asBundle.fullscreenVirtualButtonHeightDp.toFloat(),
|
value = asBundle.fullscreenVirtualButtonHeightDp.toFloat(),
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -637,7 +637,7 @@ fun SettingsPage(
|
|||||||
)
|
)
|
||||||
AnimatedVisibility(asBundle.showFullscreenFloatingButton) {
|
AnimatedVisibility(asBundle.showFullscreenFloatingButton) {
|
||||||
Column {
|
Column {
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_floating_button_size),
|
title = stringResource(R.string.pref_title_floating_button_size),
|
||||||
value = asBundle.fullscreenFloatingButtonSizeDp.toFloat(),
|
value = asBundle.fullscreenFloatingButtonSizeDp.toFloat(),
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -662,7 +662,7 @@ fun SettingsPage(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_floating_button_bg_opacity),
|
title = stringResource(R.string.pref_title_floating_button_bg_opacity),
|
||||||
value = asBundle.fullscreenFloatingButtonBackgroundAlphaPercent.toFloat(),
|
value = asBundle.fullscreenFloatingButtonBackgroundAlphaPercent.toFloat(),
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -687,7 +687,7 @@ fun SettingsPage(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_floating_button_ring_opacity),
|
title = stringResource(R.string.pref_title_floating_button_ring_opacity),
|
||||||
value = asBundle.fullscreenFloatingButtonRingAlphaPercent.toFloat(),
|
value = asBundle.fullscreenFloatingButtonRingAlphaPercent.toFloat(),
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -1064,7 +1064,7 @@ fun SettingsPage(
|
|||||||
item {
|
item {
|
||||||
SectionSmallTitle(stringResource(R.string.section_terminal))
|
SectionSmallTitle(stringResource(R.string.section_terminal))
|
||||||
Card {
|
Card {
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.pref_title_terminal_font_size),
|
title = stringResource(R.string.pref_title_terminal_font_size),
|
||||||
summary = stringResource(R.string.pref_summary_terminal_font_size),
|
summary = stringResource(R.string.pref_summary_terminal_font_size),
|
||||||
value = asBundle.terminalFontSizeSp,
|
value = asBundle.terminalFontSizeSp,
|
||||||
|
|||||||
@@ -6,20 +6,13 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import io.github.miuzarte.scrcpyforandroid.R
|
import io.github.miuzarte.scrcpyforandroid.R
|
||||||
import io.github.miuzarte.scrcpyforandroid.constants.UiSpacing
|
import io.github.miuzarte.scrcpyforandroid.constants.UiSpacing
|
||||||
@@ -29,20 +22,12 @@ import io.github.miuzarte.scrcpyforandroid.storage.Settings
|
|||||||
import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings
|
import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar
|
import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur
|
||||||
|
import io.github.miuzarte.scrcpyforandroid.ui.contextClick
|
||||||
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop
|
||||||
import io.github.miuzarte.scrcpyforandroid.widgets.VirtualButtonAction
|
import io.github.miuzarte.scrcpyforandroid.widgets.VirtualButtonAction
|
||||||
import io.github.miuzarte.scrcpyforandroid.widgets.VirtualButtonActions
|
import io.github.miuzarte.scrcpyforandroid.widgets.VirtualButtonActions
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import top.yukonga.miuix.kmp.basic.*
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import top.yukonga.miuix.kmp.basic.Card
|
|
||||||
import top.yukonga.miuix.kmp.basic.Icon
|
|
||||||
import top.yukonga.miuix.kmp.basic.IconButton
|
|
||||||
import top.yukonga.miuix.kmp.basic.Scaffold
|
|
||||||
import top.yukonga.miuix.kmp.basic.ScrollBehavior
|
|
||||||
import top.yukonga.miuix.kmp.basic.TopAppBar
|
|
||||||
import top.yukonga.miuix.kmp.blur.layerBackdrop
|
import top.yukonga.miuix.kmp.blur.layerBackdrop
|
||||||
import top.yukonga.miuix.kmp.preference.SwitchPreference
|
import top.yukonga.miuix.kmp.preference.SwitchPreference
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
@@ -51,6 +36,7 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
|||||||
internal fun VirtualButtonOrderScreen(
|
internal fun VirtualButtonOrderScreen(
|
||||||
scrollBehavior: ScrollBehavior,
|
scrollBehavior: ScrollBehavior,
|
||||||
) {
|
) {
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
val navigator = LocalRootNavigator.current
|
val navigator = LocalRootNavigator.current
|
||||||
val blurBackdrop = rememberBlurBackdrop(LocalEnableBlur.current)
|
val blurBackdrop = rememberBlurBackdrop(LocalEnableBlur.current)
|
||||||
val blurActive = blurBackdrop != null
|
val blurActive = blurBackdrop != null
|
||||||
@@ -65,7 +51,12 @@ internal fun VirtualButtonOrderScreen(
|
|||||||
if (blurActive) Color.Transparent
|
if (blurActive) Color.Transparent
|
||||||
else colorScheme.surface,
|
else colorScheme.surface,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = navigator.pop) {
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
|
navigator.pop()
|
||||||
|
},
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||||
contentDescription = stringResource(R.string.cd_back),
|
contentDescription = stringResource(R.string.cd_back),
|
||||||
@@ -169,10 +160,10 @@ internal fun VirtualButtonOrderPage(
|
|||||||
}
|
}
|
||||||
asBundle = asBundle.copy(
|
asBundle = asBundle.copy(
|
||||||
virtualButtonsLayout = VirtualButtonActions
|
virtualButtonsLayout = VirtualButtonActions
|
||||||
.encodeStoredLayout(buttonItems)
|
.encodeStoredLayout(buttonItems),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -183,7 +174,7 @@ internal fun VirtualButtonOrderPage(
|
|||||||
.apply { add(toIndex, removeAt(fromIndex)) }
|
.apply { add(toIndex, removeAt(fromIndex)) }
|
||||||
asBundle = asBundle.copy(
|
asBundle = asBundle.copy(
|
||||||
virtualButtonsLayout = VirtualButtonActions
|
virtualButtonsLayout = VirtualButtonActions
|
||||||
.encodeStoredLayout(buttonItems)
|
.encodeStoredLayout(buttonItems),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)()
|
)()
|
||||||
|
|||||||
@@ -13,13 +13,16 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import io.github.miuzarte.scrcpyforandroid.R
|
import io.github.miuzarte.scrcpyforandroid.R
|
||||||
|
import io.github.miuzarte.scrcpyforandroid.ui.contextClick
|
||||||
import top.yukonga.miuix.kmp.basic.ButtonDefaults
|
import top.yukonga.miuix.kmp.basic.ButtonDefaults
|
||||||
import top.yukonga.miuix.kmp.basic.Slider
|
import top.yukonga.miuix.kmp.basic.Slider
|
||||||
|
import top.yukonga.miuix.kmp.basic.SliderDefaults.SliderHapticEffect
|
||||||
import top.yukonga.miuix.kmp.basic.Text
|
import top.yukonga.miuix.kmp.basic.Text
|
||||||
import top.yukonga.miuix.kmp.basic.TextButton
|
import top.yukonga.miuix.kmp.basic.TextButton
|
||||||
import top.yukonga.miuix.kmp.overlay.OverlayDialog
|
import top.yukonga.miuix.kmp.overlay.OverlayDialog
|
||||||
@@ -28,19 +31,22 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
|||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SuperSlider(
|
fun ArrowSlider(
|
||||||
title: String,
|
title: String,
|
||||||
summary: String? = null,
|
summary: String? = null,
|
||||||
value: Float,
|
value: Float,
|
||||||
onValueChange: (Float) -> Unit,
|
onValueChange: (Float) -> Unit,
|
||||||
valueRange: ClosedFloatingPointRange<Float>,
|
valueRange: ClosedFloatingPointRange<Float>,
|
||||||
steps: Int,
|
steps: Int,
|
||||||
|
onValueChangeFinished: (() -> Unit)? = null,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
|
hapticEffect: SliderHapticEffect = SliderHapticEffect.Edge,
|
||||||
|
showKeyPoints: Boolean = false,
|
||||||
|
keyPoints: List<Float> = emptyList(),
|
||||||
|
magnetThreshold: Float = 0.02f,
|
||||||
unit: String = "",
|
unit: String = "",
|
||||||
zeroStateText: String? = null,
|
zeroStateText: String? = null,
|
||||||
showUnitWhenZeroState: Boolean = false,
|
showUnitWhenZeroState: Boolean = false,
|
||||||
showKeyPoints: Boolean = false,
|
|
||||||
keyPoints: List<Float> = emptyList(),
|
|
||||||
displayFormatter: (Float) -> String = { it.toInt().toString() },
|
displayFormatter: (Float) -> String = { it.toInt().toString() },
|
||||||
displayText: String? = null,
|
displayText: String? = null,
|
||||||
inputTitle: String = title,
|
inputTitle: String = title,
|
||||||
@@ -52,6 +58,8 @@ fun SuperSlider(
|
|||||||
inputValueRange: ClosedFloatingPointRange<Float>? = null,
|
inputValueRange: ClosedFloatingPointRange<Float>? = null,
|
||||||
onInputConfirm: (String) -> Unit,
|
onInputConfirm: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
|
|
||||||
var showInputDialog by remember { mutableStateOf(false) }
|
var showInputDialog by remember { mutableStateOf(false) }
|
||||||
var holdArrow by remember { mutableStateOf(false) }
|
var holdArrow by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@@ -59,6 +67,7 @@ fun SuperSlider(
|
|||||||
title = title,
|
title = title,
|
||||||
summary = summary,
|
summary = summary,
|
||||||
onClick = {
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
showInputDialog = true
|
showInputDialog = true
|
||||||
holdArrow = true
|
holdArrow = true
|
||||||
},
|
},
|
||||||
@@ -83,9 +92,12 @@ fun SuperSlider(
|
|||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
valueRange = valueRange,
|
valueRange = valueRange,
|
||||||
steps = steps,
|
steps = steps,
|
||||||
|
onValueChangeFinished = onValueChangeFinished,
|
||||||
|
enabled = enabled,
|
||||||
|
hapticEffect = hapticEffect,
|
||||||
showKeyPoints = showKeyPoints,
|
showKeyPoints = showKeyPoints,
|
||||||
keyPoints = keyPoints,
|
keyPoints = keyPoints,
|
||||||
enabled = enabled,
|
magnetThreshold = magnetThreshold,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -122,6 +134,8 @@ private fun SliderInputDialog(
|
|||||||
onDismissFinished: () -> Unit,
|
onDismissFinished: () -> Unit,
|
||||||
onConfirm: (String) -> Unit,
|
onConfirm: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val haptic = LocalHapticFeedback.current
|
||||||
|
|
||||||
OverlayDialog(
|
OverlayDialog(
|
||||||
show = showDialog,
|
show = showDialog,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -150,13 +164,17 @@ private fun SliderInputDialog(
|
|||||||
Row(horizontalArrangement = Arrangement.SpaceBetween) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween) {
|
||||||
TextButton(
|
TextButton(
|
||||||
text = stringResource(R.string.button_cancel),
|
text = stringResource(R.string.button_cancel),
|
||||||
onClick = onDismissRequest,
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
)
|
)
|
||||||
Spacer(Modifier.width(20.dp))
|
Spacer(Modifier.width(20.dp))
|
||||||
TextButton(
|
TextButton(
|
||||||
text = stringResource(R.string.button_confirm),
|
text = stringResource(R.string.button_confirm),
|
||||||
onClick = {
|
onClick = {
|
||||||
|
haptic.contextClick()
|
||||||
val inputValue = text.toFloatOrNull() ?: 0f
|
val inputValue = text.toFloatOrNull() ?: 0f
|
||||||
if (inputValue >= inputValueRange.start && inputValue <= inputValueRange.endInclusive) {
|
if (inputValue >= inputValueRange.start && inputValue <= inputValueRange.endInclusive) {
|
||||||
onConfirm(text.trim())
|
onConfirm(text.trim())
|
||||||
@@ -69,9 +69,9 @@ fun SuperTextField(
|
|||||||
onFocusGained: (() -> Unit)? = null,
|
onFocusGained: (() -> Unit)? = null,
|
||||||
onFocusLost: (() -> Unit)? = null,
|
onFocusLost: (() -> Unit)? = null,
|
||||||
insideMargin: DpSize = DpSize(16.dp, 16.dp),
|
insideMargin: DpSize = DpSize(16.dp, 16.dp),
|
||||||
backgroundColor: Color = colorScheme.secondaryContainer,
|
// backgroundColor: Color = colorScheme.secondaryContainer,
|
||||||
labelColor: Color = colorScheme.onSecondaryContainer,
|
// labelColor: Color = colorScheme.onSecondaryContainer,
|
||||||
borderColor: Color = colorScheme.primary,
|
// borderColor: Color = colorScheme.primary,
|
||||||
textStyle: TextStyle = textStyles.main,
|
textStyle: TextStyle = textStyles.main,
|
||||||
cursorBrush: Brush = SolidColor(colorScheme.primary),
|
cursorBrush: Brush = SolidColor(colorScheme.primary),
|
||||||
leadingIcon: @Composable (() -> Unit)? = null,
|
leadingIcon: @Composable (() -> Unit)? = null,
|
||||||
@@ -106,9 +106,9 @@ fun SuperTextField(
|
|||||||
keyboardActions = keyboardActions,
|
keyboardActions = keyboardActions,
|
||||||
visualTransformation = visualTransformation,
|
visualTransformation = visualTransformation,
|
||||||
insideMargin = insideMargin,
|
insideMargin = insideMargin,
|
||||||
backgroundColor = backgroundColor,
|
// backgroundColor = backgroundColor,
|
||||||
labelColor = labelColor,
|
// labelColor = labelColor,
|
||||||
borderColor = borderColor,
|
// borderColor = borderColor,
|
||||||
textStyle = textStyle,
|
textStyle = textStyle,
|
||||||
cursorBrush = cursorBrush,
|
cursorBrush = cursorBrush,
|
||||||
leadingIcon = leadingIcon,
|
leadingIcon = leadingIcon,
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import androidx.compose.ui.platform.LocalDensity
|
|||||||
import top.yukonga.miuix.kmp.blur.BlendColorEntry
|
import top.yukonga.miuix.kmp.blur.BlendColorEntry
|
||||||
import top.yukonga.miuix.kmp.blur.BlurColors
|
import top.yukonga.miuix.kmp.blur.BlurColors
|
||||||
import top.yukonga.miuix.kmp.blur.LayerBackdrop
|
import top.yukonga.miuix.kmp.blur.LayerBackdrop
|
||||||
import top.yukonga.miuix.kmp.blur.isRenderEffectSupported
|
|
||||||
import top.yukonga.miuix.kmp.blur.rememberLayerBackdrop
|
import top.yukonga.miuix.kmp.blur.rememberLayerBackdrop
|
||||||
import top.yukonga.miuix.kmp.blur.textureBlur
|
import top.yukonga.miuix.kmp.blur.textureBlur
|
||||||
|
import top.yukonga.miuix.kmp.shader.isRenderEffectSupported
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
|
|
||||||
val LocalEnableBlur = staticCompositionLocalOf { false }
|
val LocalEnableBlur = staticCompositionLocalOf { false }
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.input.pointer.pointerInteropFilter
|
import androidx.compose.ui.input.pointer.pointerInteropFilter
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -79,7 +78,7 @@ import io.github.miuzarte.scrcpyforandroid.constants.Defaults
|
|||||||
import io.github.miuzarte.scrcpyforandroid.constants.ScrcpyPresets
|
import io.github.miuzarte.scrcpyforandroid.constants.ScrcpyPresets
|
||||||
import io.github.miuzarte.scrcpyforandroid.constants.UiSpacing
|
import io.github.miuzarte.scrcpyforandroid.constants.UiSpacing
|
||||||
import io.github.miuzarte.scrcpyforandroid.models.DeviceShortcut
|
import io.github.miuzarte.scrcpyforandroid.models.DeviceShortcut
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperSlider
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.ArrowSlider
|
||||||
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
import io.github.miuzarte.scrcpyforandroid.scaffolds.SuperTextField
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.Scrcpy
|
||||||
import io.github.miuzarte.scrcpyforandroid.scrcpy.Shared.Codec
|
import io.github.miuzarte.scrcpyforandroid.scrcpy.Shared.Codec
|
||||||
@@ -587,7 +586,7 @@ internal fun ConfigPanel(
|
|||||||
enabled = !sessionStarted && soBundle.audio,
|
enabled = !sessionStarted && soBundle.audio,
|
||||||
)
|
)
|
||||||
AnimatedVisibility(audioBitRateVisibility) {
|
AnimatedVisibility(audioBitRateVisibility) {
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.device_config_audio_bitrate),
|
title = stringResource(R.string.device_config_audio_bitrate),
|
||||||
summary = "--audio-bit-rate",
|
summary = "--audio-bit-rate",
|
||||||
value = ScrcpyPresets.AudioBitRate
|
value = ScrcpyPresets.AudioBitRate
|
||||||
@@ -634,7 +633,7 @@ internal fun ConfigPanel(
|
|||||||
},
|
},
|
||||||
enabled = !sessionStarted,
|
enabled = !sessionStarted,
|
||||||
)
|
)
|
||||||
SuperSlider(
|
ArrowSlider(
|
||||||
title = stringResource(R.string.device_config_video_bitrate),
|
title = stringResource(R.string.device_config_video_bitrate),
|
||||||
summary = "--video-bit-rate",
|
summary = "--video-bit-rate",
|
||||||
value = soBundle.videoBitRate / 1_000_000f,
|
value = soBundle.videoBitRate / 1_000_000f,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "9.2.0"
|
agp = "9.2.1"
|
||||||
bcpkixJdk18on = "1.83"
|
bcpkixJdk18on = "1.83"
|
||||||
boringssl = "20251124"
|
boringssl = "20251124"
|
||||||
conscryptAndroid = "2.5.3"
|
conscryptAndroid = "2.5.3"
|
||||||
|
|||||||
Submodule submodule/miuix updated: 127d10c6cb...9b86e772d7
Reference in New Issue
Block a user