mirror of
https://github.com/fromchat-messenger/app.git
synced 2026-09-22 19:15:05 +03:00
Refactor the whole project structure
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package com.pr0gramm3r101.utils
|
||||
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
actual fun Modifier.imeScrollWithKeyboard(): Modifier = this
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.pr0gramm3r101.utils
|
||||
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import kotlinx.cinterop.addressOf
|
||||
import kotlinx.cinterop.convert
|
||||
import kotlinx.cinterop.usePinned
|
||||
import platform.CoreCrypto.CCHmac
|
||||
import platform.CoreCrypto.kCCHmacAlgSHA256
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
internal fun iosHmacSha256(key: ByteArray, data: ByteArray): ByteArray {
|
||||
val mac = ByteArray(32)
|
||||
|
||||
key.usePinned { keyPinned ->
|
||||
data.usePinned { dataPinned ->
|
||||
mac.usePinned { macPinned ->
|
||||
CCHmac(
|
||||
algorithm = kCCHmacAlgSHA256,
|
||||
key = keyPinned.addressOf(0),
|
||||
keyLength = key.size.convert(),
|
||||
data = dataPinned.addressOf(0),
|
||||
dataLength = data.size.convert(),
|
||||
macOut = macPinned.addressOf(0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mac
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.pr0gramm3r101.utils
|
||||
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import kotlinx.cinterop.addressOf
|
||||
import kotlinx.cinterop.convert
|
||||
import kotlinx.cinterop.usePinned
|
||||
import platform.Foundation.NSFileManager
|
||||
import platform.Foundation.NSNumber
|
||||
import platform.posix.SEEK_SET
|
||||
import platform.posix.fclose
|
||||
import platform.posix.fopen
|
||||
import platform.posix.fread
|
||||
import platform.posix.fseek
|
||||
import platform.posix.fwrite
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun iosFileSize(path: String): Long {
|
||||
if (!NSFileManager.defaultManager.fileExistsAtPath(path)) return 0L
|
||||
val attrs = NSFileManager.defaultManager.attributesOfItemAtPath(path, null) ?: return 0L
|
||||
return (attrs["NSFileSize"] as? NSNumber)?.longValue ?: 0L
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun iosReadFileRange(path: String, offset: Long, length: Int): ByteArray {
|
||||
if (length <= 0) return ByteArray(0)
|
||||
val file = fopen(path, "rb") ?: error("Failed to open file")
|
||||
try {
|
||||
fseek(file, offset, SEEK_SET)
|
||||
val buffer = ByteArray(length)
|
||||
buffer.usePinned { pinned ->
|
||||
val read = fread(pinned.addressOf(0), 1.convert(), length.convert(), file).toInt()
|
||||
if (read < length) {
|
||||
error("File truncated")
|
||||
}
|
||||
}
|
||||
return buffer
|
||||
} finally {
|
||||
fclose(file)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun iosAppendFile(path: String, bytes: ByteArray) {
|
||||
if (bytes.isEmpty()) return
|
||||
val file = fopen(path, "ab") ?: error("Failed to open file for append")
|
||||
try {
|
||||
bytes.usePinned { pinned ->
|
||||
val written = fwrite(pinned.addressOf(0), 1.convert(), bytes.size.convert(), file).toInt()
|
||||
if (written != bytes.size) {
|
||||
error("Short write")
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fclose(file)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun iosCopyFile(sourcePath: String, destinationPath: String) {
|
||||
val input = fopen(sourcePath, "rb") ?: error("Failed to open source file")
|
||||
val output = fopen(destinationPath, "wb") ?: run {
|
||||
fclose(input)
|
||||
error("Failed to open destination file")
|
||||
}
|
||||
val buffer = ByteArray(256 * 1024)
|
||||
try {
|
||||
while (true) {
|
||||
val read = buffer.usePinned { pinned ->
|
||||
fread(pinned.addressOf(0), 1.convert(), buffer.size.convert(), input).toInt()
|
||||
}
|
||||
if (read <= 0) break
|
||||
buffer.usePinned { pinned ->
|
||||
val written = fwrite(pinned.addressOf(0), 1.convert(), read.convert(), output).toInt()
|
||||
if (written != read) {
|
||||
error("Short write")
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fclose(input)
|
||||
fclose(output)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
class IosPosixFileReader(
|
||||
private val path: String,
|
||||
) {
|
||||
private val file = fopen(path, "rb") ?: error("Failed to open file")
|
||||
|
||||
fun read(buffer: ByteArray, offset: Int, length: Int): Int {
|
||||
if (length <= 0) return 0
|
||||
return buffer.usePinned { pinned ->
|
||||
fread(pinned.addressOf(offset), 1.convert(), length.convert(), file).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
fun close() {
|
||||
fclose(file)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.pr0gramm3r101.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
|
||||
// TODO iOS 13+ uses scene-based API; status bar control requires native Swift/ObjC bridge
|
||||
@Composable
|
||||
actual fun rememberSystemBarsController(): ((Boolean) -> Unit)? {
|
||||
return remember {
|
||||
{ _ -> }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package com.pr0gramm3r101.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import platform.UIKit.UIDevice
|
||||
import platform.posix._OSSwapInt16
|
||||
import platform.posix._OSSwapInt32
|
||||
import platform.posix._OSSwapInt64
|
||||
@@ -22,4 +23,20 @@ inline fun htonl(data: UInt) = if (isLittleEndian) _OSSwapInt32(data) else data
|
||||
inline fun htonll(data: ULong) = if (isLittleEndian) _OSSwapInt64(data) else data
|
||||
inline fun ntohs(data: UShort) = if (isLittleEndian) _OSSwapInt16(data) else data
|
||||
inline fun ntohl(data: UInt) = if (isLittleEndian) _OSSwapInt32(data) else data
|
||||
inline fun ntohll(data: ULong) = if (isLittleEndian) _OSSwapInt64(data) else data
|
||||
inline fun ntohll(data: ULong) = if (isLittleEndian) _OSSwapInt64(data) else data
|
||||
|
||||
private fun String?.trimIfNotBlank(): String? =
|
||||
this?.trim()?.takeIf { it.isNotEmpty() }
|
||||
|
||||
actual fun currentDeviceInfo(): CurrentDeviceInfo {
|
||||
val current = UIDevice.currentDevice
|
||||
|
||||
return CurrentDeviceInfo(
|
||||
osName = current.systemName.trimIfNotBlank(),
|
||||
osVersion = current.systemVersion.trimIfNotBlank(),
|
||||
deviceType = "mobile",
|
||||
deviceName = current.name.trimIfNotBlank(),
|
||||
brand = "Apple",
|
||||
model = current.model.trimIfNotBlank()
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user