diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index ee6f05e..802e9a1 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -11,7 +11,7 @@ android {
defaultConfig {
applicationId = "com.faraphel.tasks_valider"
- minSdk = 24
+ minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
@@ -52,8 +52,8 @@ android {
}
dependencies {
- implementation("androidx.core:core-ktx:1.13.0")
- implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
+ implementation("androidx.core:core-ktx:1.13.1")
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.1")
implementation("androidx.activity:activity-compose:1.9.0")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e983a70..32f3c79 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/task/TaskClient.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/task/TaskClient.kt
index b6696d7..e202317 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/connectivity/task/TaskClient.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/task/TaskClient.kt
@@ -5,6 +5,8 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
/**
@@ -32,7 +34,7 @@ class TaskClient(
this.cookies.addAll(cookies)
}
}
- )
+ ).callTimeout(30.seconds)
.build()
// TODO(Faraphel): automatically convert content to the correct type ?
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ClassApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ClassApi.kt
index 386b757..5512313 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ClassApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ClassApi.kt
@@ -1,14 +1,68 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.ClassEntity
import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class ClassApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class ClassApi(private val dao: BaseTaskDao, private val session: SessionEntity) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ClassEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ClassEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ClassEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/PersonApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/PersonApi.kt
index a7c9410..a6e04e2 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/PersonApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/PersonApi.kt
@@ -1,14 +1,68 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.PersonEntity
import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class PersonApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class PersonApi(private val dao: BaseTaskDao, private val session: SessionEntity) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, PersonEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, PersonEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, PersonEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationClassPersonApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationClassPersonApi.kt
index 308e7e5..9a4ef5a 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationClassPersonApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationClassPersonApi.kt
@@ -1,15 +1,72 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.RelationClassPersonEntity
import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class RelationClassPersonApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class RelationClassPersonApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationClassPersonEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationClassPersonEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationClassPersonEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationPersonSessionSubjectApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationPersonSessionSubjectApi.kt
index d5bcb99..feb1a79 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationPersonSessionSubjectApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/RelationPersonSessionSubjectApi.kt
@@ -1,15 +1,72 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.RelationPersonSessionSubjectEntity
import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class RelationPersonSessionSubjectApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class RelationPersonSessionSubjectApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationPersonSessionSubjectEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationPersonSessionSubjectEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, RelationPersonSessionSubjectEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SessionApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SessionApi.kt
index eafbc25..4c65413 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SessionApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SessionApi.kt
@@ -1,13 +1,71 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class SessionApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+
+class SessionApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SessionEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SessionEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SessionEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SubjectApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SubjectApi.kt
index fbbed53..252cd7f 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SubjectApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/SubjectApi.kt
@@ -1,15 +1,72 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.SessionEntity
import com.faraphel.tasks_valider.database.entities.SubjectEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class SubjectApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class SubjectApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SubjectEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SubjectEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, SubjectEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/TaskApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/TaskApi.kt
index 6f5351e..2292dfd 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/TaskApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/TaskApi.kt
@@ -1,15 +1,72 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.SessionEntity
import com.faraphel.tasks_valider.database.entities.TaskEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class TaskApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class TaskApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, TaskEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, TaskEntity::class.java)
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, TaskEntity::class.java)
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ValidationApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ValidationApi.kt
index 46132b6..266e1d0 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ValidationApi.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/ValidationApi.kt
@@ -1,15 +1,74 @@
package com.faraphel.tasks_valider.database.api.entities
-import com.faraphel.tasks_valider.database.api.entities.base.BaseTaskApi
+import com.faraphel.tasks_valider.database.api.entities.base.BaseApi
import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
import com.faraphel.tasks_valider.database.entities.SessionEntity
import com.faraphel.tasks_valider.database.entities.ValidationEntity
-import com.google.gson.reflect.TypeToken
+import com.faraphel.tasks_valider.utils.getBody
+import com.google.gson.Gson
+import fi.iki.elonen.NanoHTTPD
-class ValidationApi(dao: BaseTaskDao, session: SessionEntity) :
- BaseTaskApi(
- dao,
- object: TypeToken() {},
- session
- )
+class ValidationApi(
+ private val dao: BaseTaskDao,
+ private val session: SessionEntity
+) : BaseApi {
+ companion object {
+ private val parser = Gson() ///< The JSON parser
+ }
+
+ // Requests
+
+ override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ValidationEntity::class.java)
+ // check if the object is in the object accessible from the session
+ val exists = this.dao.getAllBySession(session.id).contains(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ if (exists) "Exists" else "Not found"
+ )
+ }
+
+ override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.OK,
+ "application/json",
+ parser.toJson(this.dao.getAllBySession(session.id))
+ )
+ }
+
+ override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ValidationEntity::class.java)
+ // save the data into the database
+ val id = this.dao.insert(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ NanoHTTPD.Response.Status.CREATED,
+ "text/plain",
+ id.toString()
+ )
+ }
+
+ override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
+ // get the content of the request
+ val data = httpSession.getBody()
+ // parse the object
+ val obj = parser.fromJson(data, ValidationEntity::class.java)
+ // delete the object from the database
+ val count = this.dao.delete(obj)
+
+ return NanoHTTPD.newFixedLengthResponse(
+ if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
+ "text/plain",
+ count.toString()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseJsonApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseJsonApi.kt
deleted file mode 100644
index 71441f7..0000000
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseJsonApi.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.faraphel.tasks_valider.database.api.entities.base
-
-import android.util.Log
-import com.faraphel.tasks_valider.database.dao.base.BaseCronDao
-import com.faraphel.tasks_valider.database.entities.base.BaseEntity
-import com.google.gson.Gson
-import com.google.gson.reflect.TypeToken
-import fi.iki.elonen.NanoHTTPD
-
-/**
- * A base for the API to handle the database operations.
- * This is preconfigured to handle JSON data.
- * @param Entity the entity type to handle
- */
-abstract class BaseJsonApi(
- private val dao: BaseCronDao,
- private val entityTypeToken: TypeToken,
-) : BaseApi {
- companion object {
- private val parser = Gson() ///< The JSON parser
- }
-
- // Requests
-
- override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- val obj = parser.fromJson(
- httpSession.inputStream.bufferedReader().readText(),
- this.entityTypeToken.type
- )
- val exists = this.dao.exists(obj)
-
- return NanoHTTPD.newFixedLengthResponse(
- if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
- "text/plain",
- if (exists) "Exists" else "Not found"
- )
- }
-
- override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- return NanoHTTPD.newFixedLengthResponse(
- NanoHTTPD.Response.Status.OK,
- "application/json",
- parser.toJson(this.dao.getAll())
- )
- }
-
- override fun post(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- val data = httpSession.inputStream.bufferedReader().readText()
- Log.i("post data", "data raw : $data")
-
- val obj = parser.fromJson(
- data,
- this.entityTypeToken.type
- )
-
- Log.i("post data", "data parsed : $obj")
-
- val id = this.dao.insert(obj)
-
- return NanoHTTPD.newFixedLengthResponse(
- NanoHTTPD.Response.Status.CREATED,
- "text/plain",
- id.toString()
- )
- }
-
- override fun delete(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- val obj = parser.fromJson(
- httpSession.inputStream.bufferedReader().readText(),
- this.entityTypeToken.type
- )
- val count = this.dao.delete(obj)
-
- return NanoHTTPD.newFixedLengthResponse(
- if (count > 0) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
- "text/plain",
- count.toString()
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseTaskApi.kt b/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseTaskApi.kt
deleted file mode 100644
index b22ca9f..0000000
--- a/app/src/main/java/com/faraphel/tasks_valider/database/api/entities/base/BaseTaskApi.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.faraphel.tasks_valider.database.api.entities.base
-
-import com.faraphel.tasks_valider.database.dao.base.BaseTaskDao
-import com.faraphel.tasks_valider.database.entities.SessionEntity
-import com.faraphel.tasks_valider.database.entities.base.BaseEntity
-import com.google.gson.Gson
-import com.google.gson.reflect.TypeToken
-import fi.iki.elonen.NanoHTTPD
-
-/**
- * A base for the API to handle the database operations.
- * This is preconfigured to handle data for Task objects.
- * @param Entity the entity type to handle
- */
-abstract class BaseTaskApi(
- private val dao: BaseTaskDao,
- private val entityTypeToken: TypeToken,
- private val session: SessionEntity,
-) : BaseJsonApi(
- dao,
- entityTypeToken,
-) {
- companion object {
- private val parser = Gson() ///< The JSON parser
- }
-
- // Requests
-
- override fun head(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- val obj = parser.fromJson(
- httpSession.inputStream.bufferedReader().readText(),
- this.entityTypeToken.type
- )
- // check if the object is in the object accessible from the session
- val exists = this.dao.getAllBySession(session.id).contains(obj)
-
- return NanoHTTPD.newFixedLengthResponse(
- if (exists) NanoHTTPD.Response.Status.OK else NanoHTTPD.Response.Status.NOT_FOUND,
- "text/plain",
- if (exists) "Exists" else "Not found"
- )
- }
-
- override fun get(httpSession: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
- return NanoHTTPD.newFixedLengthResponse(
- NanoHTTPD.Response.Status.OK,
- "application/json",
- parser.toJson(this.dao.getAllBySession(session.id))
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/authentification/server.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/authentification/server.kt
index 0ac5504..f9d5084 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/authentification/server.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/authentification/server.kt
@@ -1,6 +1,6 @@
package com.faraphel.tasks_valider.ui.screen.authentification
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
@@ -8,6 +8,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import com.faraphel.tasks_valider.connectivity.task.session.TaskRole
import com.faraphel.tasks_valider.database.entities.PersonEntity
@@ -20,19 +24,37 @@ fun AuthentificationServerScreen(personEntity: MutableState) {
val firstName = remember { mutableStateOf("") }
val lastName = remember { mutableStateOf("") }
- Column {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(
+ text = "Your Profile",
+ fontSize = 32.sp
+ )
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// first name
TextField(
value = firstName.value,
+ placeholder = { Text("first name") },
onValueChange = { text -> firstName.value = text },
)
// last name
TextField(
value = lastName.value,
+ placeholder = { Text("last name") },
onValueChange = { text -> lastName.value = text },
)
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// confirm button
Button(onClick = {
// create the person entity with the given information
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/selection.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/selection.kt
index 0f9424c..1575f12 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/selection.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/selection.kt
@@ -3,10 +3,14 @@ package com.faraphel.tasks_valider.ui.screen.communication.internet
import android.app.Activity
import android.os.Build
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@@ -29,7 +33,20 @@ fun CommunicationInternetSelectScreen(activity: Activity, database: TaskDatabase
@Composable
fun CommunicationInternetSelectContent(controller: NavController) {
- Column {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(
+ text = "Role",
+ fontSize = 32.sp
+ )
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// client mode
Button(onClick = { controller.navigate("client") }) { Text("Client") }
// server mode
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/server.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/server.kt
index 626fae9..2f81efa 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/server.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/internet/server.kt
@@ -4,8 +4,7 @@ import android.app.Activity
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
@@ -13,7 +12,14 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.text.TextMeasurer
import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.rememberTextMeasurer
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@@ -93,43 +99,71 @@ fun CommunicationInternetServerContent(
Thread { refreshClasses(database, classes) }.start()
}
- Column {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(
+ text = "New Session",
+ fontSize = 32.sp
+ )
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// classes
- Button(onClick = { areClassesExpanded.value = !areClassesExpanded.value }) {
- Row {
- Text(text = "Class")
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ // description
+ Text(text = "Class", fontSize = 12.sp)
+ // separator
+ Spacer(modifier = Modifier.width(width = 12.dp))
+ // selector
+ Button(onClick = { areClassesExpanded.value = !areClassesExpanded.value }) {
// display the selected class, if selected
- if (selectedClass.value != null)
- Text(text = selectedClass.value!!.name)
+ if (selectedClass.value != null) Text(text = selectedClass.value!!.name)
+ else Text(text = "")
}
- }
- DropdownMenu(
- expanded = areClassesExpanded.value,
- onDismissRequest = { areClassesExpanded.value = false }
- ) {
- // TODO(Faraphel): student lists should be loaded from the database or a file
- classes.value?.forEach { class_ ->
- DropdownMenuItem(
- text = { Text(class_.name) },
- onClick = {
- selectedClass.value = class_
- areClassesExpanded.value = false
- }
- )
+
+ // class selector
+ DropdownMenu(
+ expanded = areClassesExpanded.value,
+ onDismissRequest = { areClassesExpanded.value = false }
+ ) {
+ // TODO(Faraphel): student lists should be loaded from the database or a file
+ classes.value?.forEach { class_ ->
+ DropdownMenuItem(
+ text = { Text(class_.name) },
+ onClick = {
+ selectedClass.value = class_
+ areClassesExpanded.value = false
+ }
+ )
+ }
}
}
// server port
- TextField(
- value = serverPort.intValue.toString(),
- keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
- onValueChange = { text ->
- val port = text.toInt()
- if (port in RANGE_SERVER_PORT) {
- serverPort.intValue = port
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ // descriptor
+ Text(text = "Port")
+ // separator
+ Spacer(modifier = Modifier.width(width = 12.dp))
+ // input
+ TextField(
+ modifier = Modifier.width(80.dp),
+ value = serverPort.intValue.toString(),
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
+ singleLine = true,
+ onValueChange = { text ->
+ val port = text.toInt()
+ if (port in RANGE_SERVER_PORT) {
+ serverPort.intValue = port
+ }
}
- }
- )
+ )
+ }
// check if a class is selected
if (selectedClass.value != null)
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/selection.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/selection.kt
index d95ea0b..646f783 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/selection.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/communication/selection.kt
@@ -4,12 +4,17 @@ import android.app.Activity
import android.os.Build
import android.widget.Toast
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@@ -58,7 +63,20 @@ fun CommunicationModeSelectionScreen(activity: Activity, database: TaskDatabase)
fun CommunicationSelectContent(controller: NavController, activity: Activity) {
val isWifiP2pSupported = BwfManager.isSupported(activity)
- Column {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(
+ text = "Connection Type",
+ fontSize = 32.sp
+ )
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// internet communication mode
Button(onClick = { controller.navigate("internet") }) {
Text("Internet")
@@ -68,7 +86,7 @@ fun CommunicationSelectContent(controller: NavController, activity: Activity) {
Button(
colors = ButtonDefaults.buttonColors(
// if the WiFi-Direct is not supported, the button is grayed out
- containerColor = if (isWifiP2pSupported) Color.Unspecified else Color.Gray
+ containerColor = if (isWifiP2pSupported) MaterialTheme.colorScheme.primary else Color.Gray
),
onClick = {
// if the WiFi-Direct is supported, navigate to the WiFi-Direct screen
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/session.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/session.kt
index d9dea02..3cbc7db 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/session.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/session.kt
@@ -4,13 +4,17 @@ import android.app.Activity
import android.os.Build
import android.widget.Toast
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.database.entities.PersonEntity
import com.google.gson.Gson
@@ -44,10 +48,25 @@ fun TaskSessionScreen(
selectedStudent.value!!
)
- Column {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(
+ text = "Session",
+ fontSize = 32.sp
+ )
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
+
// if the groups have already been defined, display them
for (student in students.value!!) {
- Button(onClick = { selectedStudent.value = student }) {
+ Button(
+ modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp, horizontal = 16.dp),
+ onClick = { selectedStudent.value = student },
+ ) {
Text(text = student.fullName())
}
}
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/student.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/student.kt
index e5c0005..57ac420 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/student.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/task/student.kt
@@ -5,8 +5,7 @@ import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
@@ -14,6 +13,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.connectivity.task.session.TaskPermission
import com.faraphel.tasks_valider.database.entities.*
@@ -25,7 +29,6 @@ import java.time.Instant
* This screen represent a student
* @param student the student object
*/
-@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun TaskStudentScreen(
activity: Activity,
@@ -47,8 +50,17 @@ fun TaskStudentScreen(
)
}.start()
- Column {
- Text(text = student.fullName())
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ // title
+ Text(text = "Student", fontSize = 32.sp)
+ // student name - subtitle
+ Text(text = student.fullName(), fontSize = 24.sp)
+
+ // separator
+ Spacer(modifier = Modifier.height(24.dp))
// if both the list of tasks and validations are loaded
if (!(tasks.value == null || validations.value == null)) {
@@ -56,22 +68,31 @@ fun TaskStudentScreen(
// get the validation
val validation = validations.value!!.firstOrNull { validation -> validation.taskId == task.id }
- Button(onClick = {}) {
+ Box(
+ modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 64.dp),
+ ) {
Row {
Column {
// task title
- Text(task.title)
+ Text(text = task.title, fontWeight = FontWeight.Bold)
// task description
task.description?.let { description -> Text(description) }
// if the task have been validated, show the date
if (validation != null) Text(validation.date.toString())
}
+
+ // separator
+ Spacer(modifier = Modifier.fillMaxWidth())
+
// the validation state
Checkbox(
checked = validation != null,
enabled = user.role.permissions.contains(TaskPermission.WRITE),
onCheckedChange = { state ->
Thread {
+ // TODO(Faraphel): simplify or put the UI refresh in the update function ?
+
+ // send a notification to the server about the validation
updateValidation(
client,
state,
@@ -82,6 +103,14 @@ fun TaskStudentScreen(
task.id,
)
)
+ // refresh the UI
+ refreshTasksValidations(
+ activity,
+ client,
+ student,
+ tasks,
+ validations
+ )
}.start()
}
)
diff --git a/app/src/main/java/com/faraphel/tasks_valider/utils/requests.kt b/app/src/main/java/com/faraphel/tasks_valider/utils/requests.kt
new file mode 100644
index 0000000..71f6fe9
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/utils/requests.kt
@@ -0,0 +1,22 @@
+package com.faraphel.tasks_valider.utils
+
+import fi.iki.elonen.NanoHTTPD
+import java.nio.charset.Charset
+
+
+/**
+ * Return the body of a request as a string.
+ * :param charset: the encoding of the body
+ */
+fun NanoHTTPD.IHTTPSession.getBody(
+ charset: Charset = Charset.forName("UTF-8")
+): String {
+ // get the length of the body
+ val length = this.headers["content-length"]!!.toInt()
+ // prepare a buffer for the body
+ val buffer = ByteArray(length)
+ // read the body into the buffer
+ this.inputStream.read(buffer, 0, length)
+ // convert that buffer into a string
+ return buffer.toString(charset)
+}