Compare commits

...

10 Commits

Author SHA1 Message Date
Joren
c64a8d1f73
idk 2024-05-02 21:30:11 +02:00
Joren
dd3786166c
Fix a bunch of stupid fckn issues that make my life hard 2024-05-02 21:03:51 +02:00
Joren
e072f88d69
Add icon 2024-05-02 17:54:12 +02:00
Joren
dec32634b5
Remove debug switch 2024-04-30 14:38:43 +02:00
Schipman Joren
e7b9269ab0 Merge branch 'bugfixes' into 'master'
Return empty list when no results are found instaid of crashing

See merge request ti/2023-2024/s4/mobile-security/students/joren-schipman/pokesearch!5
2024-04-30 10:17:58 +00:00
Joren
13dc50afe8
Return empty list when no results are found instaid of crashing 2024-04-30 12:17:17 +02:00
Schipman Joren
9b8af28f47 Merge branch 'simple_sub_system' into 'master'
Add a simple toggle for debugging purposes

See merge request ti/2023-2024/s4/mobile-security/students/joren-schipman/pokesearch!4
2024-04-30 10:06:47 +00:00
Joren
09f9b2c5cf
Add a simple toggle for debugging purposes 2024-04-30 12:06:25 +02:00
Schipman Joren
6b7cd89f86 Merge branch 'simple_sub_system' into 'master'
Simple sub system

See merge request ti/2023-2024/s4/mobile-security/students/joren-schipman/pokesearch!3
2024-04-30 10:00:48 +00:00
Joren
8690ed006e
Add a toggle for access 2024-04-30 11:59:20 +02:00
27 changed files with 166 additions and 223 deletions

View File

@ -25,6 +25,7 @@ android {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("debug")
}
}
compileOptions {

View File

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
package="com.ti.mobpo">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".PokeSearch"
android:allowBackup="true"
android:enableOnBackInvokedCallback="true"
android:dataExtractionRules="@xml/data_extraction_rules"
@ -15,6 +16,8 @@
android:supportsRtl="true"
android:theme="@style/Theme.MobileSecurity"
tools:targetApi="31">
<!-- Specify your main activity here -->
<activity
android:name=".MainActivity"
android:exported="true"

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,29 +1,33 @@
package com.ti.mobpo
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.ti.mobpo.data.AppContainer
import com.ti.mobpo.ui.util.FeatureManager
import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
PokeSearchViewModel(
pokesearchApplication().appContainer.favouritesRepository
)
lateinit var appContainer: AppContainer
lateinit var featureManager: FeatureManager
fun initialize(appContainer: AppContainer, featureManager: FeatureManager) {
this.appContainer = appContainer
this.featureManager = featureManager
}
initializer {
val Factory = viewModelFactory {
initializer { ->
PokeSearchViewModel(
appContainer.favouritesRepository
)
}
initializer { ->
FavouritesViewModel(
pokesearchApplication().appContainer.favouritesRepository, pokesearchApplication().featureManager
appContainer.favouritesRepository,
featureManager
)
}
}
}
fun CreationExtras.pokesearchApplication(): PokeSearch =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as PokeSearch)

View File

@ -4,17 +4,39 @@ import android.annotation.SuppressLint
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.ti.mobpo.data.AppContainer
import com.ti.mobpo.data.AppDataContainer
import com.ti.mobpo.ui.Navigation
import com.ti.mobpo.ui.theme.MobileSecurityTheme
import com.ti.mobpo.ui.util.FeatureManager
class MainActivity : ComponentActivity() {
lateinit var appContainer: AppContainer
private set
lateinit var featureManager: FeatureManager
private set
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MobileSecurityTheme {
Navigation()
Navigation(this@MainActivity)
}
}
appContainer = createAppContainer()
featureManager = createFeatrureManager()
AppViewModelProvider.initialize(appContainer, featureManager)
}
private fun createAppContainer(): AppContainer {
return AppDataContainer(this)
}
private fun createFeatrureManager(): FeatureManager {
return FeatureManager(this)
}
}

View File

