Browse Source

Added outline api

Vadik Sirekanyan 2 năm trước cách đây
mục cha
commit
5c475cdef4

+ 11 - 1
app/build.gradle.kts

@@ -1,6 +1,7 @@
 plugins {
     id("com.android.application")
-    id("org.jetbrains.kotlin.android")
+    kotlin("android")
+    kotlin("plugin.serialization")
     id("org.sirekanyan.version-checker")
 }
 
@@ -47,6 +48,15 @@ android {
 }
 
 dependencies {
+
+    // compose
     implementation("androidx.activity:activity-compose:1.7.2")
     implementation("androidx.compose.material3:material3:1.1.1")
+
+    // ktor
+    implementation("io.ktor:ktor-client-cio:2.3.3")
+    implementation("io.ktor:ktor-client-content-negotiation:2.3.3")
+    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.3")
+    implementation("org.slf4j:slf4j-simple:2.0.7")
+
 }

+ 2 - 0
app/src/main/AndroidManifest.xml

@@ -2,6 +2,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools">
 
+    <uses-permission android:name="android.permission.INTERNET" />
+
     <application
         android:allowBackup="false"
         android:dataExtractionRules="@xml/data_extraction_rules"

+ 15 - 1
app/src/main/java/org/sirekanyan/outline/MainActivity.kt

@@ -5,20 +5,34 @@ import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.produceState
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
+import org.sirekanyan.outline.api.OutlineApi
+import org.sirekanyan.outline.api.model.AccessKey
 import org.sirekanyan.outline.ui.theme.OutlineTheme
 
 class MainActivity : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {
+            val api = remember { OutlineApi() }
+            val accessKeys by produceState(listOf<AccessKey>()) { value = api.getAccessKeys() }
             OutlineTheme {
                 Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
-                    Text("Hello, World!", Modifier.padding(16.dp))
+                    LazyColumn {
+                        accessKeys.forEach { key ->
+                            item {
+                                Text(key.name.ifEmpty { "Key ${key.id}" }, Modifier.padding(16.dp))
+                            }
+                        }
+                    }
                 }
             }
         }

+ 12 - 0
app/src/main/java/org/sirekanyan/outline/api/InsecureTrustManager.kt

@@ -0,0 +1,12 @@
+package org.sirekanyan.outline.api
+
+import android.annotation.SuppressLint
+import java.security.cert.X509Certificate
+import javax.net.ssl.X509TrustManager
+
+@SuppressLint("CustomX509TrustManager", "TrustAllX509TrustManager")
+object InsecureTrustManager : X509TrustManager {
+    override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
+    override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
+    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
+}

+ 27 - 0
app/src/main/java/org/sirekanyan/outline/api/OutlineApi.kt

@@ -0,0 +1,27 @@
+package org.sirekanyan.outline.api
+
+import io.ktor.client.HttpClient
+import io.ktor.client.call.body
+import io.ktor.client.engine.cio.CIO
+import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
+import io.ktor.client.request.get
+import io.ktor.serialization.kotlinx.json.json
+import kotlinx.serialization.json.Json
+import org.sirekanyan.outline.api.model.AccessKey
+import org.sirekanyan.outline.api.model.AccessKeysResponse
+
+private const val API_URL = "" // TODO: add api url
+
+class OutlineApi {
+
+    private val httpClient = HttpClient(CIO) {
+        install(ContentNegotiation) {
+            json(Json { ignoreUnknownKeys = true })
+        }
+        engine { https.trustManager = InsecureTrustManager } // TODO: remove insecure http
+    }
+
+    suspend fun getAccessKeys(): List<AccessKey> =
+        httpClient.get("$API_URL/access-keys").body<AccessKeysResponse>().accessKeys
+
+}

+ 10 - 0
app/src/main/java/org/sirekanyan/outline/api/model/AccessKey.kt

@@ -0,0 +1,10 @@
+package org.sirekanyan.outline.api.model
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+class AccessKey(
+    val id: String,
+    val name: String,
+    val accessUrl: String,
+)

+ 6 - 0
app/src/main/java/org/sirekanyan/outline/api/model/AccessKeysResponse.kt

@@ -0,0 +1,6 @@
+package org.sirekanyan.outline.api.model
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+class AccessKeysResponse(val accessKeys: List<AccessKey>)

+ 3 - 1
build.gradle.kts

@@ -1,5 +1,7 @@
 plugins {
+    val kotlinVersion = "1.9.0"
     id("com.android.application") version "8.1.0" apply false
-    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
+    kotlin("android") version kotlinVersion apply false
+    kotlin("plugin.serialization") version kotlinVersion apply false
     id("org.sirekanyan.version-checker") version "1.0.7" apply false
 }