diff --git a/app/build.gradle b/app/build.gradle index 23d01bd..4fdfb4c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,10 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' implementation 'androidx.navigation:navigation-ui-ktx:2.5.3' + implementation 'com.squareup.moshi:moshi:1.14.0' + implementation 'com.squareup.moshi:moshi-kotlin:1.14.0' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/FileListAdapter.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/FileListAdapter.kt index 9eb9148..0339bc7 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/FileListAdapter.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/FileListAdapter.kt @@ -24,7 +24,7 @@ class FileListAdapter(private val dataSet: List, private val onCl } fun bind(file: VersionedFile) { - fileNameView.text = file.fileName + fileNameView.text = file.name currentFile = file } } diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/MainActivity.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/MainActivity.kt index de6b6dc..9e39ce3 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/MainActivity.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/MainActivity.kt @@ -3,35 +3,38 @@ package fr.uca.iut.clfreville2.teaiswarm import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import fr.uca.iut.clfreville2.teaiswarm.model.Repository +import fr.uca.iut.clfreville2.teaiswarm.network.GiteaService +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +const val REPOSITORY_OWNER = "repository_owner" const val REPOSITORY_NAME = "repository_name" class MainActivity : AppCompatActivity() { + private val service = GiteaService() private lateinit var repositories: RecyclerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) repositories = findViewById(R.id.repositories_view) - repositories.adapter = RepositoryListAdapter( - listOf( - "oki", - "moshell", - "scrabble-with-numbers", - "vdn-tools", - "codefirst-test", - "iut-config", - "Ebullition" - ).map { Repository(it, 0) }) { repo -> - adapterOnClick(repo) + lifecycleScope.launch(Dispatchers.IO) { + val repos = service.listActiveRepositories("clement.freville2", 1) + lifecycleScope.launch { + repositories.adapter = RepositoryListAdapter(repos) { repo -> + adapterOnClick(repo) + } + } } } private fun adapterOnClick(repository: Repository) { val intent = Intent(this, RepositoryDetailActivity()::class.java) + intent.putExtra(REPOSITORY_OWNER, repository.owner.login) intent.putExtra(REPOSITORY_NAME, repository.name) startActivity(intent) } diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/RepositoryDetailActivity.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/RepositoryDetailActivity.kt index 3daa9aa..12cd7f1 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/RepositoryDetailActivity.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/RepositoryDetailActivity.kt @@ -3,11 +3,16 @@ package fr.uca.iut.clfreville2.teaiswarm import android.os.Bundle import android.widget.TextView import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView -import fr.uca.iut.clfreville2.teaiswarm.model.VersionedFile +import fr.uca.iut.clfreville2.teaiswarm.model.RepositoryIdentifier +import fr.uca.iut.clfreville2.teaiswarm.network.GiteaService +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class RepositoryDetailActivity : AppCompatActivity() { + private val service = GiteaService() private lateinit var repositoryName: TextView private lateinit var versionedFiles: RecyclerView @@ -17,9 +22,11 @@ class RepositoryDetailActivity : AppCompatActivity() { repositoryName = findViewById(R.id.repository_detail_name) + var currentRepositoryOwner: String? = null var currentRepositoryName: String? = null val bundle: Bundle? = intent.extras if (bundle != null) { + currentRepositoryOwner = bundle.getString(REPOSITORY_OWNER) currentRepositoryName = bundle.getString(REPOSITORY_NAME) } @@ -28,18 +35,11 @@ class RepositoryDetailActivity : AppCompatActivity() { } versionedFiles = findViewById(R.id.versioned_files_view) - versionedFiles.adapter = FileListAdapter( - listOf( - "cli", - "doc", - "sql", - "test", - "web", - ".drone.yml", - ".gitignore", - "CONVENTIONS.md", - "README.md" - ).map { VersionedFile(it) } - ) {} + lifecycleScope.launch(Dispatchers.IO) { + val repos = service.listFileContents(RepositoryIdentifier(currentRepositoryOwner!!, currentRepositoryName!!), "") + lifecycleScope.launch { + versionedFiles.adapter = FileListAdapter(repos) {} + } + } } } diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Owner.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Owner.kt new file mode 100644 index 0000000..75e2c20 --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Owner.kt @@ -0,0 +1,3 @@ +package fr.uca.iut.clfreville2.teaiswarm.model + +data class Owner(val id: Int, val login: String) diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Repository.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Repository.kt index 9c474a7..372d4f4 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Repository.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/Repository.kt @@ -1,3 +1,3 @@ package fr.uca.iut.clfreville2.teaiswarm.model -data class Repository(val name: String, val stars: Int) +data class Repository(val owner: Owner, val name: String, val stars: Int = 0) diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifiable.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifiable.kt new file mode 100644 index 0000000..e8d56aa --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifiable.kt @@ -0,0 +1,6 @@ +package fr.uca.iut.clfreville2.teaiswarm.model + +interface RepositoryIdentifiable { + + val identifier: RepositoryIdentifier +} \ No newline at end of file diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifier.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifier.kt new file mode 100644 index 0000000..96a4b2d --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/RepositoryIdentifier.kt @@ -0,0 +1,7 @@ +package fr.uca.iut.clfreville2.teaiswarm.model + +data class RepositoryIdentifier(val owner: String, val name: String) : RepositoryIdentifiable { + + override val identifier: RepositoryIdentifier + get() = this +} diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/VersionedFile.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/VersionedFile.kt index 5e36a41..5e89a5a 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/VersionedFile.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/model/VersionedFile.kt @@ -1,3 +1,3 @@ package fr.uca.iut.clfreville2.teaiswarm.model -data class VersionedFile(val fileName: String) +data class VersionedFile(val name: String) diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt new file mode 100644 index 0000000..8bd570f --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt @@ -0,0 +1,48 @@ +package fr.uca.iut.clfreville2.teaiswarm.network + +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory + +import fr.uca.iut.clfreville2.teaiswarm.model.Repository +import fr.uca.iut.clfreville2.teaiswarm.model.RepositoryIdentifiable +import fr.uca.iut.clfreville2.teaiswarm.model.VersionedFile +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Query + +interface GiteaApiService { + + @GET("users/{username}/repos") + suspend fun listActiveRepositories(@Path("username") username: String, @Query("page") page: Int): List + + @GET("repos/{owner}/{repo}/contents/{filePath}") + suspend fun listFileContents(@Path("owner") owner: String, @Path("repo") repo: String, @Path("filePath") filePath: String): List +} + +class GiteaService(private val handle: GiteaApiService) : RepositoryService { + + constructor() : this(createRetrofit().create(GiteaApiService::class.java)) + + override suspend fun listActiveRepositories(username: String, page: Int): List = + handle.listActiveRepositories(username, page) + + override suspend fun listFileContents(repository: RepositoryIdentifiable, filePath: String): List = + handle.listFileContents(repository.identifier.owner, repository.identifier.name, filePath) +} + +private const val CODEFIRST_API_BASE = "https://codefirst.iut.uca.fr/git/api/v1/" + +private val httpClient = OkHttpClient() + +private fun createRetrofit(): Retrofit = + Retrofit.Builder() + .baseUrl(CODEFIRST_API_BASE) + .addConverterFactory(MoshiConverterFactory.create( + Moshi.Builder() + .add(KotlinJsonAdapterFactory()) + .build())) + .client(httpClient) + .build() diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/RepositoryService.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/RepositoryService.kt new file mode 100644 index 0000000..944ad28 --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/RepositoryService.kt @@ -0,0 +1,12 @@ +package fr.uca.iut.clfreville2.teaiswarm.network + +import fr.uca.iut.clfreville2.teaiswarm.model.Repository +import fr.uca.iut.clfreville2.teaiswarm.model.RepositoryIdentifiable +import fr.uca.iut.clfreville2.teaiswarm.model.VersionedFile + +interface RepositoryService { + + suspend fun listActiveRepositories(username: String, page: Int): List + + suspend fun listFileContents(repository: RepositoryIdentifiable, filePath: String): List +} diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/StubRepositoryService.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/StubRepositoryService.kt new file mode 100644 index 0000000..a612cb8 --- /dev/null +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/StubRepositoryService.kt @@ -0,0 +1,43 @@ +package fr.uca.iut.clfreville2.teaiswarm.network + +import fr.uca.iut.clfreville2.teaiswarm.model.Owner +import fr.uca.iut.clfreville2.teaiswarm.model.Repository +import fr.uca.iut.clfreville2.teaiswarm.model.RepositoryIdentifiable +import fr.uca.iut.clfreville2.teaiswarm.model.VersionedFile + +class StubRepositoryService : RepositoryService { + + override suspend fun listActiveRepositories(username: String, page: Int): List = + when (page) { + 1 -> listOf( + "oki", + "moshell", + "scrabble-with-numbers", + "vdn-tools", + "codefirst-test", + "iut-config", + "Ebullition" + ) + 2 -> listOf( + "api-ef", + "codefirst-docdeployer", + "TeaIsWarm", + "Application", + "silex" + ) + else -> listOf() + }.map { Repository(Owner(-1, ""), it) } + + override suspend fun listFileContents(repository: RepositoryIdentifiable, filePath: String) = + listOf( + "cli", + "doc", + "sql", + "test", + "web", + ".drone.yml", + ".gitignore", + "CONVENTIONS.md", + "README.md" + ).map { VersionedFile(it) } +}