Merge pull request 'API_NextStep' (#8) from API_NextStep into master
continuous-integration/drone/push Build is passing Details

Reviewed-on: #8
pull/10/head
Emre KARTAL 2 years ago
commit a5e07309ba

@ -8,12 +8,17 @@ trigger:
steps: steps:
- name: code-analysis - name: code-analysis
image: androidsdk/android-31 image: openjdk:8-jdk
environment: environment:
SONAR_TOKEN: SONAR_TOKEN:
from_secret: SECRET_TOKEN from_secret: SECRET_TOKEN
settings: settings:
sources: ./src/ sources: ./src/
commands: commands:
- cd src - export SONAR_SCANNER_VERSION=4.7.0.2747
- ./gradlew --no-daemon :app:assembleDebug sonarqube -Dsonar.projectKey=Scor_It -Dsonar.host.url=https://codefirst.iut.uca.fr/sonar -Dsonar.login=$${SONAR_TOKEN} - export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
- curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -D sonar.projectKey=Scor_It -D sonar.sources=./src -D sonar.host.url=https://codefirst.iut.uca.fr/sonar

@ -45,7 +45,7 @@ dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0' implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

@ -10,8 +10,6 @@ import kotlinx.coroutines.coroutineScope
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import uca.iut.clermont.model.* import uca.iut.clermont.model.*
import java.text.SimpleDateFormat
import java.util.*
val retrofit: Retrofit = Retrofit.Builder() val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("https://api.football-data.org/v4/") .baseUrl("https://api.football-data.org/v4/")
@ -29,29 +27,26 @@ class ApiManager : DataManager() {
class ApiAreaManager : AreaManager { class ApiAreaManager : AreaManager {
override fun getItemsByName(substring: String): List<Area> { override suspend fun getItemsByName(substring: String): List<Area> = coroutineScope {
TODO("Not yet implemented") val areas = footballApi.getAreas()
return@coroutineScope areas.areas.filter { it.name.contains(substring) }
} }
override suspend fun getItems(): List<Area> { override suspend fun getItems(): List<Area> = coroutineScope {
TODO("Not yet implemented") val areas = footballApi.getAreas()
return@coroutineScope areas.areas
} }
override suspend fun getItemById(id: Int): Area? { override suspend fun getItemById(id: Int): Area = coroutineScope {
TODO("Not yet implemented") val area = footballApi.getArea(id)
return@coroutineScope area
} }
} }
class ApiPeopleManager : PeopleManager { class ApiPeopleManager : PeopleManager {
override fun getItemsByName(substring: String): List<Personne> { override suspend fun getItems(): List<Personne> = listOf()
TODO("Not yet implemented")
}
override suspend fun getItems(): List<Personne> {
TODO("Not yet implemented")
}
override suspend fun getItemById(id: Int): Personne? = coroutineScope { override suspend fun getItemById(id: Int): Personne? = coroutineScope {
val personne = footballApi.getPlayer(id) val personne = footballApi.getPlayer(id)
@ -63,12 +58,16 @@ class ApiManager : DataManager() {
} }
class ApiMatchesManager : MatchesManager { class ApiMatchesManager : MatchesManager {
override fun getNbItemsByCompetition(substring: String): Int {
TODO("Not yet implemented") override suspend fun getNbItemsByCompetition(id: Int): Int = coroutineScope {
val matches = footballApi.getMatchesByCompetition(id)
return@coroutineScope matches.matches.size
} }
override fun getItemsByCompetition(substring: String): List<Match> { override suspend fun getItemsByCompetition(id: Int): List<Match> =
TODO("Not yet implemented") coroutineScope {
val matches = footballApi.getMatchesByCompetition(id)
return@coroutineScope matches.matches.map { it.toModel() }
} }
override suspend fun getItems(): List<Match> = coroutineScope { override suspend fun getItems(): List<Match> = coroutineScope {
@ -76,29 +75,36 @@ class ApiManager : DataManager() {
return@coroutineScope matches.matches.map { matchResult -> matchResult.toModel() } return@coroutineScope matches.matches.map { matchResult -> matchResult.toModel() }
} }
override suspend fun getItemById(id: Int): Match? { override suspend fun getItemById(id: Int): Match = coroutineScope {
TODO("Not yet implemented") val match = footballApi.getMatch(id)
return@coroutineScope match.toModel()
} }
} }
class ApiCompetitionsManager : CompetitionsManager { class ApiCompetitionsManager : CompetitionsManager {
override fun getItemsByName(substring: String): List<Competition> {
TODO("Not yet implemented") override suspend fun getItemsByName(substring: String): List<Competition> = coroutineScope {
val competitons = footballApi.getCompetitions()
return@coroutineScope competitons.competitions.map { competitionResult -> competitionResult.toModel() }
.filter { it.name == substring }
} }
override suspend fun getItems(): List<Competition> = coroutineScope { override suspend fun getItems(): List<Competition> = coroutineScope {
val competitons = footballApi.getCompetitions() val competitons = footballApi.getCompetitions()
return@coroutineScope competitons.competitions.map { competitionResult -> competitionResult.toModel() }.sortedBy { it.name } return@coroutineScope competitons.competitions.map { competitionResult -> competitionResult.toModel() }
.sortedBy { it.name }
} }
override suspend fun getItemById(id: Int): Competition? { override suspend fun getItemById(id: Int): Competition = coroutineScope {
TODO("Not yet implemented") val competition = footballApi.getCompetition(id)
return@coroutineScope competition.toModel()
} }
} }
class ApiTeamsManager : TeamsManager { class ApiTeamsManager : TeamsManager {
override fun getItemsByName(substring: String): List<Team> { override fun getItemsByName(substring: String): List<Team> {
TODO("Not yet implemented") TODO("Not yet implemented")
} }

@ -3,29 +3,46 @@ package uca.iut.clermont.api
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Headers import retrofit2.http.Headers
import retrofit2.http.Path import retrofit2.http.Path
import uca.iut.clermont.api.response.areaResponse.AreaResponse
import uca.iut.clermont.api.response.competitionResponse.CompetitionResponse import uca.iut.clermont.api.response.competitionResponse.CompetitionResponse
import uca.iut.clermont.api.response.competitionResponse.CompetitionResult
import uca.iut.clermont.api.response.matchResponse.MatchResponse import uca.iut.clermont.api.response.matchResponse.MatchResponse
import uca.iut.clermont.api.response.matchResponse.MatchResult
import uca.iut.clermont.model.Area import uca.iut.clermont.model.Area
import uca.iut.clermont.model.PlayerResponse import uca.iut.clermont.model.PlayerResponse
interface FootballApi { interface FootballApi {
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("areas/{id}")
suspend fun getArea(@Path("id") id: Int): Area
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("areas") @GET("areas")
suspend fun getAreas(): List<Area> suspend fun getAreas(): AreaResponse
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57") @Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("persons/{id}") @GET("persons/{id}")
suspend fun getPlayer(@Path("id") playerId: Int): PlayerResponse suspend fun getPlayer(@Path("id") playerId: Int): PlayerResponse
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57") @Headers("X-Auth-Token: 621ef06e148542f98b4993a5442421eb")
@GET("persons")
suspend fun getPlayers(): List<PlayerResponse>
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("competitions") @GET("competitions")
suspend fun getCompetitions(): CompetitionResponse suspend fun getCompetitions(): CompetitionResponse
@Headers("X-Auth-Token: 8f51b43de0444026bd3ec3484f082575")
@GET("competitions/{id}")
suspend fun getCompetition(@Path("id") id: Int): CompetitionResult
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57") @Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("matches") @GET("matches")
suspend fun getMatches(): MatchResponse suspend fun getMatches(): MatchResponse
@Headers("X-Auth-Token: 621ef06e148542f98b4993a5442421eb")
@GET("matches/{id}")
suspend fun getMatch(@Path("id") id: Int): MatchResult
@Headers("X-Auth-Token: b002ff114afa41a590e2baef63d8c689")
@GET("competitions/{id}/matches")
suspend fun getMatchesByCompetition(@Path("id") id: Int): MatchResponse
} }

@ -0,0 +1,8 @@
package uca.iut.clermont.api.response.areaResponse
import uca.iut.clermont.model.Area
data class AreaResponse(
val areas: List<Area>,
val count: Int
)

@ -246,7 +246,7 @@ class StubData : DataManager() {
) )
) )
private val random = java.util.Random() private val random = Random()
val matchList: MutableList<Match> = mutableListOf() val matchList: MutableList<Match> = mutableListOf()
fun initMatches() { fun initMatches() {
@ -421,7 +421,7 @@ class StubData : DataManager() {
class StubAreaManager(private val parent: StubData) : AreaManager { class StubAreaManager(private val parent: StubData) : AreaManager {
override fun getItemsByName(substring: String) = override suspend fun getItemsByName(substring: String) =
parent.areaList.filter { it.name.contains(substring, ignoreCase = true) } parent.areaList.filter { it.name.contains(substring, ignoreCase = true) }
override suspend fun getItems(): List<Area> = parent.areaList override suspend fun getItems(): List<Area> = parent.areaList
@ -431,8 +431,6 @@ class StubData : DataManager() {
} }
class StubPeopleManager(private val parent: StubData) : PeopleManager { class StubPeopleManager(private val parent: StubData) : PeopleManager {
override fun getItemsByName(substring: String) =
parent.peopleList.filter { it.name.contains(substring, ignoreCase = true) }
override suspend fun getItems() = parent.peopleList override suspend fun getItems() = parent.peopleList
@ -440,11 +438,12 @@ class StubData : DataManager() {
} }
class StubMatchesManager(private val parent: StubData) : MatchesManager { class StubMatchesManager(private val parent: StubData) : MatchesManager {
override fun getNbItemsByCompetition(substring: String) =
parent.matchList.filter { it.competition.name.contains(substring) }.count()
override fun getItemsByCompetition(substring: String) = override suspend fun getNbItemsByCompetition(id: Int) =
parent.matchList.filter { it.competition.name.contains(substring) } parent.matchList.filter { it.competition.id == id }.size
override suspend fun getItemsByCompetition(id: Int) =
parent.matchList.filter { it.competition.id == id }
override suspend fun getItems(): List<Match> = parent.matchList override suspend fun getItems(): List<Match> = parent.matchList
@ -453,7 +452,7 @@ class StubData : DataManager() {
} }
class StubCompetitionsManager(private val parent: StubData) : CompetitionsManager { class StubCompetitionsManager(private val parent: StubData) : CompetitionsManager {
override fun getItemsByName(substring: String) = override suspend fun getItemsByName(substring: String) =
parent.competitionList.filter { it.name.contains(substring, ignoreCase = true) } parent.competitionList.filter { it.name.contains(substring, ignoreCase = true) }
override suspend fun getItems() = parent.competitionList override suspend fun getItems() = parent.competitionList

@ -9,22 +9,20 @@ abstract class DataManager {
} }
interface AreaManager : GenericDataManager<Area> { interface AreaManager : GenericDataManager<Area> {
fun getItemsByName(substring: String): List<Area> suspend fun getItemsByName(substring: String): List<Area>
} }
interface PeopleManager : GenericDataManager<Personne> { interface PeopleManager : GenericDataManager<Personne> {}
fun getItemsByName(substring: String): List<Personne>
}
interface MatchesManager : GenericDataManager<Match> { interface MatchesManager : GenericDataManager<Match> {
fun getNbItemsByCompetition(substring: String): Int suspend fun getNbItemsByCompetition(id: Int): Int
fun getItemsByCompetition(substring: String): List<Match> suspend fun getItemsByCompetition(id: Int): List<Match>
} }
interface CompetitionsManager : GenericDataManager<Competition> { interface CompetitionsManager : GenericDataManager<Competition> {
fun getItemsByName(substring: String): List<Competition> suspend fun getItemsByName(substring: String): List<Competition>
} }
interface TeamsManager : GenericDataManager<Team> { interface TeamsManager : GenericDataManager<Team> {

@ -8,13 +8,16 @@ import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import uca.iut.clermont.R import uca.iut.clermont.R
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import uca.iut.clermont.model.Competition import uca.iut.clermont.model.Competition
import uca.iut.clermont.view.adapter.MatchesAdapter import uca.iut.clermont.view.adapter.MatchesAdapter
import uca.iut.clermont.view.viewModel.DetailViewModel
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -22,6 +25,8 @@ class DetailFragment : Fragment() {
private var isLiked = false private var isLiked = false
private lateinit var competition: Competition private lateinit var competition: Competition
private val viewModel: DetailViewModel by viewModels()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -33,10 +38,33 @@ class DetailFragment : Fragment() {
val id = arguments?.getInt("idItem")!! val id = arguments?.getInt("idItem")!!
//competition = (activity as MainActivity).manager.competitionsMgr.getItemById(id)!!
viewModel.competition.observe(viewLifecycleOwner, Observer { comp ->
comp?.let {
competition = comp
initializeView(view) initializeView(view)
initRecyclerView(view) initRecyclerView(view)
}
})
viewModel.loadCurrentCompetition(id)
viewModel.nbCompetitionMatches.observe(viewLifecycleOwner, Observer { comp ->
comp?.let {
initNumberMatches(view)
}
})
viewModel.loadNumberMatches(id)
viewModel.competitionMatches.observe(viewLifecycleOwner, Observer { competitions ->
competitions?.let {
initRecyclerView(view)
}
})
viewModel.loadMatches(id)
return view; return view;
} }
@ -79,21 +107,24 @@ class DetailFragment : Fragment() {
dateStart.text = formattedDate dateStart.text = formattedDate
nbMatches.text =
(activity as MainActivity).manager.matchesMgr.getNbItemsByCompetition(competition.name)
.toString()
} }
private fun initNumberMatches(view: View) {
val nbMatches = view.findViewById<TextView>(R.id.nbMatches)
nbMatches.text = viewModel.nbCompetitionMatches.value.toString()
}
private fun initRecyclerView(view: View) { private fun initRecyclerView(view: View) {
val recyclerViewMatches = view.findViewById<RecyclerView>(R.id.listRecentsMatches) val recyclerViewMatches = view.findViewById<RecyclerView>(R.id.listRecentsMatches)
with(recyclerViewMatches) { with(recyclerViewMatches) {
layoutManager = LinearLayoutManager(view.context) layoutManager = LinearLayoutManager(view.context)
adapter = MatchesAdapter( adapter = viewModel.competitionMatches.value?.toList()?.let {
(activity as MainActivity).manager.matchesMgr.getItemsByCompetition(competition.name) MatchesAdapter(
.toList().toTypedArray() it.toTypedArray()
) )
} }
}
} }
} }

@ -6,7 +6,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.TextView
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
@ -21,7 +20,7 @@ import uca.iut.clermont.view.viewModel.FavoriteViewModel
class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener { class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener {
private val viewModel: FavoriteViewModel by viewModels<FavoriteViewModel>() private val viewModel: FavoriteViewModel by viewModels()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -72,8 +71,8 @@ class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener {
} }
override fun onItemClick(position: Int) { override fun onItemClick(position: Int) {
/*val competitions = viewModel.competitions val competitions = viewModel.competitions.value!!
val bundle = bundleOf("idItem" to competitions[position].id) val bundle = bundleOf("idItem" to competitions[position].id)
findNavController().navigate(R.id.action_favoriteFragment_to_detailFragment, bundle)*/ findNavController().navigate(R.id.action_favoriteFragment_to_detailFragment, bundle)
} }
} }

@ -19,7 +19,7 @@ import uca.iut.clermont.view.viewModel.HomeViewModel
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
val viewModel: HomeViewModel by viewModels<HomeViewModel>() val viewModel: HomeViewModel by viewModels()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -29,26 +29,30 @@ class HomeFragment : Fragment() {
val view = inflater.inflate(R.layout.fragment_home, container, false) val view = inflater.inflate(R.layout.fragment_home, container, false)
val text = view.findViewById<TextView>(R.id.textEmpty) val buttonFavorite = view.findViewById<ImageButton>(R.id.buttonFavorite)
val restartMatches = view.findViewById<ImageButton>(R.id.restartMatches)
val text = view.findViewById<TextView>(R.id.textEmpty)
viewModel.matches.observe(viewLifecycleOwner, Observer { matches -> viewModel.matches.observe(viewLifecycleOwner, Observer { matches ->
matches?.let { matches?.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
initRecyclerView(view, it) initRecyclerView(view, it)
} else { } else {
text.setText("No games started yet!") text.setText(R.string.noMatches)
} }
} }
}) })
viewModel.loadMatches() displayMatches()
val buttonFavorite = view.findViewById<ImageButton>(R.id.buttonFavorite)
buttonFavorite.setOnClickListener { buttonFavorite.setOnClickListener {
findNavController().navigate(R.id.favoriteFragment) findNavController().navigate(R.id.favoriteFragment)
} }
restartMatches.setOnClickListener {
displayMatches()
}
return view return view
} }
@ -57,9 +61,11 @@ class HomeFragment : Fragment() {
with(recyclerViewMatches) { with(recyclerViewMatches) {
layoutManager = LinearLayoutManager(view.context) layoutManager = LinearLayoutManager(view.context)
adapter = MatchesAdapter(matches.toList().toTypedArray()) adapter = MatchesAdapter(matches.toList().toTypedArray())
}
} }
private fun displayMatches() {
viewModel.loadMatches()
} }

@ -11,16 +11,10 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.marginStart import androidx.core.view.marginStart
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import uca.iut.clermont.R import uca.iut.clermont.R
import uca.iut.clermont.view.viewModel.HomeViewModel
class StartFragment : Fragment(), SensorEventListener { class StartFragment : Fragment(), SensorEventListener {

@ -33,11 +33,41 @@ class MatchesAdapter(private val recentMatches: Array<Match>) :
} }
val date = recentMatches[position].date val date = recentMatches[position].date
val formatter = SimpleDateFormat("dd/MM/yyyy' 'HH:mm", Locale.US)
val formatter = SimpleDateFormat("dd-MM-yyyy", Locale.US)
val formattedDate = formatter.format(date.time) val formattedDate = formatter.format(date.time)
holder.dateCompetition.text = recentMatches[position].competition.name.plus(" : ").plus(formattedDate) with(holder.iconStatus) {
setImageResource(R.drawable.mi_temp)
layoutParams.width = 0
layoutParams.height = 0
(layoutParams as ViewGroup.MarginLayoutParams).apply {
topMargin = 8
bottomMargin = 7
}
}
if (recentMatches[position].status == "IN_PLAY") {
with(holder.iconStatus) {
setImageResource(R.drawable.live)
layoutParams.width = 130
layoutParams.height = 130
(layoutParams as ViewGroup.MarginLayoutParams).apply {
topMargin = 0
bottomMargin = 0
}
}
}
if (recentMatches[position].status == "PAUSED") {
with(holder.iconStatus) {
setImageResource(R.drawable.mi_temp)
layoutParams.width = 100
layoutParams.height = 100
}
}
holder.dateCompetition.text =
recentMatches[position].competition.name.plus(" : ").plus(formattedDate)
Glide.with(holder.itemView.context) Glide.with(holder.itemView.context)
.load(recentMatches[position].homeTeam.crest) .load(recentMatches[position].homeTeam.crest)

@ -13,6 +13,7 @@ class MatchHolder(view: View) : RecyclerView.ViewHolder(view) {
val scoreAwayTeam: TextView val scoreAwayTeam: TextView
val imageHomeTeam: ImageView val imageHomeTeam: ImageView
val imageAwayTeam: ImageView val imageAwayTeam: ImageView
val iconStatus: ImageView
val dateCompetition: TextView val dateCompetition: TextView
init { init {
@ -23,6 +24,7 @@ class MatchHolder(view: View) : RecyclerView.ViewHolder(view) {
imageHomeTeam = view.findViewById(R.id.ImageFirstTeam) imageHomeTeam = view.findViewById(R.id.ImageFirstTeam)
imageAwayTeam = view.findViewById(R.id.ImageSecondTeam) imageAwayTeam = view.findViewById(R.id.ImageSecondTeam)
dateCompetition = view.findViewById(R.id.DateCompetition) dateCompetition = view.findViewById(R.id.DateCompetition)
iconStatus = view.findViewById(R.id.iconStatus)
} }

@ -1,4 +1,37 @@
package uca.iut.clermont.view.viewModel package uca.iut.clermont.view.viewModel
class DetailViewModel { import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import uca.iut.clermont.api.ApiManager
import uca.iut.clermont.model.Competition
import uca.iut.clermont.model.Match
import java.util.*
class DetailViewModel : ViewModel() {
val manager = ApiManager()
val competition = MutableLiveData<Competition?>()
val competitionMatches = MutableLiveData<List<Match>>()
val nbCompetitionMatches = MutableLiveData<Int>()
fun loadCurrentCompetition(id: Int) = viewModelScope.launch {
val result = manager.competitionsMgr.getItemById(id)
competition.value = result
}
fun loadMatches(id: Int) = viewModelScope.launch {
val matchResults = manager.matchesMgr.getItemsByCompetition(id)
competitionMatches.value = matchResults.filter { it.status != "TIMED" && it.status != "SCHEDULED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
}
fun loadNumberMatches(id: Int) = viewModelScope.launch {
val nb = manager.matchesMgr.getNbItemsByCompetition(id)
nbCompetitionMatches.value = nb
}
} }

@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import uca.iut.clermont.api.ApiManager import uca.iut.clermont.api.ApiManager
import uca.iut.clermont.model.Match import uca.iut.clermont.model.Match
import java.util.*
class HomeViewModel : ViewModel() { class HomeViewModel : ViewModel() {
@ -13,8 +14,11 @@ class HomeViewModel : ViewModel() {
val matches = MutableLiveData<List<Match>?>() val matches = MutableLiveData<List<Match>?>()
fun loadMatches() = viewModelScope.launch { fun loadMatches() = viewModelScope.launch {
val matchResult = manager.matchesMgr.getItems() val matchResults = manager.matchesMgr.getItems()
matches.value = matchResult.filter { it.status == "FINISHED" } matches.value = matchResults.filter { it.status != "TIMED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

@ -20,7 +20,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:src="@drawable/arrow" /> android:src="@drawable/arrow"
android:contentDescription="@string/imageNotFound" />
<Button <Button
android:id="@+id/buttonTextHome" android:id="@+id/buttonTextHome"

@ -19,7 +19,7 @@
android:id="@+id/textViewTitle" android:id="@+id/textViewTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello" android:text="@string/hello"
android:textColor="@color/title" android:textColor="@color/title"
android:textSize="20sp" android:textSize="20sp"
android:textStyle="bold" /> android:textStyle="bold" />
@ -28,10 +28,11 @@
android:id="@+id/buttonFavorite" android:id="@+id/buttonFavorite"
android:layout_width="34dp" android:layout_width="34dp"
android:layout_height="34dp" android:layout_height="34dp"
android:layout_gravity="right" android:layout_gravity="end"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@drawable/icon_like" /> android:src="@drawable/icon_like"
android:contentDescription="@string/imageNotFound" />
</FrameLayout> </FrameLayout>

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="350dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:background="@drawable/border_rounded" android:background="@drawable/border_rounded"
@ -19,8 +19,8 @@
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" android:layout_height="64dp"
android:layout_marginHorizontal="15dp" android:layout_marginHorizontal="15dp"
android:contentDescription="" android:layout_marginVertical="10dp"
android:layout_marginVertical="10dp" /> android:contentDescription="@string/imageNotFound"/>
<TextView <TextView
android:id="@+id/textFavorites" android:id="@+id/textFavorites"

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
<LinearLayout <LinearLayout
android:layout_width="350dp" android:layout_width="350dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="4dp"
android:background="@drawable/background" android:background="@drawable/background"
android:gravity="center" android:gravity="center"
android:orientation="vertical" android:orientation="vertical"
@ -15,11 +16,25 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iconStatus"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="end"
android:layout_marginTop="8dp"
android:layout_marginBottom="7dp"
android:contentDescription="@string/imageNotFound" />
</FrameLayout>
<TextView <TextView
android:id="@+id/DateCompetition" android:id="@+id/DateCompetition"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp" android:layout_marginBottom="15dp"
android:ellipsize="end" android:ellipsize="end"
android:fontFamily="@font/mulish_bold" android:fontFamily="@font/mulish_bold"
@ -32,14 +47,15 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:orientation="horizontal" android:baselineAligned="false"
android:baselineAligned="false"> android:gravity="center"
android:orientation="horizontal">
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.4" android:layout_weight="0.4"
android:gravity="center_horizontal" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
@ -110,7 +126,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.4" android:layout_weight="0.4"
android:gravity="center_horizontal" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView

@ -8,11 +8,10 @@
<ImageView <ImageView
android:id="@+id/imageDetail" android:id="@+id/imageDetail"
android:layout_width="170dp" android:layout_width="220dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="30dp" android:layout_marginTop="30dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_background"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.25" app:layout_constraintHeight_percent="0.25"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -22,7 +22,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:src="@drawable/arrow" /> android:src="@drawable/arrow"
android:contentDescription="@string/imageNotFound" />
<Button <Button
android:id="@+id/buttonTextHome" android:id="@+id/buttonTextHome"

@ -20,7 +20,7 @@
android:id="@+id/textViewTitle" android:id="@+id/textViewTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello" android:text="@string/hello"
android:textColor="@color/title" android:textColor="@color/title"
android:textSize="20sp" android:textSize="20sp"
android:textStyle="bold" /> android:textStyle="bold" />
@ -29,10 +29,11 @@
android:id="@+id/buttonFavorite" android:id="@+id/buttonFavorite"
android:layout_width="34dp" android:layout_width="34dp"
android:layout_height="34dp" android:layout_height="34dp"
android:layout_gravity="right" android:layout_gravity="end"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@drawable/icon_like" /> android:src="@drawable/icon_like"
android:contentDescription="@string/imageNotFound" />
</FrameLayout> </FrameLayout>
@ -95,21 +96,34 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchBarContainer" /> app:layout_constraintTop_toBottomOf="@+id/searchBarContainer" />
<ImageButton
android:id="@+id/restartMatches"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="20dp"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/restart"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchBarContainer" />
<TextView <TextView
android:id="@+id/textEmpty" android:id="@+id/textEmpty"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/title" android:textColor="@color/title"
android:textSize="20dp" android:textSize="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewRecentMatches" /> app:layout_constraintTop_toBottomOf="@+id/textViewRecentMatches" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/listRecentsMatches" android:id="@+id/listRecentsMatches"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:paddingBottom="200dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewRecentMatches" app:layout_constraintTop_toBottomOf="@+id/textViewRecentMatches"

@ -13,7 +13,8 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
android:contentDescription="@string/imageNotFound" />
<ImageView <ImageView
android:id="@+id/shadow" android:id="@+id/shadow"

@ -1,3 +1,7 @@
<resources> <resources>
<string name="app_name">Scor_It</string> <string name="app_name">Scor_It</string>
<string name="noMatches">No games started yet!</string>
<string name="imageNotFound">Image not found</string>
<string name="hello">Hello</string>
</resources> </resources>
Loading…
Cancel
Save