mirror of
https://github.com/IllusionMan1212/NPS-Browser.git
synced 2026-10-24 02:12:37 +00:00
WIP: UI for package list and grid + start of handling data
This commit is contained in:
@@ -100,7 +100,7 @@ dependencies {
|
||||
// Compose extras library for controlling system ui and etc.
|
||||
implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.2-alpha")
|
||||
|
||||
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.8.0")
|
||||
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.9.1")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||
@@ -110,4 +110,6 @@ dependencies {
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.navigation:navigation-compose:2.6.0")
|
||||
implementation("io.coil-kt:coil:2.4.0")
|
||||
implementation("io.coil-kt:coil-compose:2.4.0")
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
enum class ConsoleType {
|
||||
@@ -24,6 +25,11 @@ enum class DataType {
|
||||
THEMES,
|
||||
}
|
||||
|
||||
enum class Layout {
|
||||
LIST,
|
||||
GRID,
|
||||
}
|
||||
|
||||
class Preferences(private val context: Context) {
|
||||
companion object {
|
||||
private val Context.dataStore by preferencesDataStore("settings")
|
||||
@@ -53,7 +59,7 @@ class Preferences(private val context: Context) {
|
||||
}
|
||||
|
||||
val layout = context.dataStore.data.map{ prefs ->
|
||||
prefs[DATA_LAYOUT] ?: 0
|
||||
prefs[DATA_LAYOUT] ?: Layout.LIST.ordinal
|
||||
}
|
||||
|
||||
val seenOnboarding = context.dataStore.data.map{ prefs ->
|
||||
@@ -180,7 +186,20 @@ class Preferences(private val context: Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getAvailableTsvs(): List<Pair<ConsoleType, DataType>> {
|
||||
val list = mutableListOf<Pair<ConsoleType, DataType>>()
|
||||
if (psvGames.first().isNotEmpty()) list.add(Pair(ConsoleType.PSVITA, DataType.GAMES))
|
||||
if (psvDLC.first().isNotEmpty()) list.add(Pair(ConsoleType.PSVITA, DataType.DLC))
|
||||
if (psvThemes.first().isNotEmpty()) list.add(Pair(ConsoleType.PSVITA, DataType.THEMES))
|
||||
if (ps3Games.first().isNotEmpty()) list.add(Pair(ConsoleType.PS3, DataType.GAMES))
|
||||
if (ps3DLC.first().isNotEmpty()) list.add(Pair(ConsoleType.PS3, DataType.DLC))
|
||||
if (pspGames.first().isNotEmpty()) list.add(Pair(ConsoleType.PSP, DataType.GAMES))
|
||||
if (pspDLC.first().isNotEmpty()) list.add(Pair(ConsoleType.PSP, DataType.DLC))
|
||||
if (psxGames.first().isNotEmpty()) list.add(Pair(ConsoleType.PSX, DataType.GAMES))
|
||||
if (psmGames.first().isNotEmpty()) list.add(Pair(ConsoleType.PSM, DataType.GAMES))
|
||||
return list
|
||||
}
|
||||
|
||||
suspend fun setHMACKey(key: String) {
|
||||
@@ -224,4 +243,4 @@ class Preferences(private val context: Context) {
|
||||
prefs[PKG2ZIP_AUTO_DECRYPT] = autoDecrypt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,29 @@ package com.illusionware.npsbrowser.activities
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.basicMarquee
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
@@ -23,6 +35,9 @@ import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.ProvideTextStyle
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
@@ -40,18 +55,32 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.ColorPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.illusionware.npsbrowser.ConsoleType
|
||||
import com.illusionware.npsbrowser.Layout
|
||||
import com.illusionware.npsbrowser.Preferences
|
||||
import com.illusionware.npsbrowser.R
|
||||
import com.illusionware.npsbrowser.ui.theme.ColorAccent
|
||||
@@ -60,12 +89,18 @@ import com.illusionware.npsbrowser.ui.theme.Typography
|
||||
import com.illusionware.npsbrowser.ui.components.*
|
||||
import com.illusionware.npsbrowser.ui.pages.SettingsScreen
|
||||
import com.illusionware.npsbrowser.ui.pages.OnBoarding
|
||||
import com.illusionware.npsbrowser.ui.theme.ColorOnPrimaryLight
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
val PlaceholderColor = Color(0x1F888888)
|
||||
val redHatDisplayFamily = FontFamily(
|
||||
Font(R.font.red_hat_display_bold, FontWeight.Bold),
|
||||
)
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -128,13 +163,18 @@ fun Router() {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@Preview()
|
||||
@Preview
|
||||
fun HomePage(navigateToSettings: () -> Unit = {}) {
|
||||
val prefs = Preferences(LocalContext.current)
|
||||
var isSearchOpen by rememberSaveable { mutableStateOf(false)}
|
||||
var searchQuery by rememberSaveable { mutableStateOf("")}
|
||||
val searchBar = remember { FocusRequester() }
|
||||
var layoutDialogOpen by remember { mutableStateOf(false) }
|
||||
|
||||
val tsvs by remember { runBlocking { mutableStateOf(prefs.getAvailableTsvs()) }}
|
||||
var selectedBarItem by remember { mutableStateOf(ConsoleType.PSVITA) }
|
||||
// val noTsvs by remember { mutableStateOf(false) }
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
@@ -213,12 +253,27 @@ fun HomePage(navigateToSettings: () -> Unit = {}) {
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
if (tsvs.isNotEmpty()) {
|
||||
NavBar(
|
||||
selectedTab = selectedBarItem,
|
||||
onTabSelected = { selectedBarItem = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
) { padding ->
|
||||
Column(Modifier.padding(padding)) {
|
||||
NoTsvs(navigateToSettings = navigateToSettings)
|
||||
if (tsvs.isEmpty()) {
|
||||
NoTsvs(navigateToSettings = navigateToSettings)
|
||||
} else {
|
||||
// when (selectedBarItem) {
|
||||
// ConsoleType.PSVITA -> VitaPage(searchQuery = searchQuery)
|
||||
// ConsoleType.PS3 -> PS3Page(searchQuery = searchQuery)
|
||||
// }
|
||||
PackageList(selectedBarItem)
|
||||
}
|
||||
}
|
||||
// TODO: only show NoTsvs when there are no Tsvs loaded
|
||||
|
||||
if (layoutDialogOpen) {
|
||||
LayoutDialog(onDismiss = { layoutDialogOpen = false })
|
||||
@@ -226,6 +281,52 @@ fun HomePage(navigateToSettings: () -> Unit = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NavBar(selectedTab: ConsoleType, onTabSelected: (ConsoleType) -> Unit) {
|
||||
NavigationBar {
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == ConsoleType.PSVITA,
|
||||
icon = { Icon(painterResource(id = R.drawable.vita_icon), contentDescription = "PS Vita") },
|
||||
label = { Text(text = "PS Vita") },
|
||||
onClick = {
|
||||
onTabSelected(ConsoleType.PSVITA)
|
||||
}
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == ConsoleType.PS3,
|
||||
icon = { Icon(painterResource(id = R.drawable.ps3_icon), contentDescription = "PS3") },
|
||||
label = { Text(text = "PS3") },
|
||||
onClick = {
|
||||
onTabSelected(ConsoleType.PS3)
|
||||
}
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == ConsoleType.PSP,
|
||||
icon = { Icon(painterResource(id = R.drawable.psp_icon), contentDescription = "PSP") },
|
||||
label = { Text(text = "PSP") },
|
||||
onClick = {
|
||||
onTabSelected(ConsoleType.PSP)
|
||||
}
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == ConsoleType.PSX,
|
||||
icon = { Icon(painterResource(id = R.drawable.psx_icon), contentDescription = "PSX") },
|
||||
label = { Text(text = "PSX") },
|
||||
onClick = {
|
||||
onTabSelected(ConsoleType.PSX)
|
||||
}
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = selectedTab == ConsoleType.PSM,
|
||||
icon = { Icon(painterResource(id = R.drawable.psm_icon), contentDescription = "PSM") },
|
||||
label = { Text(text = "PSM") },
|
||||
onClick = {
|
||||
onTabSelected(ConsoleType.PSM)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun NoTsvs(padding: PaddingValues = PaddingValues(0.dp), navigateToSettings: () -> Unit = {}) {
|
||||
@@ -267,9 +368,229 @@ fun NoTsvs(padding: PaddingValues = PaddingValues(0.dp), navigateToSettings: ()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LayoutDialog(onDismiss: () -> Unit = {}) {
|
||||
@Preview
|
||||
fun PackageList(type: ConsoleType = ConsoleType.PSVITA) {
|
||||
val prefs = Preferences(LocalContext.current)
|
||||
val layout = prefs.layout.collectAsState(initial = "")
|
||||
val layout = prefs.layout.collectAsState(initial = Layout.LIST.ordinal).value
|
||||
// val thing = when (type) {
|
||||
// ConsoleType.PSVITA -> {
|
||||
// var list = ArrayList<Package>()
|
||||
// list.add(Package("test"))
|
||||
// val gs = prefs.psvGames.collectAsState(initial = emptyList<Package>())
|
||||
// list.add(gs.value)
|
||||
// }
|
||||
// ConsoleType.PS3 -> {
|
||||
// prefs.ps3Games.collectAsState(initial = emptyList())
|
||||
// }
|
||||
// ConsoleType.PSP -> {
|
||||
// prefs.pspGames.collectAsState(initial = emptyList())
|
||||
// }
|
||||
// ConsoleType.PSX -> {
|
||||
// prefs.psxGames.collectAsState(initial = emptyList())
|
||||
// }
|
||||
// ConsoleType.PSM -> {
|
||||
// prefs.psmGames.collectAsState(initial = emptyList())
|
||||
// }
|
||||
// }
|
||||
|
||||
Column(Modifier.fillMaxSize()) {
|
||||
if (layout == Layout.LIST.ordinal) {
|
||||
LazyColumn {
|
||||
items(15) {
|
||||
PackageListItem()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(140.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
) {
|
||||
items(15) {
|
||||
PackageGridItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun PackageListItem() {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { /* TODO: */ }) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.weight(1.0f)
|
||||
) {
|
||||
AsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current)
|
||||
.data("https://picsum.photos/200")
|
||||
.crossfade(true)
|
||||
.error(R.drawable.default_game_icon)
|
||||
.build(),
|
||||
placeholder = ColorPainter(PlaceholderColor),
|
||||
contentDescription = "Package Icon",
|
||||
modifier = Modifier.size(48.dp),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "10 Second Ninja X",
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
style = Typography.bodyLarge,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 2,
|
||||
modifier = Modifier
|
||||
.width(IntrinsicSize.Min)
|
||||
.weight(1.0f)
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
ProvideTextStyle(value = Typography.bodySmall.copy(color = MaterialTheme.colorScheme.outline)) {
|
||||
Text(text = "US")
|
||||
Text(text = "3.69")
|
||||
Text(text = "223.8MB")
|
||||
Tag(title = "GAME", small = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.no_url_icon),
|
||||
contentDescription = "No PKG URL",
|
||||
tint = Color(0xFFCB5A5A)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.no_key_icon),
|
||||
contentDescription = "No Zrif Key",
|
||||
tint = Color(0xFFCB5A5A)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Tag(title: String, small: Boolean = false) {
|
||||
Box(
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(Color(0xFFEAF654))
|
||||
.layoutId("tag")
|
||||
.padding(horizontal = if (small) 6.dp else 8.dp, vertical = if (small) 2.dp else 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = title.uppercase(),
|
||||
color = ColorOnPrimaryLight,
|
||||
style = Typography.bodySmall.copy(
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontFamily = redHatDisplayFamily,
|
||||
fontSize = if (small) 8.sp else 12.sp
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun PackageGridItem() {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clickable { /* TODO: */ }
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
modifier = Modifier.padding(8.dp)
|
||||
) {
|
||||
Layout(
|
||||
content = {
|
||||
AsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current)
|
||||
.data("https://picsum.photos/200")
|
||||
.crossfade(true)
|
||||
.error(R.drawable.default_game_icon)
|
||||
.build(),
|
||||
placeholder = ColorPainter(PlaceholderColor),
|
||||
contentDescription = "Package Icon",
|
||||
modifier = Modifier
|
||||
.aspectRatio(1f / 1f)
|
||||
.fillMaxWidth(),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
Tag(title = "GAME")
|
||||
}
|
||||
) { measurables, constraints ->
|
||||
val imagePlaceable = measurables[0].measure(constraints)
|
||||
val tagPlaceable = measurables.first { it.layoutId == "tag" }.measure(constraints)
|
||||
|
||||
layout(imagePlaceable.width, imagePlaceable.height) {
|
||||
imagePlaceable.placeRelative(0, 0)
|
||||
tagPlaceable.placeRelative(
|
||||
x = imagePlaceable.width - tagPlaceable.width - 16,
|
||||
y = 16,
|
||||
)
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = "10 Second Ninja X",
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
style = Typography.bodyLarge,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 2,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
ProvideTextStyle(value = Typography.bodySmall.copy(color = MaterialTheme.colorScheme.outline)) {
|
||||
Text(text = "US")
|
||||
Text(text = "3.69")
|
||||
Text(text = "223.8MB")
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.no_url_icon),
|
||||
contentDescription = "No PKG URL",
|
||||
tint = Color(0xFFCB5A5A)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.no_key_icon),
|
||||
contentDescription = "No Zrif Key",
|
||||
tint = Color(0xFFCB5A5A)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LayoutDialog(onDismiss: () -> Unit) {
|
||||
val prefs = Preferences(LocalContext.current)
|
||||
val layout = prefs.layout.collectAsState(initial = Layout.LIST.ordinal).value
|
||||
|
||||
NPSAlertDialog(
|
||||
onDismiss = onDismiss,
|
||||
@@ -283,13 +604,13 @@ fun LayoutDialog(onDismiss: () -> Unit = {}) {
|
||||
Column {
|
||||
NPSRadioButton(
|
||||
text = "List",
|
||||
selected = layout.value == 0,
|
||||
onClick = { CoroutineScope(Dispatchers.IO).launch { prefs.changeLayout(0) } },
|
||||
selected = layout == Layout.LIST.ordinal,
|
||||
onClick = { CoroutineScope(Dispatchers.IO).launch { prefs.changeLayout(Layout.LIST.ordinal) } },
|
||||
)
|
||||
NPSRadioButton(
|
||||
text = "Grid",
|
||||
selected = layout.value == 1,
|
||||
onClick = { CoroutineScope(Dispatchers.IO).launch { prefs.changeLayout(1) } },
|
||||
selected = layout == Layout.GRID.ordinal,
|
||||
onClick = { CoroutineScope(Dispatchers.IO).launch { prefs.changeLayout(Layout.GRID.ordinal) } },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,10 @@ const val PAGE_COUNT = 3
|
||||
@Composable
|
||||
fun OnBoarding(navigateToHome: () -> Unit = {}, darkTheme: Boolean = false) {
|
||||
val systemUiController = rememberSystemUiController()
|
||||
val pagerState = rememberPagerState()
|
||||
val pagerState = rememberPagerState(
|
||||
initialPage = 0,
|
||||
initialPageOffsetFraction = 0f
|
||||
)
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.illusionware.npsbrowser.viewmodels
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.github.doyaaaaaken.kotlincsv.dsl.context.ExcessFieldsRowBehaviour
|
||||
import com.github.doyaaaaaken.kotlincsv.dsl.context.InsufficientFieldsRowBehaviour
|
||||
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
|
||||
import com.illusionware.npsbrowser.ConsoleType
|
||||
import com.illusionware.npsbrowser.DataType
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
data class Package(
|
||||
val id: String,
|
||||
val title: String,
|
||||
val region: String,
|
||||
val minFW: String,
|
||||
val pkgUrl: String,
|
||||
val pkgSize: Int,
|
||||
val consoleType: ConsoleType,
|
||||
val dataType: DataType,
|
||||
)
|
||||
|
||||
data class PackageListUiState(
|
||||
val packages: List<Package> = emptyList(),
|
||||
val error: String = "",
|
||||
)
|
||||
|
||||
class PackageListViewModel(): ViewModel() {
|
||||
// TODO: actually properly think about and implement this
|
||||
private val _uiState = MutableStateFlow(PackageListUiState())
|
||||
val uiState: StateFlow<PackageListUiState> = _uiState.asStateFlow()
|
||||
private val tsvReader = csvReader {
|
||||
charset = "ISO_8859_1"
|
||||
quoteChar = '"'
|
||||
delimiter = '\t'
|
||||
excessFieldsRowBehaviour = ExcessFieldsRowBehaviour.TRIM
|
||||
insufficientFieldsRowBehaviour = InsufficientFieldsRowBehaviour.EMPTY_STRING
|
||||
}
|
||||
|
||||
fun loadPackagesFromTsv() {
|
||||
val file = "psv_games.tsv"
|
||||
val rows = tsvReader.readAll(file)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||
<solid android:color="@android:color/holo_blue_dark" />
|
||||
<stroke android:width="2dip" android:color="@android:color/holo_blue_dark"/>
|
||||
<corners android:radius="10dp" />
|
||||
</shape>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||
<solid android:color="@android:color/holo_red_dark" />
|
||||
<stroke android:width="2dip" android:color="@android:color/holo_red_dark"/>
|
||||
<corners android:radius="10dp" />
|
||||
</shape>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
|
||||
|
||||
<!-- The background color -->
|
||||
<item android:drawable="@drawable/splash_gradient"/>
|
||||
|
||||
<!-- App logo -->
|
||||
<item
|
||||
android:drawable="@drawable/ic_nps_fg_no_shadow"
|
||||
android:gravity="center"
|
||||
android:width="400dp"
|
||||
android:height="400dp" />
|
||||
|
||||
</layer-list>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="#FFCA00"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<vector android:height="24dp" android:viewportHeight="12"
|
||||
android:viewportWidth="12" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group>
|
||||
<clip-path android:pathData="M0,0h12v12h-12z"/>
|
||||
<path android:fillColor="#000000" android:pathData="M6,1C3.24,1 1,3.24 1,6C1,8.76 3.24,11 6,11C8.76,11 11,8.76 11,6C11,3.24 8.76,1 6,1ZM6,10C3.79,10 2,8.21 2,6C2,5.075 2.315,4.225 2.845,3.55L8.45,9.155C7.775,9.685 6.925,10 6,10ZM9.155,8.45L3.55,2.845C4.225,2.315 5.075,2 6,2C8.21,2 10,3.79 10,6C10,6.925 9.685,7.775 9.155,8.45Z"/>
|
||||
<group>
|
||||
<clip-path android:pathData="M2,2h8v8h-8z"/>
|
||||
<path android:fillColor="#000000" android:fillType="evenOdd" android:pathData="M5.2,4.8C5.2,4.38 5.332,3.972 5.577,3.631C5.823,3.291 6.169,3.036 6.567,2.903C6.965,2.77 7.395,2.766 7.795,2.891C8.196,3.016 8.547,3.264 8.799,3.599C9.051,3.934 9.191,4.341 9.2,4.76C9.208,5.18 9.084,5.591 8.846,5.936C8.608,6.282 8.267,6.543 7.872,6.684C7.477,6.825 7.047,6.838 6.644,6.722L5.883,7.483C5.808,7.558 5.706,7.6 5.6,7.6H5.2V8C5.2,8.106 5.158,8.208 5.083,8.283C5.008,8.358 4.906,8.4 4.8,8.4H4.4V8.8C4.4,8.906 4.358,9.008 4.283,9.083C4.208,9.158 4.106,9.2 4,9.2H3.2C3.094,9.2 2.992,9.158 2.917,9.083C2.842,9.008 2.8,8.906 2.8,8.8V8C2.8,7.894 2.842,7.792 2.917,7.717L5.278,5.356C5.226,5.175 5.2,4.988 5.2,4.8ZM7.2,3.6C7.12,3.6 7.044,3.632 6.988,3.688C6.932,3.744 6.9,3.82 6.9,3.9C6.9,3.98 6.932,4.056 6.988,4.112C7.044,4.168 7.12,4.2 7.2,4.2C7.359,4.2 7.512,4.263 7.624,4.376C7.737,4.488 7.8,4.641 7.8,4.8C7.8,4.88 7.832,4.956 7.888,5.012C7.944,5.068 8.02,5.1 8.1,5.1C8.18,5.1 8.256,5.068 8.312,5.012C8.368,4.956 8.4,4.88 8.4,4.8C8.4,4.482 8.274,4.177 8.049,3.951C7.823,3.726 7.518,3.6 7.2,3.6Z"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,15 @@
|
||||
<vector android:height="24dp" android:viewportHeight="12"
|
||||
android:viewportWidth="12" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group>
|
||||
<clip-path android:pathData="M0,0h12v12h-12z"/>
|
||||
<path android:fillColor="#000000" android:pathData="M6,1C3.24,1 1,3.24 1,6C1,8.76 3.24,11 6,11C8.76,11 11,8.76 11,6C11,3.24 8.76,1 6,1ZM6,10C3.79,10 2,8.21 2,6C2,5.075 2.315,4.225 2.845,3.55L8.45,9.155C7.775,9.685 6.925,10 6,10ZM9.155,8.45L3.55,2.845C4.225,2.315 5.075,2 6,2C8.21,2 10,3.79 10,6C10,6.925 9.685,7.775 9.155,8.45Z"/>
|
||||
<path android:fillColor="#00000000"
|
||||
android:pathData="M5.822,4.231L6.441,3.612C6.703,3.374 7.046,3.245 7.401,3.253C7.755,3.261 8.093,3.406 8.343,3.657C8.594,3.907 8.739,4.245 8.747,4.599C8.755,4.953 8.626,5.297 8.387,5.559L7.503,6.441C7.376,6.569 7.224,6.67 7.057,6.739C6.891,6.809 6.712,6.844 6.531,6.844C6.351,6.844 6.172,6.809 6.005,6.739C5.838,6.67 5.687,6.569 5.559,6.441"
|
||||
android:strokeColor="#000000" android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" android:strokeWidth="1"/>
|
||||
<path android:fillColor="#00000000"
|
||||
android:pathData="M6.178,7.769L5.559,8.387C5.297,8.626 4.954,8.755 4.599,8.747C4.245,8.739 3.907,8.594 3.657,8.343C3.406,8.093 3.261,7.755 3.253,7.401C3.245,7.047 3.374,6.703 3.613,6.441L4.497,5.559C4.624,5.431 4.776,5.33 4.943,5.261C5.109,5.191 5.288,5.156 5.469,5.156C5.649,5.156 5.828,5.191 5.995,5.261C6.162,5.33 6.313,5.431 6.441,5.559"
|
||||
android:strokeColor="#000000" android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" android:strokeWidth="1"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||
<gradient
|
||||
android:startColor="#FF00A7FF"
|
||||
android:endColor="#FF93278F"
|
||||
android:angle="270"/>
|
||||
</shape>
|
||||
Binary file not shown.
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<include
|
||||
android:id="@+id/include"
|
||||
layout="@layout/appbar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="56dp"
|
||||
android:background="@color/colorAmoled"
|
||||
android:backgroundTint="@color/colorAmoled"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/include"
|
||||
tools:context=".activities.MainActivity" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
This layout is used only on API 21 & 22 (Lollipop) because on these API levels,
|
||||
Android doesn't scale SVGs very well - we noticed the logo stretched across the
|
||||
screen and looked ugly.
|
||||
In SplashActivity, setContentView(R.layout.activity_splash) is called only for API 21 & 22.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/splashRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/splash" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/Widget.MaterialComponents.Toolbar.Primary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/colorAmoled"
|
||||
android:theme="@style/NPSTheme.ActionBar"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
tools:context=".fragments.mainactivity.MainActivityFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/appsRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
app:spanCount="2"
|
||||
tools:listitem="@layout/recycler_item_grid" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/tsvChooserButton"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginBottom="40dp"
|
||||
android:backgroundTint="@color/colorPrimary"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_add_24dp"
|
||||
app:borderWidth="2dp"
|
||||
app:fabCustomSize="52dp"
|
||||
app:layout_anchor="@+id/appsRecycler"
|
||||
app:layout_anchorGravity="bottom|center"
|
||||
app:maxImageSize="32dp" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -1,116 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="0dp">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="214dp"
|
||||
android:backgroundTint="@color/colorAmoled"
|
||||
app:cardBackgroundColor="@color/colorPrimary"
|
||||
app:cardElevation="4dp"
|
||||
app:cardUseCompatPadding="false"
|
||||
app:contentPadding="15dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView2"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_games_placeholder_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:ellipsize="marquee"
|
||||
android:enabled="true"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="@color/colorOnPrimary"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/imageView2"
|
||||
tools:text="App Title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appRegion"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rect_light_blue"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="ASIA" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appMinFW"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rect_red"
|
||||
android:padding="4dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/appRegion"
|
||||
tools:text="3.69" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appLastDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:padding="4dp"
|
||||
android:textColor="@color/colorOnSecondary"
|
||||
android:textSize="10sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="2018-04-22" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -1,105 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="0dp">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:backgroundTint="@color/colorAmoled"
|
||||
app:cardBackgroundColor="@color/colorPrimary"
|
||||
app:cardElevation="4dp"
|
||||
app:cardUseCompatPadding="false"
|
||||
app:contentPadding="15dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="56dp"
|
||||
android:contentDescription="app icon"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_games_placeholder_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:ellipsize="marquee"
|
||||
android:focusable="auto"
|
||||
android:focusableInTouchMode="true"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="@color/colorOnPrimary"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="App Title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appRegion"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:background="@drawable/rect_light_blue"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/appMinFW"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
||||
tools:text="ASIA" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appMinFW"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/rect_red"
|
||||
android:padding="4dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/appRegion"
|
||||
tools:text="3.69" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appLastDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp"
|
||||
android:textColor="@color/colorOnSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="2020-02-12" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/prefers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/prefs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/ic_search_24dp"
|
||||
android:title="@string/search"
|
||||
app:iconTint="?attr/colorOnPrimary"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_settings"
|
||||
android:title="@string/title_activity_settings"
|
||||
app:iconTint="?attr/colorOnPrimary"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
Reference in New Issue
Block a user