1 Commits

Author SHA1 Message Date
f7236485c0 Slight update 2022-11-06 21:39:51 +01:00
10 changed files with 91 additions and 202 deletions

View File

@@ -62,13 +62,11 @@ dependencies {
// Navigation // Navigation
implementation "androidx.navigation:navigation-compose:2.5.3" implementation "androidx.navigation:navigation-compose:2.5.3"
// ViewModel and livedata // ViewModel
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' implementation "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07"
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1' implementation 'androidx.activity:activity-compose:1.3.1'
implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"

View File

@@ -1,32 +0,0 @@
package com.mitchelbv.thuis_c.database
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.mitchelbv.thuis_c.ui.feyenoord.Match
@Entity
data class DatabaseMatches constructor(
@PrimaryKey(autoGenerate = true)
val id: Int,
val home_team: String,
val away_team: String,
val date: String,
val begin_time: String,
val end_time: String,
val home_image: String,
val away_image: String
)
fun List<DatabaseMatches>.asDomainModel(): List<Match> {
return map {
Match(
home_team = it.home_team,
away_team = it.away_team,
date = it.date,
begin_time = it.begin_time,
end_time = it.end_time,
home_image = it.home_image,
away_image = it.away_image
)
}
}

View File

@@ -1,42 +0,0 @@
package com.mitchelbv.thuis_c.database
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.room.*
import kotlinx.coroutines.withContext
@Dao
interface MatchDao {
@Query("select * from databasematches")
fun getMatches(): LiveData<List<DatabaseMatches>>
@Query("select * from databasematches order by id ASC")
fun getUpcomingMatch(): LiveData<DatabaseMatches>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(matches: List<DatabaseMatches>)
}
@Database(entities = [DatabaseMatches::class], version = 1)
abstract class MatchesDatabase : RoomDatabase() {
abstract val matchDao: MatchDao
companion object {
@Volatile
private lateinit var INSTANCE: MatchesDatabase
fun getDatabase(context: Context): MatchesDatabase {
synchronized(MatchesDatabase::class.java) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
MatchesDatabase::class.java,
"matches"
).build()
}
}
return INSTANCE
}
}
}

View File

