Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions FloconAndroid/.idea/xcode.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions FloconAndroid/flocon-base/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ kotlin {

jvm()

/*
iosX64()
iosArm64()
iosSimulatorArm64()
*/


sourceSets {
val commonMain by getting {
dependencies {
Expand All @@ -38,7 +36,6 @@ kotlin {
}
}

/*
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
Expand All @@ -48,7 +45,6 @@ kotlin {
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
*/
}
}

Expand Down
6 changes: 1 addition & 5 deletions FloconAndroid/flocon-no-op/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ kotlin {

jvm()

/*
iosX64()
iosArm64()
iosSimulatorArm64()
*/


sourceSets {
val commonMain by getting {
dependencies {
Expand All @@ -39,7 +37,6 @@ kotlin {
}
}

/*
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
Expand All @@ -49,7 +46,6 @@ kotlin {
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
*/
}
}

Expand Down
16 changes: 11 additions & 5 deletions FloconAndroid/flocon/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ kotlin {

jvm()

/*
iosX64()
iosArm64()
iosSimulatorArm64()
*/


sourceSets {
val commonMain by getting {
dependencies {
Expand Down Expand Up @@ -50,7 +48,6 @@ kotlin {
}
}

/*
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
Expand All @@ -61,9 +58,18 @@ kotlin {
iosSimulatorArm64Main.dependsOn(this)
dependencies {
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.darwin)

implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.client.logging)
implementation(libs.ktor.serialization.kotlinx.json)

implementation(libs.androidx.sqlite.bundled)

// to store the device id
implementation("com.russhwolf:multiplatform-settings:1.3.0")
}
}
*/
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import io.github.openflocon.flocon.core.FloconMessageSender
import io.github.openflocon.flocon.core.FloconPlugin
import io.github.openflocon.flocon.model.FloconMessageFromServer
import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update

internal class FloconDeeplinksPluginImpl(
private val sender: FloconMessageSender,
) : FloconPlugin, FloconDeeplinksPlugin {

private val deeplinks = java.util.concurrent.atomic.AtomicReference<List<DeeplinkModel>?>(null)
private val deeplinks = MutableStateFlow<List<DeeplinkModel>?>(null)

override fun onMessageReceived(
messageFromServer: FloconMessageFromServer,
Expand All @@ -21,13 +23,15 @@ internal class FloconDeeplinksPluginImpl(

override fun onConnectedToServer() {
// on connected, send known dashboard
deeplinks.get()?.let {
deeplinks.value?.let {
registerDeeplinks(it)
}
}

override fun registerDeeplinks(deeplinks: List<DeeplinkModel>) {
this.deeplinks.set(deeplinks)
this.deeplinks.update {
deeplinks
}

try {
sender.send(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.openflocon.flocon

object Flocon : FloconCore() {

fun initialize() {
super.initializeFlocon(context = FloconContext())
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.openflocon.flocon

actual class FloconContext

internal actual fun displayClearTextError(context: FloconContext) {
// no op on ios
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.openflocon.flocon

internal actual class FloconFile {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.openflocon.flocon

internal actual fun getServerHost(floconContext: FloconContext): String {
return "localhost"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.github.openflocon.flocon.core

import com.russhwolf.settings.NSUserDefaultsSettings
import io.github.openflocon.flocon.FloconContext
import platform.Foundation.NSBundle
import platform.Foundation.NSUUID
import platform.Foundation.NSUserDefaults
import platform.UIKit.UIDevice

private fun getDeviceId() : String {
val settings = NSUserDefaultsSettings(
NSUserDefaults.standardUserDefaults()
)
val id = settings.getStringOrNull("deviceId")
return if(id != null) {
id
} else {
val newId = NSUUID.UUID().UUIDString()
settings.putString("deviceId", newId)
newId
}
}

private fun deviceName(): String {
val device = UIDevice.currentDevice
return "${device.systemName()} ${device.model}"
}

internal actual fun getAppInfos(floconContext: FloconContext): AppInfos {
val bundle = NSBundle.mainBundle
val appName = bundle.objectForInfoDictionaryKey("CFBundleName") as? String ?: "Unknown"
val appPackageName = bundle.bundleIdentifier ?: "Unknown"

return AppInfos(
deviceId = getDeviceId(),
deviceName = deviceName(),
appName = appName,
appPackageName = appPackageName,
platform = "ios",
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package io.github.openflocon.flocon.plugins.database

import androidx.sqlite.SQLiteConnection
import androidx.sqlite.driver.NativeSQLiteDriver
import io.github.openflocon.flocon.FloconContext
import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel
import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse
import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel
import platform.Foundation.NSFileManager
import platform.posix.close

internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource {
return FloconDatabaseDataSourceIos(context)
}

internal class FloconDatabaseDataSourceIos(
private val context: FloconContext
) : FloconDatabaseDataSource {

override fun executeSQL(
registeredDatabases: List<FloconDatabaseModel>,
databaseName: String,
query: String
): DatabaseExecuteSqlResponse {
val fileManager = NSFileManager.defaultManager
if (!fileManager.fileExistsAtPath(databaseName)) {
return DatabaseExecuteSqlResponse.Error(
message = "Database file not found: $databaseName",
originalSql = query
)
}

val driver = NativeSQLiteDriver()
val connection = driver.open(fileName = databaseName)

return try {
val firstWord = getFirstWord(query).uppercase()
when (firstWord) {
"SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query)
"INSERT" -> executeInsert(connection, query)
"UPDATE", "DELETE" -> executeUpdateDelete(connection, query)
else -> executeRawQuery(connection, query)
}
} catch (t: Throwable) {
DatabaseExecuteSqlResponse.Error(
message = t.message ?: "Error executing SQL",
originalSql = query
)
} finally {
connection.close()
}
}

override fun getAllDataBases(
registeredDatabases: List<FloconDatabaseModel>
): List<DeviceDataBaseDataModel> {
val fileManager = NSFileManager.defaultManager
return registeredDatabases.mapNotNull {
if (fileManager.fileExistsAtPath(it.absolutePath)) {
DeviceDataBaseDataModel(
id = it.absolutePath,
name = it.displayName
)
} else null
}
}
}

// --- SQL execution helpers ---

private fun executeSelect(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse {
val cursor = connection.prepare(query).use { statement ->
val columnCount = statement.getColumnCount()
val columns = (0 until columnCount).map { statement.getColumnName(it) }
val rows = mutableListOf<List<String?>>()

while (statement.step()) {
val row = (0 until columnCount).map { idx ->
statement.getText(idx)
}
rows.add(row)
}

statement.close() // maybe remove
DatabaseExecuteSqlResponse.Select(columns, rows)
}
return cursor
}

private fun executeUpdateDelete(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse {
connection.prepare(query).use { statement ->
statement.close()
}
// sqlite-kt n'expose pas encore `changes()`, on renvoie 0
return DatabaseExecuteSqlResponse.UpdateDelete(affectedCount = 0)
}

private fun executeInsert(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse {
connection.prepare(query).use { statement ->
statement.close()
}

// Récupération du dernier ID inséré
var id = -1L
connection.prepare("SELECT last_insert_rowid()").use {
id = if (it.step()) it.getLong(0) else -1L
it.close() // maybe remove
}

return DatabaseExecuteSqlResponse.Insert(id)
}

private fun executeRawQuery(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse {
connection.prepare(query).use { statement ->
statement.close() // maybe remove
}
return DatabaseExecuteSqlResponse.RawSuccess
}

// --- Utilities ---
private fun getFirstWord(s: String): String {
val trimmed = s.trim()
val firstSpace = trimmed.indexOf(' ')
return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.openflocon.flocon.plugins.device

import io.github.openflocon.flocon.FloconContext

internal actual fun restartApp(context: FloconContext) {
// TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.openflocon.flocon.plugins.device

import io.github.openflocon.flocon.FloconContext

actual fun getAppIconBase64(context: FloconContext): String? {
return null // TODO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.github.openflocon.flocon.plugins.files

import io.github.openflocon.flocon.FloconContext
import io.github.openflocon.flocon.FloconFile
import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel

internal actual fun fileDataSource(context: FloconContext): FileDataSource {
return FileDataSourceIOs()
}

// TODO
internal class FileDataSourceIOs : FileDataSource {
override fun getFile(
path: String,
isConstantPath: Boolean
): FloconFile? {
return null
}

override fun getFolderContent(
path: String,
isConstantPath: Boolean
): List<FileDataModel> {
return emptyList()
}

override fun deleteFile(path: String) {
// TODO
}

override fun deleteFolderContent(folder: FloconFile) {
// TODO
}

}
Loading