basic frontend added

This commit is contained in:
2026-02-06 00:49:38 +05:00
parent c35b466de6
commit fbbe35c9c0
19 changed files with 2374 additions and 7 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Textpipe SMS Gateway</title>
<script type="module" crossorigin src="./assets/index-BR9M1eFw.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-jwVA1VU4.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@@ -1,5 +1,6 @@
package sh.sar.textpipe.server
import android.content.Context
import android.util.Log
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
@@ -13,18 +14,18 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.json.Json
import sh.sar.textpipe.data.model.ErrorResponse
import sh.sar.textpipe.data.repository.SmsRepository
import sh.sar.textpipe.server.auth.configureAuth
import sh.sar.textpipe.server.routes.smsRoutes
import sh.sar.textpipe.server.routes.statusRoutes
import sh.sar.textpipe.server.routes.webUIRoutes
import sh.sar.textpipe.sim.SimManager
import java.net.BindException
import java.net.ServerSocket
class TextpipeServer(
private val context: Context,
private val smsRepository: SmsRepository,
private val simManager: SimManager
) {
@@ -143,6 +144,10 @@ class TextpipeServer(
private fun Application.configureRouting() {
routing {
// Web UI routes (served from assets)
webUIRoutes(context)
// API routes
statusRoutes(simManager, { startTime }, { currentPort })
smsRoutes(smsRepository)
}

View File

@@ -6,10 +6,6 @@ import sh.sar.textpipe.data.model.StatusResponse
import sh.sar.textpipe.sim.SimManager
fun Route.statusRoutes(simManager: SimManager, getStartTime: () -> Long, getPort: () -> Int) {
get("/") {
call.respondText("Textpipe SMS Gateway API")
}
get("/api/status") {
val uptime = System.currentTimeMillis() - getStartTime()
val response = StatusResponse(

View File

@@ -0,0 +1,52 @@
package sh.sar.textpipe.server.routes
import android.content.Context
import io.ktor.http.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import java.io.IOException
fun Route.webUIRoutes(context: Context) {
get("/") {
serveAsset(context, call, "index.html", ContentType.Text.Html)
}
get("/assets/{file}") {
val fileName = call.parameters["file"] ?: return@get
val contentType = getContentType(fileName)
serveAsset(context, call, "assets/$fileName", contentType)
}
get("/favicon.svg") {
serveAsset(context, call, "favicon.svg", ContentType.Image.SVG)
}
}
private suspend fun serveAsset(
context: Context,
call: io.ktor.server.application.ApplicationCall,
path: String,
contentType: ContentType
) {
try {
val inputStream = context.assets.open("webui/$path")
val bytes = inputStream.readBytes()
inputStream.close()
call.respondBytes(bytes, contentType)
} catch (e: IOException) {
call.respond(HttpStatusCode.NotFound, "File not found: $path")
}
}
private fun getContentType(fileName: String): ContentType {
return when {
fileName.endsWith(".js") -> ContentType.Application.JavaScript
fileName.endsWith(".css") -> ContentType.Text.CSS
fileName.endsWith(".html") -> ContentType.Text.Html
fileName.endsWith(".svg") -> ContentType.Image.SVG
fileName.endsWith(".png") -> ContentType.Image.PNG
fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") -> ContentType.Image.JPEG
fileName.endsWith(".json") -> ContentType.Application.Json
else -> ContentType.Application.OctetStream
}
}

View File

@@ -101,7 +101,7 @@ class TextpipeService : Service() {
smsSender.register()
smsRepository = SmsRepository(dao, smsSender, simManager)
textpipeServer = TextpipeServer(smsRepository, simManager)
textpipeServer = TextpipeServer(this, smsRepository, simManager)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {