diff --git a/.gitignore b/.gitignore index aa724b7..643d213 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx -local.properties +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore index 26d3352..eaf91e2 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,3 +1,3 @@ -# Default ignored files -/shelf/ -/workspace.xml +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index b589d56..8fabff5 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef3..b153300 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -1,10 +1,18 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 32522c1..0b0534c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,18 +1,19 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 44ca2d9..d023ca6 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,41 +1,41 @@ - - - + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index fdf8d99..356aa17 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml index f8051a6..48052b2 100644 --- a/.idea/migrations.xml +++ b/.idea/migrations.xml @@ -1,10 +1,10 @@ - - - - - + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 0ad17cb..8978d23 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..9661ac7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/README.md b/README.md index b4bcd35..b4b0813 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# Projet de caméra timelapse - -## Partie frontend du projet (Raph) - -Cahier des charges : - -- [ ] réaliser un frontend -- [ ] trois volets : accueil, vidéo et métriques -- [ ] bouton lancement de la vidéo -- [ ] redimensionnement de la période de récupération des données -- [ ] capacité de choisir quand sa vidéo commence, se déplacer dans la vidéo -- [ ] lancement et arrêt de de la caméra à distance -- [ ] schedule de la prise de caméra - +# Projet de caméra timelapse + +## Partie frontend du projet (Raph) + +Cahier des charges : + +- [ ] réaliser un frontend +- [ ] trois volets : accueil, vidéo et métriques +- [ ] bouton lancement de la vidéo +- [ ] redimensionnement de la période de récupération des données +- [ ] capacité de choisir quand sa vidéo commence, se déplacer dans la vidéo +- [ ] lancement et arrêt de de la caméra à distance +- [ ] schedule de la prise de caméra + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index eaf0f4f..c670454 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,69 +1,80 @@ -plugins { - alias(libs.plugins.android.application) - alias(libs.plugins.jetbrains.kotlin.android) -} - -android { - namespace = "com.dreamteam.timelapse" - compileSdk = 34 - - defaultConfig { - applicationId = "com.dreamteam.timelapse" - minSdk = 28 - targetSdk = 34 - versionCode = 1 - versionName = "1.0" - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary = true - } - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = "1.8" - } - buildFeatures { - compose = true - } - composeOptions { - kotlinCompilerExtensionVersion = "1.5.1" - } - packaging { - resources { - excludes += "/META-INF/{AL2.0,LGPL2.1}" - } - } -} - -dependencies { - - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.lifecycle.runtime.ktx) - implementation(libs.androidx.activity.compose) - implementation(platform(libs.androidx.compose.bom)) - implementation(libs.androidx.ui) - implementation(libs.androidx.ui.graphics) - implementation(libs.androidx.ui.tooling.preview) - implementation(libs.androidx.material3) - testImplementation(libs.junit) - androidTestImplementation(libs.androidx.junit) - androidTestImplementation(libs.androidx.espresso.core) - androidTestImplementation(platform(libs.androidx.compose.bom)) - androidTestImplementation(libs.androidx.ui.test.junit4) - debugImplementation(libs.androidx.ui.tooling) - debugImplementation(libs.androidx.ui.test.manifest) +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.jetbrains.kotlin.android) +} + +android { + namespace = "com.dreamteam.timelapse" + compileSdk = 34 + + defaultConfig { + applicationId = "com.dreamteam.timelapse" + minSdk = 28 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + viewBinding = true + dataBinding = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.5.1" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.material) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.navigation.fragment.ktx) + implementation(libs.androidx.navigation.ui.ktx) + implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") + implementation("com.squareup.retrofit2:retrofit:2.9.0") //internet, api etc... + implementation("com.squareup.retrofit2:converter-gson:2.9.0") // Si tu veux utiliser Gson pour la sérialisation + implementation("com.squareup.okhttp3:logging-interceptor:4.9.0") // Pour le logging + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..64b4a05 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. #-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/dreamteam/timelapse/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/dreamteam/timelapse/ExampleInstrumentedTest.kt index 9a3246f..5d241ff 100644 --- a/app/src/androidTest/java/com/dreamteam/timelapse/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/dreamteam/timelapse/ExampleInstrumentedTest.kt @@ -1,24 +1,24 @@ -package com.dreamteam.timelapse - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.dreamteam.timelapse", appContext.packageName) - } +package com.dreamteam.timelapse + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.dreamteam.timelapse", appContext.packageName) + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3512377..534a1c4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,28 +1,28 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/CustomSwipeRefreshLayout.kt b/app/src/main/java/com/dreamteam/timelapse/CustomSwipeRefreshLayout.kt new file mode 100644 index 0000000..6842144 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/CustomSwipeRefreshLayout.kt @@ -0,0 +1,18 @@ +package com.dreamteam.timelapse + +import android.content.Context +import android.util.AttributeSet +import android.util.Log +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout + +class CustomSwipeRefreshLayout(context: Context, attrs: AttributeSet) : SwipeRefreshLayout(context, attrs) { + init { + Log.d("CustomSwipeRefreshLayout", "CustomSwipeRefreshLayout instancié") + } + override fun canChildScrollUp(): Boolean { + // Vérifie si l'enfant direct (RecyclerView par exemple) peut encore scroller vers le haut + val view = getChildAt(0) + //Log.i("CustomSwipeRefreshLayout", "canChildScrollUp: ${view?.canScrollVertically(-1)}") + return view != null && view.canScrollVertically(-1) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt b/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt index 121935b..7895cfb 100644 --- a/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt +++ b/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt @@ -1,47 +1,79 @@ package com.dreamteam.timelapse +import android.R +import com.dreamteam.timelapse.R as Rtmp import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import com.dreamteam.timelapse.ui.theme.TimelapseTheme +import android.util.Log +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import androidx.viewpager2.widget.ViewPager2 +import com.dreamteam.timelapse.databinding.ActivityMainBinding +import com.google.android.material.snackbar.Snackbar +import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator + + +class MainActivity : AppCompatActivity() { + + private lateinit var appBarConfiguration: AppBarConfiguration + private lateinit var binding: ActivityMainBinding -class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { +// super.onCreate(savedInstanceState) +// + + Log.d("mainActivity", "La main activity est créée") + + +// setSupportActionBar(binding.toolbar) +// super.onCreate(savedInstanceState) - enableEdgeToEdge() - setContent { - TimelapseTheme { - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - Greeting( - name = "caca prout", - modifier = Modifier.padding(innerPadding) - ) - } + //val navController = findNavController(R.id.nav_host_fragment_content_main) + //appBarConfiguration = AppBarConfiguration(navController.graph) + //setupActionBarWithNavController(navController, appBarConfiguration) + + // R.layout contient : + // - un TabLayout avec l'id tabLayout + // - un ViewPager2 avec l'id viewPager + // - un FloatingActionButton avec l'id fab + + //setContentView(R.layout.activity_main) + //ce qui corrigé donne : + setContentView(Rtmp.layout.activity_main) + val tabLayout = findViewById(Rtmp.id.tabLayout) as TabLayout + val viewPager = findViewById(Rtmp.id.viewPager) as ViewPager2 + + + // Configurer l'adapter pour ViewPager2 + var tabsAdapter = TabsAdapter(this) + viewPager.setAdapter(tabsAdapter) + + + // Connecter le ViewPager au TabLayout + TabLayoutMediator( + tabLayout, viewPager + ) { tab: TabLayout.Tab, position: Int -> + when (position) { + 0 -> tab.setText("Mes projets") // Nom du premier onglet + 1 -> tab.setText("Mes vidéos") // Nom du second onglet } - } - } -} + }.attach() -@Composable -fun Greeting(name: String, modifier: Modifier = Modifier) { - Text( - text = "Hello $name!", - modifier = modifier - ) -} - -@Preview(showBackground = true) -@Composable -fun GreetingPreview() { - TimelapseTheme { - Greeting("Android") + // Bouton flottant +// binding.fab.setOnClickListener { view -> +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) +// //.setAction("Action", null) //sert à rien +// .setAnchorView(R.id.fab).show() //au dessus du bouton mail +// } } + +// override fun onSupportNavigateUp(): Boolean { +// val navController = findNavController(R.id.nav_host_fragment_content_main) +// return navController.navigateUp(appBarConfiguration) +// || super.onSupportNavigateUp() +// } } \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/Project.kt b/app/src/main/java/com/dreamteam/timelapse/Project.kt new file mode 100644 index 0000000..c12b2ae --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/Project.kt @@ -0,0 +1,23 @@ +package com.dreamteam.timelapse + +import java.util.Date + +//{ +// "id": 1, +// "creation": "2024-10-24T13:46:04.513Z", +// "status": "test", +// "description": "Projet de Test", +// "titre": "Test Project" +//} +data class Project ( + val id: Int, + val creation: Date, + val status: String, + val description: String, + val titre: String, + val thumbnail_url: String? +) { +// fun getThumbnail(): String { +// return images[0] +// } +} diff --git a/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt b/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt new file mode 100644 index 0000000..1b0527b --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt @@ -0,0 +1,30 @@ +package com.dreamteam.timelapse + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class ProjectAdapter(private val projects: List) : RecyclerView.Adapter() { + + class ProjectViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val projectTitle: TextView = itemView.findViewById(R.id.projectTitle) + } + + //crée les éléments dans le fragment + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_project_card, parent, false) + return ProjectViewHolder(view) + } + + // Remplit le ViewHolder avec les données + override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) { + val project = projects[position] + holder.projectTitle.text = project.titre // Affiche le titre du projet + } + + override fun getItemCount(): Int { + return projects.size + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/ProjetsFrag.kt b/app/src/main/java/com/dreamteam/timelapse/ProjetsFrag.kt new file mode 100644 index 0000000..3d7e5b7 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/ProjetsFrag.kt @@ -0,0 +1,102 @@ +package com.dreamteam.timelapse + +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ListView +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.dreamteam.timelapse.data.ProjectRepository +import com.dreamteam.timelapse.databinding.FragmentProjetsBinding +import com.dreamteam.timelapse.databinding.FragmentVideosBinding +import kotlinx.coroutines.delay +import com.dreamteam.timelapse.data.ApiService +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +/** + * A simple [Fragment] subclass as the default destination in the navigation. + */ + +class ProjetsFrag : Fragment() { + + private lateinit var projectRepository: ProjectRepository + //private lateinit var listView: ListView + private lateinit var recyclerView: RecyclerView + private lateinit var projectAdapter: ProjectAdapter + private var _binding: FragmentProjetsBinding? = null + private val binding get() = _binding!! + + private lateinit var apiService: ApiService // Déclare l'apiService + private var projects: List = emptyList() // Déclare une liste de projets vide + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // Initialiser apiService ici, par exemple, en utilisant Retrofit + val retrofit = Retrofit.Builder() + .baseUrl("https://timelapse.kerboul.me/api/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + apiService = retrofit.create(ApiService::class.java) // Crée une instance d'ApiService + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + Log.d("ProjetsFrag", "Fragment Projets créé") + _binding = FragmentProjetsBinding.inflate(inflater, container, false) + + projectRepository = ProjectRepository(apiService) // Tu initialises ton repository + fetchProjects() + + return _binding?.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val swipeRefreshLayout = binding.swipeRefreshLayout + + swipeRefreshLayout.setOnRefreshListener { + fetchProjects() + Log.d("ProjetsFrag", "Actualisation des projets") + } + + recyclerView = binding.recyclerView // view.findViewById(R.id.recyclerView) + recyclerView.layoutManager = LinearLayoutManager(context) + + + } + + private fun fetchProjects() { + // Simulez l'appel API + binding.swipeRefreshLayout.isRefreshing = true + + Log.d("ProjetsFrag", "User has refreshed the projects list") + projectRepository.fetchProjects( + onSuccess = { projects -> + Log.d("ProjetsFrag", "Projets reçus : $projects") + this.projects = projects + this.projectAdapter = ProjectAdapter(this.projects) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir) + this.recyclerView.adapter = this.projectAdapter + // Mettre à jour le RecyclerView ou autre traitement + }, + onError = { errorMessage -> + Log.e("ProjetsFrag", errorMessage) + } + ) + binding.swipeRefreshLayout.isRefreshing = false + } + +// override fun onDestroyView() { +// super.onDestroyView() +// _binding = null +// } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/RetrofitClient.kt b/app/src/main/java/com/dreamteam/timelapse/RetrofitClient.kt new file mode 100644 index 0000000..0a27a3b --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/RetrofitClient.kt @@ -0,0 +1,18 @@ +package com.dreamteam.timelapse + +import com.dreamteam.timelapse.data.ApiService +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object RetrofitClient { + private const val BASE_URL = "https://timelapse.kerbou.me/api/" // Remplace par l'URL de base de ton API + + val instance: ApiService by lazy { + val retrofit = Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + retrofit.create(ApiService::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/TabsAdapter.kt b/app/src/main/java/com/dreamteam/timelapse/TabsAdapter.kt new file mode 100644 index 0000000..f425858 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/TabsAdapter.kt @@ -0,0 +1,20 @@ +package com.dreamteam.timelapse + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class TabsAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) { + + override fun getItemCount(): Int { + return 2 // Nombre total d'onglets + } + + override fun createFragment(position: Int): Fragment { + return when (position) { + 0 -> ProjetsFrag() // Premier fragment + 1 -> VideoFrag() // Second fragment + else -> ProjetsFrag() // Par défaut + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/VideoFrag.kt b/app/src/main/java/com/dreamteam/timelapse/VideoFrag.kt new file mode 100644 index 0000000..8824bc9 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/VideoFrag.kt @@ -0,0 +1,44 @@ +package com.dreamteam.timelapse + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.navigation.fragment.findNavController +import com.dreamteam.timelapse.databinding.FragmentVideosBinding + +/** + * A simple [Fragment] subclass as the second destination in the navigation. + */ +class VideoFrag : Fragment() { + + private var _binding: FragmentVideosBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + + _binding = FragmentVideosBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.buttonSecond.setOnClickListener { + findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt b/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt new file mode 100644 index 0000000..649da09 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt @@ -0,0 +1,9 @@ +package com.dreamteam.timelapse.data +import com.dreamteam.timelapse.Project +import retrofit2.Call +import retrofit2.http.GET + +interface ApiService { + @GET("itemsdb") // Remplace par l'endpoint de ton API + fun getProjets(): Call> +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt b/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt new file mode 100644 index 0000000..705ac57 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt @@ -0,0 +1,29 @@ +package com.dreamteam.timelapse.data + +import com.dreamteam.timelapse.Project +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class ProjectRepository(private val apiService: ApiService) { + + fun fetchProjects(onSuccess: (List) -> Unit, onError: (String) -> Unit) { + val call = apiService.getProjets() + call.enqueue(object : Callback> { + override fun onResponse(call: Call>, response: Response>) { + if (response.isSuccessful) { + val projects = response.body() + projects?.let { + onSuccess(it) + } ?: onError("Aucun projet trouvé") + } else { + onError("Erreur : ${response.code()}") + } + } + + override fun onFailure(call: Call>, t: Throwable) { + onError("Échec de l'appel API : ${t.message}") + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Color.kt b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Color.kt index 611cc9c..dc85e18 100644 --- a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Color.kt +++ b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Color.kt @@ -1,11 +1,11 @@ -package com.dreamteam.timelapse.ui.theme - -import androidx.compose.ui.graphics.Color - -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) - -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) +package com.dreamteam.timelapse.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Theme.kt b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Theme.kt index de2b0ae..c9b5e3f 100644 --- a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Theme.kt +++ b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Theme.kt @@ -1,58 +1,58 @@ -package com.dreamteam.timelapse.ui.theme - -import android.app.Activity -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext - -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) - -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) - -@Composable -fun TimelapseTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = true, - content: @Composable () -> Unit -) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - - darkTheme -> DarkColorScheme - else -> LightColorScheme - } - - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content - ) +package com.dreamteam.timelapse.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun TimelapseTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) } \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Type.kt b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Type.kt index 9f6fb50..5d5a8c2 100644 --- a/app/src/main/java/com/dreamteam/timelapse/ui/theme/Type.kt +++ b/app/src/main/java/com/dreamteam/timelapse/ui/theme/Type.kt @@ -1,34 +1,34 @@ -package com.dreamteam.timelapse.ui.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ +package com.dreamteam.timelapse.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ ) \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..a4f78de 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 2b068d1..cc14f03 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,30 +1,30 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..307b3c5 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_projets.xml b/app/src/main/res/layout/fragment_projets.xml new file mode 100644 index 0000000..44d43de --- /dev/null +++ b/app/src/main/res/layout/fragment_projets.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_videos.xml b/app/src/main/res/layout/fragment_videos.xml new file mode 100644 index 0000000..b22a705 --- /dev/null +++ b/app/src/main/res/layout/fragment_videos.xml @@ -0,0 +1,35 @@ + + + + + +