diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/app/AppFileType.kt b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppFileType.kt new file mode 100644 index 000000000..0d978abc4 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppFileType.kt @@ -0,0 +1,8 @@ +package com.clipevery.app + +enum class AppFileType { + USER, + LOG, + ENCRYPT, + DATA, +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfo.kt similarity index 87% rename from composeApp/src/commonMain/kotlin/com/clipevery/model/AppInfo.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfo.kt index a4019f97e..5a01d77b8 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppInfo.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfo.kt @@ -1,4 +1,4 @@ -package com.clipevery.model +package com.clipevery.app import kotlinx.serialization.Serializable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/AppInfoFactory.kt b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfoFactory.kt similarity index 51% rename from composeApp/src/commonMain/kotlin/com/clipevery/AppInfoFactory.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfoFactory.kt index 0c0a6cf80..56da9e2dc 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/AppInfoFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppInfoFactory.kt @@ -1,6 +1,4 @@ -package com.clipevery - -import com.clipevery.model.AppInfo +package com.clipevery.app interface AppInfoFactory { fun createAppInfo(): AppInfo diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppUI.kt b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppUI.kt similarity index 75% rename from composeApp/src/commonMain/kotlin/com/clipevery/model/AppUI.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/app/AppUI.kt index fe4e7f802..2c2790514 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppUI.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppUI.kt @@ -1,4 +1,4 @@ -package com.clipevery.model +package com.clipevery.app import androidx.compose.ui.unit.Dp diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItem.kt index b7a7bfaaa..305d3eb1b 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.datatransfer.Transferable interface ClipItem { diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/ClipItemType.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItemType.kt similarity index 79% rename from composeApp/src/commonMain/kotlin/com/clipevery/clip/ClipItemType.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItemType.kt index af1129c2b..0bb9cda08 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/ClipItemType.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ClipItemType.kt @@ -1,4 +1,4 @@ -package com.clipevery.clip +package com.clipevery.clip.item enum class ClipItemType { Text, diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FileClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FileClipItem.kt index a94444a14..edd43d145 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FileClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FileClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable import java.io.File diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FilesClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FilesClipItem.kt index efc59d94f..fd2e95dfc 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FilesClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/FilesClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable import java.io.File diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/HtmlTextClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/HtmlTextClipItem.kt index 8c6a5bdb6..35c49aef8 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/HtmlTextClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/HtmlTextClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageClipItem.kt index 2f5412b4e..65b8421b7 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.Image import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageFileClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageFileClipItem.kt index 7f48c6b8b..f6d64a145 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageFileClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/ImageFileClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.Image import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/TextClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/TextClipItem.kt index 43eb6251a..ba38434a5 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/TextClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/TextClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/UrlClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/UrlClipItem.kt index ad2df246e..31aaa122b 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/UrlClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/UrlClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.net.URL class UrlClipItem(override val url: URL): TextClipItem(url.toString()), ClipUrl { diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/VideoFileClipItem.kt b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/VideoFileClipItem.kt index 3e80ae8da..258e908ff 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/VideoFileClipItem.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/clip/item/VideoFileClipItem.kt @@ -1,6 +1,5 @@ package com.clipevery.clip.item -import com.clipevery.clip.ClipItemType import java.io.File val SUPPORT_VIDEO_EXTENSIONS = setOf("mp4", "avi", "mov", "mkv", "flv", "wmv") diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppConfig.kt b/composeApp/src/commonMain/kotlin/com/clipevery/config/AppConfig.kt similarity index 92% rename from composeApp/src/commonMain/kotlin/com/clipevery/model/AppConfig.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/config/AppConfig.kt index 7a9310680..5a879b1c8 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/AppConfig.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/config/AppConfig.kt @@ -1,4 +1,4 @@ -package com.clipevery.model +package com.clipevery.config import kotlinx.serialization.Serializable import java.util.Locale diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/config/ConfigManager.kt b/composeApp/src/commonMain/kotlin/com/clipevery/config/ConfigManager.kt index b9b0e1e98..400f99e31 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/config/ConfigManager.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/config/ConfigManager.kt @@ -1,6 +1,5 @@ package com.clipevery.config -import com.clipevery.model.AppConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/config/FileType.kt b/composeApp/src/commonMain/kotlin/com/clipevery/config/FileType.kt deleted file mode 100644 index b27821f23..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/config/FileType.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.clipevery.config - -enum class FileType { - USER, - LOG, - ENCRYPT, - DATA, -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/device/DeviceInfoFactory.kt b/composeApp/src/commonMain/kotlin/com/clipevery/device/DeviceInfoFactory.kt deleted file mode 100644 index 88e28dac7..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/device/DeviceInfoFactory.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.clipevery.device - -import com.clipevery.model.DeviceInfo - -interface DeviceInfoFactory { - - fun createDeviceInfo(): DeviceInfo -} diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfo.kt new file mode 100644 index 000000000..c5bdd8471 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfo.kt @@ -0,0 +1,19 @@ +package com.clipevery.endpoint + +import com.clipevery.net.HostInfo +import com.clipevery.platform.Platform +import kotlinx.serialization.Serializable + +@Serializable +data class EndpointInfo(val deviceId: String, + val deviceName: String, + val platform: Platform, + val hostInfoList: List, + val port: Int) + +data class ExplicitEndpointInfo(val deviceId: String, + val deviceName: String, + val platform: Platform, + val hostInfo: HostInfo, + val port: Int) + diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfoFactory.kt b/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfoFactory.kt new file mode 100644 index 000000000..55779e383 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/clipevery/endpoint/EndpointInfoFactory.kt @@ -0,0 +1,6 @@ +package com.clipevery.endpoint + +interface EndpointInfoFactory { + + fun createEndpointInfo(): EndpointInfo +} diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/DeviceInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/DeviceInfo.kt deleted file mode 100644 index 52fdaf66e..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/DeviceInfo.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.clipevery.model - -import com.clipevery.platform.Platform -import kotlinx.serialization.Serializable - -@Serializable -data class DeviceInfo(val deviceId: String, - val deviceName: String, - val platform: Platform, - val hostInfoList: List) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/EndpointInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/EndpointInfo.kt deleted file mode 100644 index b0f3daf27..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/EndpointInfo.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.clipevery.model - -import com.clipevery.platform.Platform - -data class EndpointInfo(val deviceId: String, - val deviceName: String, - val platform: Platform, - val hostInfo: HostInfo, - val port: Int) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/RequestEndpointInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/RequestEndpointInfo.kt deleted file mode 100644 index df9a2f219..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/RequestEndpointInfo.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.clipevery.model - -import com.clipevery.encrypt.base64Encode -import kotlinx.serialization.Serializable -import java.io.ByteArrayOutputStream -import java.io.DataOutputStream - -@Serializable -data class RequestEndpointInfo(val deviceInfo: DeviceInfo, - val port: Int) { - - fun getBase64Encode(token: Int): String { - val byteStream = ByteArrayOutputStream() - val dataStream = DataOutputStream(byteStream) - encodeDeviceInfo(dataStream) - dataStream.writeInt(port) - val byteArray = byteStream.toByteArray() - val size = byteArray.size - val offset = token % size - val byteArrayRotate = byteArray.rotate(offset) - val saltByteStream = ByteArrayOutputStream() - val saltDataStream = DataOutputStream(saltByteStream) - saltDataStream.write(byteArrayRotate) - saltDataStream.writeInt(token) - return base64Encode(saltByteStream.toByteArray()) - } - - private fun encodeDeviceInfo(dataOutputStream: DataOutputStream) { - dataOutputStream.writeUTF(deviceInfo.deviceId) - dataOutputStream.writeUTF(deviceInfo.deviceName) - encodePlatform(dataOutputStream) - dataOutputStream.writeInt(deviceInfo.hostInfoList.size) - deviceInfo.hostInfoList.forEach { - dataOutputStream.writeUTF(it.displayName) - dataOutputStream.writeUTF(it.hostAddress) - } - } - - private fun encodePlatform(dataOutputStream: DataOutputStream) { - dataOutputStream.writeUTF(deviceInfo.platform.name) - dataOutputStream.writeUTF(deviceInfo.platform.arch) - dataOutputStream.writeInt(deviceInfo.platform.bitMode) - dataOutputStream.writeUTF(deviceInfo.platform.version) - } - - private fun ByteArray.rotate(offset: Int): ByteArray { - val effectiveOffset = offset % size - if (effectiveOffset == 0 || this.isEmpty()) { - return this.copyOf() // 如果偏移量为0或数组为空,则直接返回原数组的副本 - } - - val result = ByteArray(this.size) - for (i in this.indices) { - val newPosition = (i + effectiveOffset + this.size) % this.size - result[newPosition] = this[i] - } - return result - } -} diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/SyncInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/SyncInfo.kt deleted file mode 100644 index a6c080810..000000000 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/SyncInfo.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.clipevery.model - -data class SyncInfo( - val appInfo: AppInfo, - val endpointInfo: EndpointInfo, - val state: SyncState -) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/RequestSyncInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/RequestSyncInfo.kt index 73ffed4a9..1a723424f 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/RequestSyncInfo.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/RequestSyncInfo.kt @@ -1,12 +1,12 @@ package com.clipevery.model.sync -import com.clipevery.model.AppInfo -import com.clipevery.model.RequestEndpointInfo +import com.clipevery.app.AppInfo +import com.clipevery.endpoint.EndpointInfo import kotlinx.serialization.Serializable @Serializable data class RequestSyncInfo(val appInfo: AppInfo, - val requestEndpointInfo: RequestEndpointInfo, + val endpointInfo: EndpointInfo, val preKeyBundle: ByteArray, val token: Int) { override fun equals(other: Any?): Boolean { @@ -16,7 +16,7 @@ data class RequestSyncInfo(val appInfo: AppInfo, other as RequestSyncInfo if (appInfo != other.appInfo) return false - if (requestEndpointInfo != other.requestEndpointInfo) return false + if (endpointInfo != other.endpointInfo) return false if (!preKeyBundle.contentEquals(other.preKeyBundle)) return false if (token != other.token) return false @@ -25,7 +25,7 @@ data class RequestSyncInfo(val appInfo: AppInfo, override fun hashCode(): Int { var result = appInfo.hashCode() - result = 31 * result + requestEndpointInfo.hashCode() + result = 31 * result + endpointInfo.hashCode() result = 31 * result + preKeyBundle.contentHashCode() result = 31 * result + token return result diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/ResponseSyncInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/ResponseSyncInfo.kt index e91918056..56aba4fac 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/ResponseSyncInfo.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/ResponseSyncInfo.kt @@ -1,8 +1,8 @@ package com.clipevery.model.sync -import com.clipevery.model.AppInfo -import com.clipevery.model.RequestEndpointInfo +import com.clipevery.app.AppInfo +import com.clipevery.endpoint.EndpointInfo data class ResponseSyncInfo(val appInfo: AppInfo, - val requestEndpointInfo: RequestEndpointInfo + val endpointInfo: EndpointInfo ) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncInfo.kt new file mode 100644 index 000000000..45bef08c7 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncInfo.kt @@ -0,0 +1,10 @@ +package com.clipevery.model.sync + +import com.clipevery.app.AppInfo +import com.clipevery.endpoint.ExplicitEndpointInfo + +data class SyncInfo( + val appInfo: AppInfo, + val endpointInfo: ExplicitEndpointInfo, + val state: SyncState +) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/SyncState.kt b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncState.kt similarity index 66% rename from composeApp/src/commonMain/kotlin/com/clipevery/model/SyncState.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncState.kt index 21bfb84a8..8a87cf833 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/SyncState.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/model/sync/SyncState.kt @@ -1,4 +1,4 @@ -package com.clipevery.model +package com.clipevery.model.sync enum class SyncState { ONLINE, diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/model/HostInfo.kt b/composeApp/src/commonMain/kotlin/com/clipevery/net/HostInfo.kt similarity index 83% rename from composeApp/src/commonMain/kotlin/com/clipevery/model/HostInfo.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/net/HostInfo.kt index 0950b29cd..ccffda33f 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/model/HostInfo.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/net/HostInfo.kt @@ -1,4 +1,4 @@ -package com.clipevery.model +package com.clipevery.net import kotlinx.serialization.Serializable diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/net/SyncValidator.kt b/composeApp/src/commonMain/kotlin/com/clipevery/net/SyncValidator.kt index 5db2a59eb..b152bd83d 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/net/SyncValidator.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/net/SyncValidator.kt @@ -1,7 +1,7 @@ package com.clipevery.net import com.clipevery.exception.ClipException -import com.clipevery.model.SyncInfo +import com.clipevery.model.sync.SyncInfo import com.clipevery.model.sync.RequestSyncInfo import org.signal.libsignal.protocol.state.PreKeyBundle diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/path/PathProvider.kt b/composeApp/src/commonMain/kotlin/com/clipevery/path/PathProvider.kt index 6df3227b0..aac64a894 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/path/PathProvider.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/path/PathProvider.kt @@ -1,15 +1,15 @@ package com.clipevery.path -import com.clipevery.config.FileType +import com.clipevery.app.AppFileType import java.nio.file.Path interface PathProvider { - fun resolve(fileName: String?, fileType: FileType): Path { - val path = when (fileType) { - FileType.USER -> clipUserPath - FileType.LOG -> clipLogPath.resolve("logs") - FileType.ENCRYPT -> clipEncryptPath.resolve("encrypt") - FileType.DATA -> clipDataPath.resolve("data") + fun resolve(fileName: String?, appFileType: AppFileType): Path { + val path = when (appFileType) { + AppFileType.USER -> clipUserPath + AppFileType.LOG -> clipLogPath.resolve("logs") + AppFileType.ENCRYPT -> clipEncryptPath.resolve("encrypt") + AppFileType.DATA -> clipDataPath.resolve("data") } if (!path.toFile().exists()) { diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/presist/FilePersist.kt b/composeApp/src/commonMain/kotlin/com/clipevery/presist/FilePersist.kt index c23b2a1b8..3733ae7e5 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/presist/FilePersist.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/presist/FilePersist.kt @@ -1,6 +1,6 @@ package com.clipevery.presist -import com.clipevery.config.FileType +import com.clipevery.app.AppFileType import com.clipevery.path.PathProvider import java.nio.file.Path @@ -8,8 +8,8 @@ interface FilePersist { val pathProvider: PathProvider - fun getPersist(configName: String, fileType: FileType): OneFilePersist { - return createOneFilePersist(pathProvider.resolve(configName, fileType)) + fun getPersist(configName: String, appFileType: AppFileType): OneFilePersist { + return createOneFilePersist(pathProvider.resolve(configName, appFileType)) } fun createOneFilePersist(path: Path): OneFilePersist diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/dao/store/IdentityKeyStoreFactory.kt b/composeApp/src/commonMain/kotlin/com/clipevery/signal/IdentityKeyStoreFactory.kt similarity index 82% rename from composeApp/src/commonMain/kotlin/com/clipevery/dao/store/IdentityKeyStoreFactory.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/signal/IdentityKeyStoreFactory.kt index 5861bc2cc..ff22382dc 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/dao/store/IdentityKeyStoreFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/signal/IdentityKeyStoreFactory.kt @@ -1,4 +1,4 @@ -package com.clipevery.dao.store +package com.clipevery.signal import org.signal.libsignal.protocol.state.IdentityKeyStore diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncItemUI.kt b/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncItemUI.kt index a92646b80..aaa63fc5b 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncItemUI.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncItemUI.kt @@ -40,8 +40,8 @@ import androidx.compose.ui.unit.sp import com.clipevery.LocalKoinApplication import com.clipevery.i18n.Copywriter import com.clipevery.i18n.GlobalCopywriter -import com.clipevery.model.SyncInfo -import com.clipevery.model.SyncState +import com.clipevery.model.sync.SyncInfo +import com.clipevery.model.sync.SyncState import compose.icons.TablerIcons import compose.icons.tablericons.Ghost diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncUI.kt b/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncUI.kt index 580b4f65e..9a197ca49 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncUI.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/ui/SyncUI.kt @@ -8,27 +8,28 @@ import androidx.compose.material.Divider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.clipevery.LocalKoinApplication -import com.clipevery.device.DeviceInfoFactory -import com.clipevery.model.HostInfo -import com.clipevery.model.AppInfo -import com.clipevery.model.EndpointInfo -import com.clipevery.model.SyncInfo -import com.clipevery.model.SyncState +import com.clipevery.endpoint.EndpointInfoFactory +import com.clipevery.net.HostInfo +import com.clipevery.app.AppInfo +import com.clipevery.endpoint.ExplicitEndpointInfo +import com.clipevery.model.sync.SyncInfo +import com.clipevery.model.sync.SyncState import com.clipevery.platform.Platform import com.clipevery.platform.currentPlatform @Composable fun Syncs() { val current = LocalKoinApplication.current - val deviceFactory = current.koin.get() - val deviceInfo = deviceFactory.createDeviceInfo() - SyncItem(SyncInfo( + val deviceFactory = current.koin.get() + val deviceInfo = deviceFactory.createEndpointInfo() + SyncItem( + SyncInfo( appInfo = AppInfo( appInstanceId = "1234567890", appVersion = "1.0.0", userName = "John Doe" ), - endpointInfo = EndpointInfo( + endpointInfo = ExplicitEndpointInfo( deviceId = deviceInfo.deviceId, deviceName = deviceInfo.deviceName, platform = currentPlatform(), @@ -38,13 +39,14 @@ fun Syncs() { state = SyncState.ONLINE) ) Divider(modifier = Modifier.fillMaxWidth()) - SyncItem(SyncInfo( + SyncItem( + SyncInfo( appInfo = AppInfo( appInstanceId = "1234567890", appVersion = "1.0.0", userName = "John Doe" ), - endpointInfo = EndpointInfo( + endpointInfo = ExplicitEndpointInfo( deviceId = "abdcs-adasda-sdasdasd", deviceName = "John Doe's Windows", platform = object: Platform { @@ -63,13 +65,14 @@ fun Syncs() { state = SyncState.OFFLINE) ) Divider(modifier = Modifier.fillMaxWidth()) - SyncItem(SyncInfo( + SyncItem( + SyncInfo( appInfo = AppInfo( appInstanceId = "1234567890", appVersion = "1.0.0", userName = "John Doe" ), - endpointInfo = EndpointInfo( + endpointInfo = ExplicitEndpointInfo( deviceId = "abdcs-adasda-sdasdasd", deviceName = "John Doe's Windows", hostInfo = HostInfo( diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/encrypt/EncryptUtils.kt b/composeApp/src/commonMain/kotlin/com/clipevery/utils/EncryptUtils.kt similarity index 98% rename from composeApp/src/commonMain/kotlin/com/clipevery/encrypt/EncryptUtils.kt rename to composeApp/src/commonMain/kotlin/com/clipevery/utils/EncryptUtils.kt index d09ed084f..0ffd95d21 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/encrypt/EncryptUtils.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/utils/EncryptUtils.kt @@ -1,4 +1,4 @@ -package com.clipevery.encrypt +package com.clipevery.utils import java.security.SecureRandom import java.util.Base64 diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/model/DesktopAppInfoFactory.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/app/DesktopAppInfoFactory.kt similarity index 96% rename from composeApp/src/desktopMain/kotlin/com/clipevery/model/DesktopAppInfoFactory.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/app/DesktopAppInfoFactory.kt index 62c2ae850..f51990fc5 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/model/DesktopAppInfoFactory.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/app/DesktopAppInfoFactory.kt @@ -1,6 +1,5 @@ -package com.clipevery.model +package com.clipevery.app -import com.clipevery.AppInfoFactory import com.clipevery.config.ConfigManager import com.clipevery.platform.currentPlatform import io.github.oshai.kotlinlogging.KotlinLogging diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopClipboardService.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopClipboardService.kt index de178ade7..240c44767 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopClipboardService.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopClipboardService.kt @@ -1,8 +1,8 @@ package com.clipevery.clip -import com.clipevery.macos.MacosClipboardService +import com.clipevery.os.macos.MacosClipboardService import com.clipevery.platform.currentPlatform -import com.clipevery.windows.WindowsClipboardService +import com.clipevery.os.windows.WindowsClipboardService fun getDesktopClipboardService(clipConsumer: TransferableConsumer): ClipboardService { val currentPlatform = currentPlatform() diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopTransferableConsumer.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopTransferableConsumer.kt index c3968ce5d..2f0763462 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopTransferableConsumer.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/DesktopTransferableConsumer.kt @@ -1,6 +1,7 @@ package com.clipevery.clip import com.clipevery.clip.item.ClipItem +import com.clipevery.clip.item.ClipItemType import com.clipevery.clip.item.FileClipItem import com.clipevery.clip.item.FilesClipItem import com.clipevery.clip.item.HtmlTextClipItem diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/PlatformClipboard.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/PlatformClipboard.kt similarity index 68% rename from composeApp/src/desktopMain/kotlin/com/clipevery/PlatformClipboard.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/clip/PlatformClipboard.kt index 80bdb4dab..57b5f8659 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/PlatformClipboard.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/clip/PlatformClipboard.kt @@ -1,10 +1,8 @@ -package com.clipevery +package com.clipevery.clip -import com.clipevery.clip.ClipboardService -import com.clipevery.clip.TransferableConsumer -import com.clipevery.macos.MacosClipboardService +import com.clipevery.os.macos.MacosClipboardService +import com.clipevery.os.windows.WindowsClipboardService import com.clipevery.platform.currentPlatform -import com.clipevery.windows.WindowsClipboardService fun getClipboard(clipConsumer: TransferableConsumer): ClipboardService { val platform = currentPlatform() diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/config/DefaultConfigManager.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/config/DefaultConfigManager.kt index dfe499747..e96d5c3ba 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/config/DefaultConfigManager.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/config/DefaultConfigManager.kt @@ -1,6 +1,6 @@ package com.clipevery.config -import com.clipevery.model.AppConfig +import com.clipevery.app.AppFileType import com.clipevery.presist.FilePersist import kotlinx.coroutines.CoroutineScope import org.koin.core.component.KoinComponent @@ -10,7 +10,7 @@ class DefaultConfigManager(ioScope: CoroutineScope) : ConfigManager(ioScope), Ko private val filePersist: FilePersist by inject() - private val configFilePersist = filePersist.getPersist("appConfig.json", FileType.USER) + private val configFilePersist = filePersist.getPersist("appConfig.json", AppFileType.USER) override fun loadConfig(): AppConfig? { return configFilePersist.read(AppConfig::class) diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/controller/SyncController.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/controller/SyncController.kt index 0b8de185f..b538b1dd8 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/controller/SyncController.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/controller/SyncController.kt @@ -1,18 +1,16 @@ package com.clipevery.controller +import com.clipevery.app.AppInfo import com.clipevery.dao.SyncDao -import com.clipevery.device.DeviceInfoFactory -import com.clipevery.encrypt.decodePreKeyBundle +import com.clipevery.utils.decodePreKeyBundle +import com.clipevery.endpoint.EndpointInfoFactory +import com.clipevery.endpoint.ExplicitEndpointInfo import com.clipevery.exception.ClipException import com.clipevery.exception.StandardErrorCode -import com.clipevery.model.AppInfo -import com.clipevery.model.EndpointInfo -import com.clipevery.model.RequestEndpointInfo -import com.clipevery.model.SyncInfo -import com.clipevery.model.SyncState +import com.clipevery.model.sync.SyncInfo import com.clipevery.model.sync.RequestSyncInfo import com.clipevery.model.sync.ResponseSyncInfo -import com.clipevery.net.ClipServer +import com.clipevery.model.sync.SyncState import com.clipevery.net.SyncInfoWithPreKeyBundle import com.clipevery.net.SyncValidator import com.clipevery.utils.telnet @@ -33,8 +31,7 @@ class SyncController(private val appInfo: AppInfo, private val preKeyStore: PreKeyStore, private val signedPreKeyStore: SignedPreKeyStore, private val identityKeyStore: IdentityKeyStore, - private val clipServer: Lazy, - private val deviceInfoFactory: DeviceInfoFactory): SyncValidator { + private val endpointInfoFactory: EndpointInfoFactory): SyncValidator { fun receiveEndpointSyncInfo(requestSyncInfo: RequestSyncInfo): ResponseSyncInfo { val (syncInfo, preKeyBundle) = runBlocking { validate(requestSyncInfo) } @@ -44,7 +41,7 @@ class SyncController(private val appInfo: AppInfo, syncDao.saveSyncEndpoint(syncInfo) sessionBuilder.process(preKeyBundle) } - return ResponseSyncInfo(appInfo, RequestEndpointInfo(deviceInfoFactory.createDeviceInfo(), clipServer.value.port())) + return ResponseSyncInfo(appInfo, endpointInfoFactory.createEndpointInfo()) } private var token: Int? = null @@ -72,13 +69,13 @@ class SyncController(private val appInfo: AppInfo, } else if (requestSyncInfo.token != this.token) { throw ClipException(StandardErrorCode.SYNC_INVALID.toErrorCode(), "token invalid") } - val hostInfoList = requestSyncInfo.requestEndpointInfo.deviceInfo.hostInfoList + val hostInfoList = requestSyncInfo.endpointInfo.hostInfoList if (hostInfoList.isEmpty()) { throw ClipException(StandardErrorCode.SYNC_INVALID.toErrorCode(), "cant find host info") } val host: String = telnet( - requestSyncInfo.requestEndpointInfo.deviceInfo.hostInfoList.map { hostInfo -> hostInfo.hostAddress }, - requestSyncInfo.requestEndpointInfo.port, 1000 + requestSyncInfo.endpointInfo.hostInfoList.map { hostInfo -> hostInfo.hostAddress }, + requestSyncInfo.endpointInfo.port, 1000 ) ?: throw ClipException(StandardErrorCode.SYNC_INVALID.toErrorCode(), "cant find telnet success host") val hostInfo = hostInfoList.find { hostInfo -> hostInfo.hostAddress == host }!! @@ -94,11 +91,11 @@ class SyncController(private val appInfo: AppInfo, val appInfo = requestSyncInfo.appInfo - val endpointInfo = EndpointInfo( - requestSyncInfo.requestEndpointInfo.deviceInfo.deviceId, - requestSyncInfo.requestEndpointInfo.deviceInfo.deviceName, - requestSyncInfo.requestEndpointInfo.deviceInfo.platform, - hostInfo, requestSyncInfo.requestEndpointInfo.port + val endpointInfo = ExplicitEndpointInfo( + requestSyncInfo.endpointInfo.deviceId, + requestSyncInfo.endpointInfo.deviceName, + requestSyncInfo.endpointInfo.platform, + hostInfo, requestSyncInfo.endpointInfo.port ) return SyncInfoWithPreKeyBundle(SyncInfo(appInfo, endpointInfo, SyncState.ONLINE), preKeyBundle) diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/DriverFactory.desktop.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/dao/DriverFactory.desktop.kt index bd00955bb..9f5139b27 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/DriverFactory.desktop.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/dao/DriverFactory.desktop.kt @@ -3,13 +3,13 @@ package com.clipevery.dao import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import com.clipevery.Database -import com.clipevery.config.FileType +import com.clipevery.app.AppFileType import com.clipevery.path.getPathProvider import java.nio.file.Path actual class DriverFactory { - private val dbFilePath: Path = getPathProvider().resolve("clipevery.db", FileType.DATA) + private val dbFilePath: Path = getPathProvider().resolve("clipevery.db", AppFileType.DATA) actual fun createDriver(): SqlDriver { val driver: SqlDriver = JdbcSqliteDriver("jdbc:sqlite:${dbFilePath.toAbsolutePath()}") diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/SyncDao.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/dao/SyncDao.kt index 383c52286..204777fcc 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/SyncDao.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/dao/SyncDao.kt @@ -1,7 +1,7 @@ package com.clipevery.dao import com.clipevery.Database -import com.clipevery.model.SyncInfo +import com.clipevery.model.sync.SyncInfo class SyncDao(val database: Database) { diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/device/DesktopDeviceInfoFactory.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/endpoint/DesktopEndpointInfoFactory.kt similarity index 73% rename from composeApp/src/desktopMain/kotlin/com/clipevery/device/DesktopDeviceInfoFactory.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/endpoint/DesktopEndpointInfoFactory.kt index ae88e5b1a..29ee6982e 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/device/DesktopDeviceInfoFactory.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/endpoint/DesktopEndpointInfoFactory.kt @@ -1,8 +1,8 @@ -package com.clipevery.device +package com.clipevery.endpoint -import com.clipevery.macos.api.MacosApi -import com.clipevery.model.DeviceInfo -import com.clipevery.model.HostInfo +import com.clipevery.os.macos.api.MacosApi +import com.clipevery.net.ClipServer +import com.clipevery.net.HostInfo import com.clipevery.platform.Platform import com.clipevery.platform.currentPlatform import com.sun.jna.platform.win32.Kernel32Util @@ -12,38 +12,41 @@ import java.io.InputStreamReader import java.net.NetworkInterface import java.util.Collections -class DesktopDeviceInfoFactory: DeviceInfoFactory { - override fun createDeviceInfo(): DeviceInfo { +class DesktopEndpointInfoFactory(private val clipServer: Lazy): EndpointInfoFactory { + override fun createEndpointInfo(): EndpointInfo { val platform = currentPlatform() + val port = clipServer.value.port() return if (platform.isMacos()) { - getMacDeviceInfo(platform) + getMacEndpointInfo(port, platform) } else if (platform.isWindows()) { - getWindowDeviceInfo(platform) + getWindowEndpointInfo(port, platform) } else { throw IllegalStateException("Unsupported platform: $platform") } } } -private fun getMacDeviceInfo(platform: Platform): DeviceInfo { +private fun getMacEndpointInfo(port: Int, platform: Platform): EndpointInfo { val deviceName = MacosApi.INSTANCE.getComputerName() ?: "Unknown" val deviceId = MacosApi.INSTANCE.getHardwareUUID() ?: "Unknown" - return DeviceInfo( + return EndpointInfo( deviceId = deviceId, deviceName = deviceName, platform = platform, - hostInfoList = getHostInfoList() + hostInfoList = getHostInfoList(), + port = port ) } -private fun getWindowDeviceInfo(platform: Platform): DeviceInfo { +private fun getWindowEndpointInfo(port: Int, platform: Platform): EndpointInfo { val deviceName = Kernel32Util.getComputerName() val deviceId = getWindowDeviceId() - return DeviceInfo( + return EndpointInfo( deviceId = deviceId, deviceName = deviceName, platform = platform, - hostInfoList = getHostInfoList() + hostInfoList = getHostInfoList(), + port = port ) } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt index 9c0c67603..64216db37 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt @@ -19,23 +19,23 @@ import com.clipevery.clip.TransferableConsumer import com.clipevery.clip.getDesktopClipboardService import com.clipevery.config.ConfigManager import com.clipevery.config.DefaultConfigManager -import com.clipevery.config.FileType +import com.clipevery.app.AppFileType import com.clipevery.controller.SyncController import com.clipevery.dao.DriverFactory import com.clipevery.dao.SyncDao import com.clipevery.dao.createDatabase -import com.clipevery.dao.store.DesktopPreKeyStore -import com.clipevery.dao.store.DesktopSessionStore -import com.clipevery.dao.store.DesktopSignedPreKeyStore -import com.clipevery.dao.store.getIdentityKeyStoreFactory -import com.clipevery.device.DesktopDeviceInfoFactory -import com.clipevery.device.DeviceInfoFactory +import com.clipevery.signal.DesktopPreKeyStore +import com.clipevery.signal.DesktopSessionStore +import com.clipevery.signal.DesktopSignedPreKeyStore +import com.clipevery.signal.getIdentityKeyStoreFactory +import com.clipevery.endpoint.DesktopEndpointInfoFactory +import com.clipevery.endpoint.EndpointInfoFactory import com.clipevery.i18n.GlobalCopywriter import com.clipevery.i18n.GlobalCopywriterImpl import com.clipevery.listen.GlobalListener import com.clipevery.log.initLogger -import com.clipevery.model.AppInfo -import com.clipevery.model.DesktopAppInfoFactory +import com.clipevery.app.AppInfo +import com.clipevery.app.DesktopAppInfoFactory import com.clipevery.net.ClipClient import com.clipevery.net.ClipServer import com.clipevery.net.DesktopClipClient @@ -76,8 +76,8 @@ fun initKoinApplication(ioScope: CoroutineScope): KoinApplication { single { DesktopClipServer(get()).start() } single> { lazy { get() } } single { DesktopClipClient() } - single { DesktopDeviceInfoFactory() } - single { DesktopQRCodeGenerator(get(), get(), get()) } + single { DesktopEndpointInfoFactory( lazy { get() }) } + single { DesktopQRCodeGenerator(get(), get()) } single { GlobalCopywriterImpl(get()) } single { getDesktopClipboardService(get()) } single { DesktopTransferableConsumer() } @@ -89,7 +89,7 @@ fun initKoinApplication(ioScope: CoroutineScope): KoinApplication { single { DesktopPreKeyStore(get()) } single { DesktopSignedPreKeyStore(get()) } single { createDatabase(DriverFactory()) } - single { SyncController(get(), get(), get(), get(), get(), get(), get(), get()) } + single { SyncController(get(), get(), get(), get(), get(), get(), get()) } single { get() } single { SyncDao(get()) } } @@ -108,7 +108,7 @@ fun initInject(koinApplication: KoinApplication) { fun main() = application { val pathProvider = getPathProvider() - initLogger(pathProvider.resolve("clipevery.log", FileType.LOG).pathString) + initLogger(pathProvider.resolve("clipevery.log", AppFileType.LOG).pathString) val logger = KotlinLogging.logger {} logger.info { "Starting Clipevery" } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosClipboardService.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosClipboardService.kt similarity index 96% rename from composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosClipboardService.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosClipboardService.kt index 2ae7cb654..a58c11edf 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosClipboardService.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosClipboardService.kt @@ -1,8 +1,8 @@ -package com.clipevery.macos +package com.clipevery.os.macos import com.clipevery.clip.ClipboardService import com.clipevery.clip.TransferableConsumer -import com.clipevery.macos.api.MacosApi +import com.clipevery.os.macos.api.MacosApi import java.awt.Toolkit import java.awt.datatransfer.Clipboard import java.awt.datatransfer.Transferable diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosKeychainHelper.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosKeychainHelper.kt similarity index 89% rename from composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosKeychainHelper.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosKeychainHelper.kt index 1d7f389cd..be111cd1f 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/MacosKeychainHelper.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/MacosKeychainHelper.kt @@ -1,6 +1,6 @@ -package com.clipevery.macos +package com.clipevery.os.macos -import com.clipevery.macos.api.MacosApi +import com.clipevery.os.macos.api.MacosApi object MacosKeychainHelper { diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/api/MacosApi.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt similarity index 94% rename from composeApp/src/desktopMain/kotlin/com/clipevery/macos/api/MacosApi.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt index 5830386fd..4ce002af4 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/macos/api/MacosApi.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt @@ -1,4 +1,4 @@ -package com.clipevery.macos.api +package com.clipevery.os.macos.api import com.sun.jna.Library import com.sun.jna.Native diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowDapiHelper.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowDapiHelper.kt similarity index 91% rename from composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowDapiHelper.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowDapiHelper.kt index a19427de7..9a6871eb6 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowDapiHelper.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowDapiHelper.kt @@ -1,4 +1,4 @@ -package com.clipevery.windows +package com.clipevery.os.windows import com.sun.jna.platform.win32.Crypt32Util.cryptProtectData import com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowsClipboardService.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowsClipboardService.kt similarity index 98% rename from composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowsClipboardService.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowsClipboardService.kt index c14415e89..a372484f0 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/WindowsClipboardService.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/WindowsClipboardService.kt @@ -1,9 +1,9 @@ -package com.clipevery.windows +package com.clipevery.os.windows import com.clipevery.clip.ClipboardService import com.clipevery.clip.TransferableConsumer import com.clipevery.platform.currentPlatform -import com.clipevery.windows.api.User32 +import com.clipevery.os.windows.api.User32 import com.sun.jna.Pointer import com.sun.jna.platform.win32.Kernel32 import com.sun.jna.platform.win32.WinDef.HWND diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/User32.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/api/User32.kt similarity index 98% rename from composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/User32.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/api/User32.kt index e23288879..8d7eb2662 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/User32.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/windows/api/User32.kt @@ -1,4 +1,4 @@ -package com.clipevery.windows.api +package com.clipevery.os.windows.api import com.sun.jna.Native import com.sun.jna.platform.win32.WinDef.HRGN diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/IdentityKeyStore.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/IdentityKeyStore.kt similarity index 93% rename from composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/IdentityKeyStore.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/signal/IdentityKeyStore.kt index a4d93d124..2623e8900 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/IdentityKeyStore.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/IdentityKeyStore.kt @@ -1,18 +1,18 @@ -package com.clipevery.dao.store +package com.clipevery.signal import com.clipevery.Database -import com.clipevery.config.FileType -import com.clipevery.encrypt.decryptData -import com.clipevery.encrypt.encryptData -import com.clipevery.encrypt.generateAESKey -import com.clipevery.encrypt.secretKeyToString -import com.clipevery.encrypt.stringToSecretKey -import com.clipevery.macos.MacosKeychainHelper -import com.clipevery.model.AppInfo +import com.clipevery.app.AppFileType +import com.clipevery.utils.decryptData +import com.clipevery.utils.encryptData +import com.clipevery.utils.generateAESKey +import com.clipevery.utils.secretKeyToString +import com.clipevery.utils.stringToSecretKey +import com.clipevery.os.macos.MacosKeychainHelper +import com.clipevery.app.AppInfo import com.clipevery.path.getPathProvider import com.clipevery.platform.currentPlatform import com.clipevery.presist.DesktopOneFilePersist -import com.clipevery.windows.WindowDapiHelper +import com.clipevery.os.windows.WindowDapiHelper import io.github.oshai.kotlinlogging.KotlinLogging import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.IdentityKeyPair @@ -105,7 +105,7 @@ class MacosIdentityKeyStoreFactory(private val appInfo: AppInfo, private val filePersist = DesktopOneFilePersist( getPathProvider() - .resolve("signal.data", FileType.ENCRYPT)) + .resolve("signal.data", AppFileType.ENCRYPT)) override fun createIdentityKeyStore(): IdentityKeyStore { val file = filePersist.path.toFile() @@ -162,7 +162,7 @@ class WindowsIdentityKeyStoreFactory(private val appInfo: AppInfo, private val filePersist = DesktopOneFilePersist( getPathProvider() - .resolve("signal.data", FileType.ENCRYPT)) + .resolve("signal.data", AppFileType.ENCRYPT)) override fun createIdentityKeyStore(): IdentityKeyStore { val file = filePersist.path.toFile() diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/PreKeyStore.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/PreKeyStore.kt similarity index 97% rename from composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/PreKeyStore.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/signal/PreKeyStore.kt index 108e25dc5..92aad2bc6 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/PreKeyStore.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/PreKeyStore.kt @@ -1,4 +1,4 @@ -package com.clipevery.dao.store +package com.clipevery.signal import com.clipevery.Database import com.clipevery.data.PreKey diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SessionStore.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/SessionStore.kt similarity index 98% rename from composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SessionStore.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/signal/SessionStore.kt index a0deb3261..4dff1bf86 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SessionStore.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/SessionStore.kt @@ -1,4 +1,4 @@ -package com.clipevery.dao.store +package com.clipevery.signal import com.clipevery.Database import org.signal.libsignal.protocol.SignalProtocolAddress diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SignedPreKeyStore.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/SignedPreKeyStore.kt similarity index 98% rename from composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SignedPreKeyStore.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/signal/SignedPreKeyStore.kt index 5ad1568b2..bf92a5006 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/dao/store/SignedPreKeyStore.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/signal/SignedPreKeyStore.kt @@ -1,4 +1,4 @@ -package com.clipevery.dao.store +package com.clipevery.signal import com.clipevery.Database import com.clipevery.data.SignedPreKey diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/encrypt/PrekeyBundleUtils.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PrekeyBundleUtils.kt similarity index 98% rename from composeApp/src/desktopMain/kotlin/com/clipevery/encrypt/PrekeyBundleUtils.kt rename to composeApp/src/desktopMain/kotlin/com/clipevery/utils/PrekeyBundleUtils.kt index f90b27a1c..b4f7b0293 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/encrypt/PrekeyBundleUtils.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PrekeyBundleUtils.kt @@ -1,4 +1,4 @@ -package com.clipevery.encrypt +package com.clipevery.utils import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.InvalidKeyException diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/QRCodeUtils.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/QRCodeUtils.kt index bee9fd85d..5ae3bbfad 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/QRCodeUtils.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/QRCodeUtils.kt @@ -2,24 +2,24 @@ package com.clipevery.utils import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toComposeImageBitmap -import com.clipevery.device.DeviceInfoFactory -import com.clipevery.model.RequestEndpointInfo -import com.clipevery.net.ClipServer +import com.clipevery.endpoint.EndpointInfo +import com.clipevery.endpoint.EndpointInfoFactory import com.clipevery.net.SyncValidator +import com.clipevery.platform.Platform import com.google.zxing.BarcodeFormat import com.google.zxing.qrcode.QRCodeWriter import java.awt.Color import java.awt.image.BufferedImage +import java.io.ByteArrayOutputStream +import java.io.DataOutputStream class DesktopQRCodeGenerator(private val syncValidator: SyncValidator, - private val clipServer: ClipServer, - private val deviceInfoFactory: DeviceInfoFactory): QRCodeGenerator { + private val endpointInfoFactory: EndpointInfoFactory): QRCodeGenerator { private fun endpointInfo(): String { val token = syncValidator.createToken() - val deviceInfo = deviceInfoFactory.createDeviceInfo() - val port = clipServer.port() - return RequestEndpointInfo(deviceInfo, port).getBase64Encode(token) + val endpointInfo = endpointInfoFactory.createEndpointInfo() + return encodeEndpointInfo(endpointInfo, token) } override fun generateQRCode(width: Int, height: Int): ImageBitmap { @@ -37,4 +37,54 @@ class DesktopQRCodeGenerator(private val syncValidator: SyncValidator, fun getRefreshTime(): Long { return syncValidator.getRefreshTime() } + + private fun encodeEndpointInfo(endpointInfo: EndpointInfo, token: Int): String { + val byteStream = ByteArrayOutputStream() + val dataStream = DataOutputStream(byteStream) + doEncodeDeviceInfo(endpointInfo, dataStream) + val byteArray = byteStream.toByteArray() + val size = byteArray.size + val offset = token % size + val byteArrayRotate = byteArray.rotate(offset) + val saltByteStream = ByteArrayOutputStream() + val saltDataStream = DataOutputStream(saltByteStream) + saltDataStream.write(byteArrayRotate) + saltDataStream.writeInt(token) + return base64Encode(saltByteStream.toByteArray()) + } + + private fun doEncodeDeviceInfo(endpointInfo: EndpointInfo, + dataOutputStream: DataOutputStream + ) { + dataOutputStream.writeUTF(endpointInfo.deviceId) + dataOutputStream.writeUTF(endpointInfo.deviceName) + encodePlatform(endpointInfo.platform, dataOutputStream) + dataOutputStream.writeInt(endpointInfo.hostInfoList.size) + endpointInfo.hostInfoList.forEach { + dataOutputStream.writeUTF(it.displayName) + dataOutputStream.writeUTF(it.hostAddress) + } + dataOutputStream.writeInt(endpointInfo.port) + } + + private fun encodePlatform(platform: Platform, dataOutputStream: DataOutputStream) { + dataOutputStream.writeUTF(platform.name) + dataOutputStream.writeUTF(platform.arch) + dataOutputStream.writeInt(platform.bitMode) + dataOutputStream.writeUTF(platform.version) + } + + private fun ByteArray.rotate(offset: Int): ByteArray { + val effectiveOffset = offset % size + if (effectiveOffset == 0 || this.isEmpty()) { + return this.copyOf() // 如果偏移量为0或数组为空,则直接返回原数组的副本 + } + + val result = ByteArray(this.size) + for (i in this.indices) { + val newPosition = (i + effectiveOffset + this.size) % this.size + result[newPosition] = this[i] + } + return result + } } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/UIUtils.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/UIUtils.kt index aed7fa85b..9063a4f86 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/UIUtils.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/UIUtils.kt @@ -3,7 +3,7 @@ package com.clipevery.utils import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp -import com.clipevery.model.AppUI +import com.clipevery.app.AppUI import java.awt.GraphicsEnvironment import java.awt.Toolkit diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/GDI32.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/GDI32.kt deleted file mode 100644 index d5a4b10e7..000000000 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/windows/api/GDI32.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.clipevery.windows.api - -import com.sun.jna.Native -import com.sun.jna.platform.win32.WinDef.HRGN - -import com.sun.jna.win32.StdCallLibrary - - -interface GDI32 : StdCallLibrary { - fun CreateRoundRectRgn(x1: Int, y1: Int, x2: Int, y2: Int, w: Int, h: Int): HRGN? - - companion object { - val INSTANCE: GDI32 = Native.load("gdi32", GDI32::class.java) - } -} \ No newline at end of file diff --git a/composeApp/src/desktopTest/kotlin/com/clipevery/macos/MacosKeychainHelperTest.kt b/composeApp/src/desktopTest/kotlin/com/clipevery/macos/MacosKeychainHelperTest.kt index 259520de0..6a3e1c4d9 100644 --- a/composeApp/src/desktopTest/kotlin/com/clipevery/macos/MacosKeychainHelperTest.kt +++ b/composeApp/src/desktopTest/kotlin/com/clipevery/macos/MacosKeychainHelperTest.kt @@ -1,5 +1,6 @@ package com.clipevery.macos +import com.clipevery.os.macos.MacosKeychainHelper import com.clipevery.platform.currentPlatform import org.junit.Test import kotlin.test.assertEquals diff --git a/composeApp/src/desktopTest/kotlin/com/clipevery/path/PathProviderTest.kt b/composeApp/src/desktopTest/kotlin/com/clipevery/path/PathProviderTest.kt index 1a02108bb..b46e92f15 100644 --- a/composeApp/src/desktopTest/kotlin/com/clipevery/path/PathProviderTest.kt +++ b/composeApp/src/desktopTest/kotlin/com/clipevery/path/PathProviderTest.kt @@ -1,6 +1,6 @@ package com.clipevery.path -import com.clipevery.config.FileType +import com.clipevery.app.AppFileType import com.clipevery.platform.currentPlatform import org.junit.Test import kotlin.test.assertEquals @@ -11,7 +11,7 @@ class PathProviderTest { fun testPathProvider() { val pathProvider = getPathProvider() - val configPath = pathProvider.resolve("test.config", FileType.USER) + val configPath = pathProvider.resolve("test.config", AppFileType.USER) assertEquals("test.config", configPath.fileName.toString()) val currentPlatform = currentPlatform() diff --git a/composeApp/src/desktopTest/kotlin/com/clipevery/windows/WindowDapiHelperTest.kt b/composeApp/src/desktopTest/kotlin/com/clipevery/windows/WindowDapiHelperTest.kt index 319d4cf20..7aacadd94 100644 --- a/composeApp/src/desktopTest/kotlin/com/clipevery/windows/WindowDapiHelperTest.kt +++ b/composeApp/src/desktopTest/kotlin/com/clipevery/windows/WindowDapiHelperTest.kt @@ -1,5 +1,6 @@ package com.clipevery.windows +import com.clipevery.os.windows.WindowDapiHelper import com.clipevery.platform.currentPlatform import kotlin.test.Test import kotlin.test.assertEquals