@ -1,28 +0,0 @@
package com.ti.mobpo
import android.app.Application
import com.ti.mobpo.data.AppContainer
import com.ti.mobpo.data.AppDataContainer
import com.ti.mobpo.ui.util.FeatureManager
class PokeSearch : Application() {
lateinit var appContainer: AppContainer
private set
lateinit var featureManager: FeatureManager
private set
override fun onCreate() {
super.onCreate()
appContainer = createAppContainer()
featureManager = createFeatrureManager()
}
private fun createAppContainer(): AppContainer {
return AppDataContainer(this)
}
private fun createFeatrureManager(): FeatureManager {
return FeatureManager(this)
}
}

View File

@ -31,13 +31,14 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.ti.mobpo.AppViewModelProvider
import com.ti.mobpo.MainActivity
import com.ti.mobpo.ui.screens.FavoritesScreen
import com.ti.mobpo.ui.screens.PokeSearchScreen
import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel
@Composable
fun Navigation() {
fun Navigation(activity: MainActivity) {
val items = listOf(
BottomNavigationItem(
title = "Home",
@ -66,6 +67,8 @@ fun Navigation() {
val pokeSearchVM = viewModel<PokeSearchViewModel>(factory = AppViewModelProvider.Factory)
val favoritesVM = viewModel<FavouritesViewModel>(factory = AppViewModelProvider.Factory)
Scaffold (
bottomBar = {
NavigationBar {

View File

@ -1,5 +1,6 @@
package com.ti.mobpo.ui.screens
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@ -16,6 +17,8 @@ import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
@ -41,6 +44,29 @@ fun Favorites(favoritesViewModel: FavouritesViewModel) {
) {
Spacer(modifier = Modifier.height(16.dp))
if (favoritesViewModel.accessCheckFailed.value) {
AlertDialog(
onDismissRequest = {
favoritesViewModel.accessCheckFailed.value = false
},
title = {
Text("Access Denied")
},
text = {
Text("You do not have access to this feature.")
},
confirmButton = {
Button(
onClick = {
favoritesViewModel.accessCheckFailed.value = false
}
) {
Text("OK")
}
}
)
}
favorites?.let { favoritesList ->
if (favoritesList.isNotEmpty()) {
LazyVerticalGrid(

View File

@ -1,5 +1,7 @@
package com.ti.mobpo.ui.viewmodels
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ti.mobpo.data.Favourite
@ -17,15 +19,22 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import java.io.IOException
class FavouritesViewModel(private val favouritesRepository: FavouritesRepository, featureManager: FeatureManager) : ViewModel() {
private val service = PokeApi.retrofitService
class FavouritesViewModel(private val favouritesRepository: FavouritesRepository,
private val featureManager: FeatureManager
) : ViewModel() {
private val service = PokeApi.retrofitService
private val _pokemonDetails = MutableStateFlow<List<PokemonDetails>?>(null)
val pokemonDetails: StateFlow<List<PokemonDetails>?> = _pokemonDetails.asStateFlow()
val accessCheckFailed: MutableState<Boolean> = mutableStateOf(false)
fun loadFavourites() {
// featureManager.setPaidFeatureEnabled(false) enable and disable acccess
// Ugly workaround to make sure all the favourites are loaded before displaying them
viewModelScope.launch {
if(!featureManager.hasAccessToPaidFeature()) {
accessCheckFailed.value = true
return@launch
}
try {
val favouritesList: StateFlow<FavouriteUiState> =
favouritesRepository.getAllItems().map { FavouriteUiState(it) }

View File

@ -48,7 +48,7 @@ class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository
val detailsList = mutableListOf<PokemonDetails>()
if (firstIndex != null && lastIndex != null) {
if (firstIndex != null && lastIndex != null && firstIndex != -1 && lastIndex != -1) {
val endIndex = minOf(firstIndex + SHOW_LIMIT, lastIndex + 1)
val startIndex = maxOf(firstIndex, endIndex - SHOW_LIMIT)

View File

@ -1,170 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -2,6 +2,7 @@
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
id("com.google.devtools.ksp") version "1.9.20-1.0.14"
}
buildscript {