Skip to content

Commit

Permalink
✨ Add double-click quick copy feature (#1642)
Browse files Browse the repository at this point in the history
  • Loading branch information
guiyanakuang committed Aug 10, 2024
1 parent 6779bb6 commit 1be65bf
Show file tree
Hide file tree
Showing 12 changed files with 181 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.crosspaste.ui.paste.detail

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.onClick
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
Expand Down Expand Up @@ -41,10 +42,12 @@ import com.crosspaste.utils.getDateUtils
import com.crosspaste.utils.getFileUtils
import kotlinx.coroutines.delay

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HtmlToImageDetailView(
pasteData: PasteData,
pasteHtml: PasteHtml,
onDoubleClick: () -> Unit,
) {
val current = LocalKoinApplication.current
val density = LocalDensity.current
Expand Down Expand Up @@ -94,9 +97,12 @@ fun HtmlToImageDetailView(
.fillMaxSize()
.horizontalScroll(horizontalScrollState)
.verticalScroll(verticalScrollState)
.clickable {
uiSupport.openHtml(pasteHtml.html)
},
.onClick(
onDoubleClick = onDoubleClick,
onClick = {
uiSupport.openHtml(pasteHtml.html)
},
),
) {
Image(
painter = loadData.readPainter(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crosspaste.ui.paste.detail

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.onClick
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
Expand Down Expand Up @@ -55,11 +57,12 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

@OptIn(ExperimentalComposeUiApi::class)
@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
@Composable
fun PasteFilesDetailView(
pasteData: PasteData,
pasteFiles: PasteFiles,
onDoubleClick: () -> Unit,
) {
val current = LocalKoinApplication.current
val density = LocalDensity.current
Expand Down Expand Up @@ -125,6 +128,10 @@ fun PasteFilesDetailView(
onEvent = {
hover = false
},
)
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crosspaste.ui.paste.detail

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand All @@ -15,6 +16,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.onClick
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
Expand Down Expand Up @@ -67,11 +69,12 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okio.Path

@OptIn(ExperimentalComposeUiApi::class)
@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
@Composable
fun PasteImagesDetailView(
pasteData: PasteData,
pasteFiles: PasteFiles,
onDoubleClick: () -> Unit,
) {
if (pasteFiles.count > 0) {
val current = LocalKoinApplication.current
Expand Down Expand Up @@ -138,6 +141,10 @@ fun PasteImagesDetailView(
onEvent = {
hover = false
},
)
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.crosspaste.ui.paste.detail

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.onClick
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
Expand All @@ -27,10 +29,12 @@ import com.crosspaste.paste.item.PasteText
import com.crosspaste.utils.getDateUtils
import com.crosspaste.utils.getFileUtils

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PasteTextDetailView(
pasteData: PasteData,
pasteText: PasteText,
onDoubleClick: () -> Unit,
) {
val current = LocalKoinApplication.current
val copywriter = current.koin.get<GlobalCopywriter>()
Expand All @@ -41,7 +45,15 @@ fun PasteTextDetailView(

PasteDetailView(
detailView = {
Row(modifier = Modifier.fillMaxSize().padding(10.dp)) {
Row(
modifier =
Modifier.fillMaxSize()
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
)
.padding(10.dp),
) {
Text(
text = text,
modifier =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.crosspaste.ui.paste.detail

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.onClick
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
Expand All @@ -27,10 +28,12 @@ import com.crosspaste.ui.base.UISupport
import com.crosspaste.utils.getDateUtils
import com.crosspaste.utils.getFileUtils

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PasteUrlDetailView(
pasteData: PasteData,
pasteUrl: PasteUrl,
onDoubleClick: () -> Unit,
) {
val current = LocalKoinApplication.current
val copywriter = current.koin.get<GlobalCopywriter>()
Expand All @@ -45,9 +48,13 @@ fun PasteUrlDetailView(
Row(
modifier =
Modifier.fillMaxSize()
.clickable {
uiSupport.openUrlInBrowser(pasteUrl.url)
}.padding(10.dp),
.onClick(
onDoubleClick = onDoubleClick,
onClick = {
uiSupport.openUrlInBrowser(pasteUrl.url)
},
)
.padding(10.dp),
) {
Text(
text = url,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.crosspaste.ui.paste.preview

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.onClick
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Expand All @@ -14,16 +16,27 @@ import com.crosspaste.path.UserDataPathProvider
import com.crosspaste.utils.FileExtUtils.canPreviewImage
import com.crosspaste.utils.extension

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun FilesPreviewView(pasteData: PasteData) {
fun FilesPreviewView(
pasteData: PasteData,
onDoubleClick: () -> Unit,
) {
pasteData.getPasteItem()?.let {
val current = LocalKoinApplication.current
val userDataPathProvider = current.koin.get<UserDataPathProvider>()
val pasteFilePaths = (it as PasteFiles).getFilePaths(userDataPathProvider)

PasteSpecificPreviewContentView(
pasteMainContent = {
LazyRow(modifier = Modifier.fillMaxSize()) {
LazyRow(
modifier =
Modifier.fillMaxSize()
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
),
) {
items(pasteFilePaths.size) { index ->
val filepath = pasteFilePaths[index]
if (canPreviewImage(filepath.extension)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ import com.crosspaste.image.getImageDataLoader
import com.crosspaste.paste.item.PasteHtml
import com.crosspaste.path.UserDataPathProvider
import com.crosspaste.ui.base.AsyncView
import com.crosspaste.ui.base.UISupport
import kotlinx.coroutines.delay

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HtmlToImagePreviewView(pasteData: PasteData) {
fun HtmlToImagePreviewView(
pasteData: PasteData,
onDoubleClick: () -> Unit,
) {
pasteData.getPasteItem()?.let {
val current = LocalKoinApplication.current
val density = LocalDensity.current

val uiSupport = current.koin.get<UISupport>()
val userDataPathProvider = current.koin.get<UserDataPathProvider>()
val imageDataLoader = getImageDataLoader()

Expand Down Expand Up @@ -72,9 +72,10 @@ fun HtmlToImagePreviewView(pasteData: PasteData) {
Modifier
.fillMaxSize()
.clip(RoundedCornerShape(5.dp))
.onClick {
uiSupport.openHtml(it.html)
},
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
),
) {
Image(
painter = loadData.readPainter(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.crosspaste.ui.paste.preview

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.onClick
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Expand All @@ -12,8 +14,12 @@ import com.crosspaste.dao.paste.PasteData
import com.crosspaste.paste.item.PasteFiles
import com.crosspaste.path.UserDataPathProvider

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ImagesPreviewView(pasteData: PasteData) {
fun ImagesPreviewView(
pasteData: PasteData,
onDoubleClick: () -> Unit,
) {
pasteData.getPasteItem()?.let {
val current = LocalKoinApplication.current
val userDataPathProvider = current.koin.get<UserDataPathProvider>()
Expand All @@ -23,7 +29,14 @@ fun ImagesPreviewView(pasteData: PasteData) {
PasteSpecificPreviewContentView(
pasteMainContent = {
val imagePaths = pasteFiles.getFilePaths(userDataPathProvider)
LazyRow(modifier = Modifier.fillMaxSize()) {
LazyRow(
modifier =
Modifier.fillMaxSize()
.onClick(
onDoubleClick = onDoubleClick,
onClick = {},
),
) {
items(imagePaths.size) { index ->
SingleImagePreviewView(imagePaths[index])
if (index != imagePaths.size - 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,31 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.crosspaste.LocalKoinApplication
import com.crosspaste.app.AppWindowManager
import com.crosspaste.dao.paste.PasteCollection
import com.crosspaste.dao.paste.PasteData
import com.crosspaste.dao.paste.PasteItem
import com.crosspaste.dao.paste.PasteState
import com.crosspaste.dao.paste.PasteType
import com.crosspaste.i18n.Copywriter
import com.crosspaste.i18n.GlobalCopywriter
import com.crosspaste.paste.PasteboardService
import com.crosspaste.ui.base.MessageType
import com.crosspaste.ui.base.NotificationManager
import com.crosspaste.utils.getDateUtils
import com.crosspaste.utils.ioDispatcher
import com.crosspaste.utils.mainDispatcher
import io.realm.kotlin.types.RealmInstant
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.reflect.KClass
import kotlin.reflect.cast

Expand Down Expand Up @@ -92,12 +103,35 @@ fun PasteSpecificPreviewView(pasteData: PasteData) {
if (pasteData.pasteState == PasteState.LOADING) {
PrePreviewView(pasteData)
} else {
val current = LocalKoinApplication.current
val appWindowManager = current.koin.get<AppWindowManager>()
val copywriter = current.koin.get<GlobalCopywriter>()
val pasteboardService = current.koin.get<PasteboardService>()
val notificationManager = current.koin.get<NotificationManager>()
val scope = rememberCoroutineScope()
val onDoubleClick: () -> Unit = {
appWindowManager.setMainCursorWait()
scope.launch(ioDispatcher) {
pasteboardService.tryWritePasteboard(
pasteData,
localOnly = true,
filterFile = false,
)
withContext(mainDispatcher) {
appWindowManager.resetMainCursor()
notificationManager.addNotification(
copywriter.getText("copy_successful"),
MessageType.Success,
)
}
}
}
when (pasteData.pasteType) {
PasteType.TEXT -> TextPreviewView(pasteData)
PasteType.URL -> UrlPreviewView(pasteData)
PasteType.HTML -> HtmlToImagePreviewView(pasteData)
PasteType.IMAGE -> ImagesPreviewView(pasteData)
PasteType.FILE -> FilesPreviewView(pasteData)
PasteType.TEXT -> TextPreviewView(pasteData, onDoubleClick)
PasteType.URL -> UrlPreviewView(pasteData, onDoubleClick)
PasteType.HTML -> HtmlToImagePreviewView(pasteData, onDoubleClick)
PasteType.IMAGE -> ImagesPreviewView(pasteData, onDoubleClick)
PasteType.FILE -> FilesPreviewView(pasteData, onDoubleClick)
}
}
}
Expand Down
Loading

0 comments on commit 1be65bf

Please sign in to comment.