Skip to content

Commit

Permalink
[kmp/DeskNMM] 增加对网页快捷键的处理。
Browse files Browse the repository at this point in the history
  • Loading branch information
huang493 committed Jul 15, 2024
1 parent ca4a7c1 commit 58eb55b
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -416,5 +416,10 @@ object BrowserI18nResource {
Language.EN to "Share"
)

val uninstallAlert = SimpleI18nResource(
Language.ZH to "其所有数据也将被删除",
Language.EN to "All its data will also be deleted!"
)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,6 @@ abstract class DesktopAppController constructor(open val deskNMM: DeskNMM.DeskRu
suspend fun quit(mmid: String) {
deskNMM.nativeFetch("file://desk.browser.dweb/closeApp?app_id=$mmid")
}

suspend fun search(words: String) {
deskNMM.nativeFetch("file://web.browser.dweb/search?q=$words")
}

suspend fun openWebLink(url: String) {
deskNMM.nativeFetch("file://web.browser.dweb/openinbrowser?url=$url")
}
}


Expand Down Expand Up @@ -103,6 +95,10 @@ open class DesktopController private constructor(
webLinkStore.delete(id)
return true
}

suspend fun openWebLink(url: String) {
deskNMM.nativeFetch("file://web.browser.dweb/openinbrowser?url=$url")
}
// 针对 WebLink 的管理部分 end

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down Expand Up @@ -231,6 +227,10 @@ open class DesktopController private constructor(
// TODO: 分享
}

suspend fun search(words: String) {
deskNMM.nativeFetch("file://web.browser.dweb/search?q=$words")
}