@@ -1,6 +1,7 @@
package com.mitchelbv.thuis_c.network.feyenoord package com.mitchelbv.thuis_c.network.feyenoord
import com.mitchelbv.thuis_c.network.feyenoord.responses.FeyenoordEventResponse import com.mitchelbv.thuis_c.network.feyenoord.responses.FeyenoordEventResponse
import retrofit2.Call
import retrofit2.http.GET import retrofit2.http.GET
interface FeyenoordService { interface FeyenoordService {

View File

@@ -1,62 +1,12 @@
package com.mitchelbv.thuis_c.network.feyenoord.responses package com.mitchelbv.thuis_c.network.feyenoord.responses
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import com.mitchelbv.thuis_c.database.DatabaseMatches
import com.mitchelbv.thuis_c.ui.feyenoord.Match
data class FeyenoordEventResponse( data class FeyenoordEventResponse(
@SerializedName("HeaderItem") var HeaderItem: HeaderItem? = HeaderItem(), @SerializedName("HeaderItem") var HeaderItem: HeaderItem? = HeaderItem(),
@SerializedName("TabItems") var TabItems: ArrayList<TabItems> = arrayListOf(), @SerializedName("TabItems") var TabItems: ArrayList<TabItems> = arrayListOf(),
@SerializedName("CrossSellInfo") var CrossSellInfo: String? = null @SerializedName("CrossSellInfo") var CrossSellInfo: String? = null
)
fun notNullHandler(test: String?): String {
if (!test.isNullOrEmpty()) {
return test;
}
return ""
}
fun FeyenoordEventResponse.asDomainModel(): List<Match> {
val tempMatches = mutableListOf<Match>()
val test2 = TabItems.filter { it.CategoryId == 2 }
test2.forEach { items ->
for (item in items.Items) {
tempMatches.add(
Match(
home_team = notNullHandler(item.NameHomeTeam),
away_team = notNullHandler(item.NameAwayTeam),
date = notNullHandler(item.EventStartDateTimeFormatted?.Full),
begin_time = notNullHandler(item.EventStartDateTimeFormatted?.Time),
end_time = notNullHandler(item.EventEndDateTimeFormatted?.Time),
away_image = notNullHandler(item.AwayImageUrl),
home_image = notNullHandler(item.HomeImageUrl)
) )
)
}
}
return tempMatches
}
fun FeyenoordEventResponse.asDatabaseModel(): List<DatabaseMatches> {
val tempMatches = mutableListOf<DatabaseMatches>()
val test2 = TabItems.filter { it.CategoryId == 2 }
test2.forEach { items ->
for (item in items.Items) {
tempMatches.add(
DatabaseMatches(
id = item.EventId!!,
home_team = notNullHandler(item.NameHomeTeam),
away_team = notNullHandler(item.NameAwayTeam),
date = notNullHandler(item.EventStartDateTimeFormatted?.Full),
begin_time = notNullHandler(item.EventStartDateTimeFormatted?.Time),
end_time = notNullHandler(item.EventEndDateTimeFormatted?.Time),
away_image = notNullHandler(item.AwayImageUrl),
home_image = notNullHandler(item.HomeImageUrl)
)
)
}
}
return tempMatches
}

View File

@@ -1,25 +0,0 @@
package com.mitchelbv.thuis_c.repository
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import com.mitchelbv.thuis_c.database.MatchesDatabase
import com.mitchelbv.thuis_c.database.asDomainModel
import com.mitchelbv.thuis_c.network.feyenoord.FeyenoordRetrofitHelper
import com.mitchelbv.thuis_c.network.feyenoord.responses.asDatabaseModel
import com.mitchelbv.thuis_c.ui.feyenoord.Match
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class FeyenoordRepository(private val database: MatchesDatabase) {
val matches: LiveData<List<Match>> = Transformations.map(database.matchDao.getMatches()) {
it.asDomainModel()
}
suspend fun refreshMatches() {
withContext(Dispatchers.IO) {
val matches = FeyenoordRetrofitHelper.feyenoord.getEvents()
database.matchDao.insertAll(matches.asDatabaseModel())
}
}
}

View File

@@ -42,9 +42,7 @@ fun MatchList(matches: List<Match>, modifier: Modifier) {
@Composable @Composable
fun TeamNameWithLogo(team_name: String, team_logo_url: String, modifier: Modifier) { fun TeamNameWithLogo(team_name: String, team_logo_url: String, modifier: Modifier) {
Column(modifier = modifier Column(modifier = modifier.size(128.dp).fillMaxWidth(), Arrangement.Center, Alignment.CenterHorizontally) {
.size(128.dp)
.fillMaxWidth(), Arrangement.Center, Alignment.CenterHorizontally) {
AsyncImage( AsyncImage(
model = team_logo_url, model = team_logo_url,
contentDescription = team_name, contentDescription = team_name,
@@ -52,9 +50,7 @@ fun TeamNameWithLogo(team_name: String, team_logo_url: String, modifier: Modifie
contentScale = ContentScale.Fit, contentScale = ContentScale.Fit,
modifier = modifier.size(64.dp) modifier = modifier.size(64.dp)
) )
Text(text = team_name, modifier = modifier Text(text = team_name, modifier = modifier.fillMaxWidth().wrapContentWidth(Alignment.CenterHorizontally))
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally))
} }
} }

View File

@@ -1,61 +1,55 @@
package com.mitchelbv.thuis_c.ui.feyenoord package com.mitchelbv.thuis_c.ui.feyenoord
import android.app.Application import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.mitchelbv.thuis_c.database.MatchesDatabase.Companion.getDatabase import com.mitchelbv.thuis_c.network.feyenoord.FeyenoordRetrofitHelper
import com.mitchelbv.thuis_c.repository.FeyenoordRepository import com.mitchelbv.thuis_c.network.feyenoord.FeyenoordService
import com.mitchelbv.thuis_c.network.feyenoord.responses.FeyenoordEventResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
data class FeyenoordUiState( data class FeyenoordUiState(
val matches: List<Match> = listOf() val matches: List<Match> = listOf()
) )
class FeyenoordViewModel(application: Application) : ViewModel() { class FeyenoordViewModel : ViewModel() {
private val _uiState = MutableStateFlow(FeyenoordUiState()) private val _uiState = MutableStateFlow(FeyenoordUiState())
val uiState: StateFlow<FeyenoordUiState> = _uiState.asStateFlow() val uiState: StateFlow<FeyenoordUiState> = _uiState.asStateFlow()
private val feyenoordRepository = FeyenoordRepository(getDatabase(application))
val matches = feyenoordRepository.matches
init { init {
refreshMatchesFromRepository() fillMatches()
} }
private fun refreshMatchesFromRepository() { private fun fillMatches() {
viewModelScope.launch { // TODO Get data from the internet
feyenoordRepository.refreshMatches() val tempMatches = mutableListOf<Match>()
_uiState.value = FeyenoordUiState(matches = matches.value!!) viewModelScope.launch(Dispatchers.IO) {
val apiResponse = FeyenoordRetrofitHelper.feyenoord.getEvents()
for (tabItem in apiResponse.TabItems) {
val test = arrayOf(tabItem).filter { it.CategoryId == 2 }
test.forEach {
for (item in it.Items) {
tempMatches.add(Match(
home_team = item.NameHomeTeam!!,
away_team = item.NameAwayTeam!!,
date = item.EventStartDateTimeFormatted?.Full!!,
begin_time = item.EventStartDateTimeFormatted?.Time!!,
end_time = item.EventEndDateTimeFormatted?.Time!!,
away_image = item.AwayImageUrl!!,
home_image = item.HomeImageUrl!!
))
}
}
}
_uiState.value = FeyenoordUiState(matches = tempMatches)
} }
} }
// private fun fillMatches() {
// // TODO Get data from the internet
// val tempMatches = mutableListOf<Match>()
// viewModelScope.launch(Dispatchers.IO) {
// val fApiClient =
// FeyenoordRetrofitHelper.getInstance().create(FeyenoordService::class.java)
// val apiResponse = fApiClient.getEvents()
// for (tabItem in apiResponse.TabItems) {
// val test = arrayOf(tabItem).filter { it.CategoryId == 2 }
// test.forEach {
// for (item in it.Items) {
// tempMatches.add(Match(
// home_team = item.NameHomeTeam!!,
// away_team = item.NameAwayTeam!!,
// date = item.EventStartDateTimeFormatted?.Full!!,
// begin_time = item.EventStartDateTimeFormatted?.Time!!,
// end_time = item.EventEndDateTimeFormatted?.Time!!,
// away_image = item.AwayImageUrl!!,
// home_image = item.HomeImageUrl!!
// ))
// }
// }
// }
// _uiState.value = FeyenoordUiState(matches = tempMatches)
// }
// }
} }

View File

@@ -0,0 +1,49 @@
package com.mitchelbv.thuis_c.ui.home
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mitchelbv.thuis_c.Screen
import com.mitchelbv.thuis_c.network.feyenoord.FeyenoordRetrofitHelper
import com.mitchelbv.thuis_c.network.feyenoord.FeyenoordService
import com.mitchelbv.thuis_c.ui.feyenoord.Match
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
data class HomeUiState(
val upcomingMatch: Match? = null
)
class HomeViewModel : ViewModel() {
private val _uiState = MutableStateFlow(HomeUiState())
val uiState: StateFlow<HomeUiState> = _uiState.asStateFlow()
init {
getUpcomingMatch()
}
fun notNullHandler(test: String?): String {
if (!test.isNullOrEmpty()) {
return test;
}
return ""
}
private fun getUpcomingMatch() {
viewModelScope.launch {
val apiResponse = FeyenoordRetrofitHelper.feyenoord.getEvents().HeaderItem!!
val match = Match(
home_team = notNullHandler(apiResponse.NameHomeTeam),
away_team = notNullHandler(apiResponse.NameAwayTeam),
date = notNullHandler(apiResponse.EventStartDateTimeFormatted?.Full),
begin_time = notNullHandler(apiResponse.EventStartDateTimeFormatted?.Time),
end_time = notNullHandler(apiResponse.EventEndDateTimeFormatted?.Time),
away_image = notNullHandler(apiResponse.AwayImageUrl),
home_image = notNullHandler(apiResponse.HomeImageUrl)
)
_uiState.value = HomeUiState(upcomingMatch = match)
}
}
}

View File

@@ -1,7 +1,7 @@
<resources> <resources>
<string name="app_name">Thuis</string> <string name="app_name">Thuis</string>
<string name="nav_feyenoord">Feyenoord</string> <string name="nav_feyenoord">Wedstrijden</string>
<string name="nav_recipes">Recepten</string> <string name="nav_recipes">Recepten</string>
<string name="nav_home">Home</string> <string name="nav_home">Home</string>
</resources> </resources>