suspend fun isSystemApp(mmid: String) =
!deskNMM.nativeFetch("file://jmm.browser.dweb/isInstalled?app_id=$mmid").boolean()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.dweb_browser.browser.desk

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloat
Expand All @@ -16,6 +17,7 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -25,6 +27,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.safeGestures
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
Expand All @@ -39,8 +42,11 @@ import androidx.compose.material.icons.outlined.Description
import androidx.compose.material.icons.outlined.HighlightOff
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
Expand Down Expand Up @@ -99,7 +105,6 @@ import org.dweb_browser.helper.compose.clickableWithNoEffect
import org.dweb_browser.helper.compose.div
import org.dweb_browser.helper.compose.iosTween
import org.dweb_browser.helper.randomUUID
import org.dweb_browser.helper.toJsonElement
import org.dweb_browser.pure.image.compose.ImageLoadResult
import org.dweb_browser.pure.image.compose.PureImageLoader
import org.dweb_browser.pure.image.compose.SmartLoad
Expand All @@ -108,6 +113,7 @@ import org.dweb_browser.sys.window.core.helper.toStrict
import org.dweb_browser.sys.window.render.AppIcon
import org.dweb_browser.sys.window.render.blobFetchHook

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NewDesktopView(
desktopController: DesktopController,
Expand All @@ -116,6 +122,8 @@ fun NewDesktopView(
val apps = remember { mutableStateListOf<DesktopAppModel>() }

var popUpApp by remember { mutableStateOf<DesktopAppModel?>(null) }
var showMoreMenu by remember { mutableStateOf(false) }
var showDeleteDialog by remember { mutableStateOf(false) }

val scope = rememberCoroutineScope()

Expand Down Expand Up @@ -151,7 +159,10 @@ fun NewDesktopView(
oldApp?.copy(running = runStatus) ?: DesktopAppModel(
it.short_name.ifEmpty { it.name },
it.mmid,
if (isWebLink) DesktopAppData.WebLink(mmid = it.mmid, url = it.name) else DesktopAppData.App(mmid = it.mmid),
if (isWebLink) DesktopAppData.WebLink(
mmid = it.mmid,
url = it.name
) else DesktopAppData.App(mmid = it.mmid),
icon,
isSystemApp,
runStatus,
Expand Down Expand Up @@ -206,6 +217,7 @@ fun NewDesktopView(
desktopController.open(mmid)
}
}

is DesktopAppData.WebLink -> {
scope.launch {
desktopController.openWebLink(oldApp.data.url)
Expand Down Expand Up @@ -233,9 +245,11 @@ fun NewDesktopView(
}
}

fun doDelete(mmid: String) {
//TODO: 后期优化
doUninstall(mmid)

fun doWebLinkDelete(mmid: String) {
scope.launch {
desktopController.removeWebLink(mmid)
}
}

fun doShare(mmid: String) {
Expand All @@ -253,10 +267,13 @@ fun NewDesktopView(
fun doShowPopUp(index: Int) {
popUpApp = apps.getOrNull(index)?.also {
doHaptics()
showMoreMenu = true
}
}

fun doHidePopUp() {
showMoreMenu = false
showDeleteDialog = false
popUpApp = null
}

Expand Down Expand Up @@ -316,69 +333,126 @@ fun NewDesktopView(
}
}


val iconScale by animateFloatAsState(
if (popUpApp != null) 1.05f else 1f, animationSpec = iosTween(popUpApp != null)
)
val iconContainerAlpha by animateFloatAsState(
if (popUpApp != null) 0.8f else 0.2f, animationSpec = iosTween(popUpApp != null)
)
popUpApp?.also { app ->
BoxWithConstraints(
Modifier.zIndex(2f).fillMaxSize().clickableWithNoEffect {
doHidePopUp()
}, Alignment.TopStart
) {

DeskAppIcon(
app,
microModule,
containerAlpha = iconContainerAlpha,
modifier = Modifier.requiredSize(app.size.width.dp, app.size.height.dp).offset {
app.offSet.toIntOffset(1f)
}.scale(iconScale),
)
if (showMoreMenu) {
popUpApp?.also { app ->
BoxWithConstraints(
Modifier.zIndex(2f).fillMaxSize().clickableWithNoEffect {
doHidePopUp()
}, Alignment.TopStart
) {

val moreAppDisplayModels by remember(app) {
mutableStateOf(createMoreAppDisplayModels(app))
}
DeskAppIcon(
app,
microModule,
containerAlpha = iconContainerAlpha,
modifier = Modifier.requiredSize(app.size.width.dp, app.size.height.dp).offset {
app.offSet.toIntOffset(1f)
}.scale(iconScale),
)

val itemSize = IntSize(60, 60)
val moreAppDisplayMenuWidth = moreAppDisplayModels.size * itemSize.width
val moreAppDisplayMenuHeight = itemSize.height
val density = LocalDensity.current.density
val moreAppDisplayModels by remember(app) {
mutableStateOf(createMoreAppDisplayModels(app))
}

val moreAppDisplayOffSet by remember(app.offSet, moreAppDisplayModels) {
//此处有坑:在于app.offset, app.size, 取到的数值倍数不一致。。。
val minX = app.offSet.x.toInt()
val maxY = app.offSet.y.toInt() + app.size.height * density
val minY = app.offSet.y.toInt()
val space = 5
mutableStateOf(
IntOffset(
if (minX + moreAppDisplayMenuWidth * density < constraints.maxWidth) minX else constraints.maxWidth - space - (moreAppDisplayMenuWidth * density).toInt(),
if (maxY + space + moreAppDisplayMenuHeight * density < constraints.maxHeight) maxY.toInt() + space else minY - space - (moreAppDisplayMenuHeight * density).toInt(),
val itemSize = IntSize(60, 60)
val moreAppDisplayMenuWidth = moreAppDisplayModels.size * itemSize.width
val moreAppDisplayMenuHeight = itemSize.height
val density = LocalDensity.current.density

val moreAppDisplayOffSet by remember(app.offSet, moreAppDisplayModels) {
//此处有坑:在于app.offset, app.size, 取到的数值倍数不一致。。。
val minX = app.offSet.x.toInt()
val maxY = app.offSet.y.toInt() + app.size.height * density
val minY = app.offSet.y.toInt()
val space = 5
mutableStateOf(
IntOffset(
if (minX + moreAppDisplayMenuWidth * density < constraints.maxWidth) minX else constraints.maxWidth - space - (moreAppDisplayMenuWidth * density).toInt(),
if (maxY + space + moreAppDisplayMenuHeight * density < constraints.maxHeight) maxY.toInt() + space else minY - space - (moreAppDisplayMenuHeight * density).toInt(),
)
)
)
}

moreAppItemsDisplay(moreAppDisplayModels,
Modifier.offset { moreAppDisplayOffSet }
.size(moreAppDisplayMenuWidth.dp, moreAppDisplayMenuHeight.dp),
action = { type ->
when (type) {
MoreAppModelType.OFF -> doHidePopUp().also { doQuit(app.mmid) }
MoreAppModelType.DETAIL -> doHidePopUp().also { doDetail(app.mmid) }
MoreAppModelType.SHARE -> doHidePopUp().also { doShare(app.mmid) }
MoreAppModelType.UNINSTALL, MoreAppModelType.DELETE -> {
showMoreMenu = false
showDeleteDialog = true
}
}
})
}
}
}

moreAppItemsDisplay(moreAppDisplayModels,
Modifier.offset { moreAppDisplayOffSet }
.size(moreAppDisplayMenuWidth.dp, moreAppDisplayMenuHeight.dp),
dismiss = { doHidePopUp() },
action = { type ->
when (type) {
MoreAppModelType.OFF -> doQuit(app.mmid)
MoreAppModelType.DETAIL -> doDetail(app.mmid)
MoreAppModelType.UNINSTALL -> doUninstall(app.mmid)
MoreAppModelType.DELETE -> doDelete(app.mmid)
MoreAppModelType.SHARE -> doShare(app.mmid)
AnimatedVisibility(showDeleteDialog) {
popUpApp?.let { app ->
DeleteAlert(app, microModule, onDismissRequest = ::doHidePopUp, confirm = {
doHidePopUp().also {
when (app.data) {
is DesktopAppData.App -> doUninstall(app.mmid)
is DesktopAppData.WebLink -> doWebLinkDelete(app.mmid)
}
})
}
})
}
}
}

private typealias AppItemAction = (String) -> Unit
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun DeleteAlert(
app: DesktopAppModel,
microModule: NativeMicroModule.NativeRuntime,
onDismissRequest: () -> Unit,
confirm: () -> Unit
) {
BasicAlertDialog(
onDismissRequest = onDismissRequest
) {
Column(
Modifier
.clip(RoundedCornerShape(10))
.background(Color.White.copy(alpha = 0.8f))
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {

DeskAppIcon(app, microModule, containerAlpha = 1f)

when (app.data) {
is DesktopAppData.App -> {
Text("${BrowserI18nResource.Desktop.uninstall.text}: \"${app.name}\"", color = Color.Black)
Text(BrowserI18nResource.Desktop.uninstallAlert.text, color = Color.Black)
}

is DesktopAppData.WebLink -> {
Text("${BrowserI18nResource.Desktop.delete.text}: \"${app.name}\"", color = Color.Black)
}
}

Row {
TextButton(onDismissRequest) { Text(BrowserI18nResource.button_name_cancel.text , color = Color.Black) }
Spacer(Modifier.width(50.dp))
TextButton(confirm) { Text(BrowserI18nResource.button_name_confirm.text, color = Color.Red) }
}
}
}
}

@Composable
private fun AppItem(
Expand Down Expand Up @@ -507,7 +581,6 @@ private fun moreAppItemsDisplay(
displays: List<MoreAppModel>,
modifier: Modifier,
action: (MoreAppModelType) -> Unit,
dismiss: () -> Unit,
) {
Row(
modifier = modifier.clip(RoundedCornerShape(8.dp)).background(Color.White.copy(alpha = 0.5f)),
Expand All @@ -518,7 +591,6 @@ private fun moreAppItemsDisplay(
Column(
modifier = Modifier.padding(4.dp).fillMaxSize().weight(1f).clickable(enabled = it.enable) {
action(it.type)
dismiss()
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
Expand Down Expand Up @@ -663,6 +735,7 @@ fun desktopSearchBar(

private sealed class DesktopAppData {
abstract val mmid: String

data class App(override val mmid: String) : DesktopAppData()
data class WebLink(override val mmid: String, val url: String) : DesktopAppData()
}
Expand Down

0 comments on commit 58eb55b

Please sign in to comment.