Skip to content

Guide screen #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 15, 2024
20 changes: 20 additions & 0 deletions ResistanceGuide.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"id": 0,
"name": "4-band",
"image": "https://www.shutterstock.com/image-vector/vector-electronics-component-resistor-260nw-41750524.jpg",
"description": "Overview:\n\n4-band resistors are identified by four colored bands that convey essential information about their resistance value.\n\nDetails:\n\n- First Significant Digit: Represents the first significant digit of the resistance value.\n- Second Significant Digit: Represents the second significant digit of the resistance value.\n- Multiplier: Indicates the multiplier, i.e., the number of zeros to append to the significant digits.\n- Tolerance: Represents the tolerance of the resistor, indicating the acceptable range of the resistance value.\n\nCalculation:\n\nCombine the values of the first two bands, multiply by the multiplier, and apply the tolerance.\n\nBenefits:\n\nThe 4-band resistor coding system is simple and commonly used."
},
{
"id": 1,
"name": "5-band",
"image": "https://circuitdigest.com/sites/default/files/inlineimages/5-band-resistor-color-code.png",
"description": "Overview:\n\n5-band resistors provide more precision than 4-band resistors by adding an extra digit to the resistance value.\n\nDetails:\n\n- First Significant Digit: Represents the first significant digit of the resistance value.\n- Second Significant Digit: Represents the second significant digit of the resistance value.\n- Third Significant Digit: Represents the third significant digit of the resistance value.\n- Multiplier: Indicates the multiplier, i.e., the number of zeros to append to the significant digits.\n- Tolerance: Represents the tolerance of the resistor, indicating the acceptable range of the resistance value.\n\nCalculation:\n\nCombine the values of the first three bands, multiply by the multiplier, and apply the tolerance.\n\nBenefits:\n\nThe 5-band system allows for a more precise representation of resistor values."
},
{
"id": 2,
"name": "6-band",
"image": "https://circuitdigest.com/sites/default/files/inlineimages/6-band-resistor.png",
"description": "Overview:\n\n6-band resistors are identified by six colored bands that convey essential information about their resistance value.\n\nDetails:\n\n- First Significant Digit: Represents the first significant digit of the resistance value.\n- Second Significant Digit: Represents the second significant digit of the resistance value.\n- Third Significant Digit: Represents the third significant digit of the resistance value.\n- Multiplier: Indicates the multiplier, i.e., the number of zeros to append to the significant digits.\n- Tolerance: Represents the tolerance of the resistor, indicating the acceptable range of the resistance value.\n\nCalculation:\n\nCombine the values of the first three bands, multiply by the multiplier, and apply the tolerance.\n\nBenefits:\n\nThe 6-band system allows for a more detailed representation of resistor values."
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import cafe.adriel.voyager.navigator.Navigator
import com.ammar.resistorassistant.screens.SplashScreen
import com.ammar.resistorassistant.screens.list.ListScreen

@Composable
fun App() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import io.ktor.client.call.body
import io.ktor.client.request.get
import io.ktor.utils.io.CancellationException

interface MuseumApi {
suspend fun getData(): List<MuseumObject>
interface AppAPI {
suspend fun getResistorData(): List<ResistorObject>
}

class KtorMuseumApi(private val client: HttpClient) : MuseumApi {
class KtorAppAPI(private val client: HttpClient) : AppAPI {
companion object {
private const val API_URL =
"https://raw.githubusercontent.com/Kotlin/KMP-App-Template/main/list.json"
"https://raw.githubusercontent.com/Ammar-Ishfaq/ResistanceCalculator/guideScreen/ResistanceGuide.json?token=GHSAT0AAAAAACIEJLUL3TFGABEEAM4VDZDUZM7Z4RQ"
}

override suspend fun getData(): List<MuseumObject> {
override suspend fun getResistorData(): List<ResistorObject> {
return try {
client.get(API_URL).body()
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch

class MuseumRepository(
private val museumApi: MuseumApi,
private val museumStorage: MuseumStorage,
class AppRepository(
private val appAPI: AppAPI,
private val appStorage: AppStorage,
) {
private val scope = CoroutineScope(SupervisorJob())

Expand All @@ -18,10 +18,10 @@ class MuseumRepository(
}

suspend fun refresh() {
museumStorage.saveObjects(museumApi.getData())
appStorage.saveObjects(appAPI.getResistorData())
}

fun getObjects(): Flow<List<MuseumObject>> = museumStorage.getObjects()
fun getObjects(): Flow<List<ResistorObject>> = appStorage.getObjects()

fun getObjectById(objectId: Int): Flow<MuseumObject?> = museumStorage.getObjectById(objectId)
fun getObjectById(objectId: Int): Flow<ResistorObject?> = appStorage.getObjectById(objectId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.ammar.resistorassistant.data

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map

interface AppStorage {
suspend fun saveObjects(newObjects: List<ResistorObject>)

fun getObjectById(objectId: Int): Flow<ResistorObject?>

fun getObjects(): Flow<List<ResistorObject>>
}

class InMemoryAppStorage : AppStorage {
private val storedObjects = MutableStateFlow(emptyList<ResistorObject>())

override suspend fun saveObjects(newObjects: List<ResistorObject>) {
storedObjects.value = newObjects
}

override fun getObjectById(id: Int): Flow<ResistorObject?> {
return storedObjects.map { objects ->
objects.find { it.id == id }
}
}

override fun getObjects(): Flow<List<ResistorObject>> = storedObjects
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ammar.resistorassistant.data

import kotlinx.serialization.Serializable

@Serializable
data class ResistorObject(
val id: Int,
val name: String,
val image: String,
val description: String
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.ammar.resistorassistant.di

import com.ammar.resistorassistant.data.InMemoryMuseumStorage
import com.ammar.resistorassistant.data.KtorMuseumApi
import com.ammar.resistorassistant.data.MuseumApi
import com.ammar.resistorassistant.data.MuseumRepository
import com.ammar.resistorassistant.data.MuseumStorage
import com.ammar.resistorassistant.data.InMemoryAppStorage
import com.ammar.resistorassistant.data.KtorAppAPI
import com.ammar.resistorassistant.data.AppAPI
import com.ammar.resistorassistant.data.AppRepository
import com.ammar.resistorassistant.data.AppStorage
import com.ammar.resistorassistant.screens.detail.DetailScreenModel
import com.ammar.resistorassistant.screens.list.ListScreenModel
import io.ktor.client.HttpClient
Expand All @@ -27,10 +27,10 @@ val dataModule = module {
}
}

single<MuseumApi> { KtorMuseumApi(get()) }
single<MuseumStorage> { InMemoryMuseumStorage() }
single<AppAPI> { KtorAppAPI(get()) }
single<AppStorage> { InMemoryAppStorage() }
single {
MuseumRepository(get(), get()).apply {
AppRepository(get(), get()).apply {
initialize()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ammar.resistorassistant.screens

import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
Expand All @@ -11,9 +12,10 @@ import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Info
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand All @@ -26,42 +28,63 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.ammar.resistorassistant.MR
import com.ammar.resistorassistant.extension.toCR
import com.ammar.resistorassistant.screens.band.*
import com.ammar.resistorassistant.screens.detail.DetailScreen
import com.ammar.resistorassistant.screens.list.ListScreenModel
import com.ammar.resistorassistant.screens.list.ObjectGrid

data object ResistanceCalculator : Screen {
@Composable
override fun Content() {
val screenModel: ListScreenModel = getScreenModel()
val navigator = LocalNavigator.currentOrThrow
val objects by screenModel.objects.collectAsState()

var selectedScreen by remember { mutableStateOf(ScreenType.HOME) }


val isHome = selectedScreen == ScreenType.HOME
Box(modifier = Modifier.fillMaxSize()) {
Column {
// Title header
Text(
text = if (isHome) "Res Calculate" else "Menu", // Replace with your desired title
text = if (isHome) "Res Calculate" else "Guide", // Replace with your desired title
style = MaterialTheme.typography.h4,
fontWeight = FontWeight.Bold,
modifier = Modifier.fillMaxWidth()
.background(color = MR.colors.background_color.toCR())
)

// Black box with padding
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f) // Takes up remaining space
.weight(1f)
.padding(16.dp)
) {
// Content for the box (e.g., screen-specific content)
when (selectedScreen) {
ScreenType.HOME -> {
HomeScreenContent()
}

ScreenType.MORE -> {
Text("MoreScreen Content")
ScreenType.GUIDE -> {

AnimatedContent(objects.isNotEmpty()) { objectsAvailable ->
if (objectsAvailable) {
ObjectGrid(
objects = objects,
onObjectClick = { objectId ->
navigator.push(DetailScreen(objectId))
}
)
} else {
EmptyScreenContent(Modifier.fillMaxSize())
}
}
}
}
}
Expand Down Expand Up @@ -91,7 +114,7 @@ fun BottomNavigationBar(
) {
val items = listOf(
BottomNavItem("Home", Icons.Default.Home, ScreenType.HOME),
BottomNavItem("More", Icons.Default.Menu, ScreenType.MORE)
BottomNavItem("More", Icons.Default.Info, ScreenType.GUIDE)
)

Row(
Expand Down Expand Up @@ -144,8 +167,9 @@ fun BottomNavItemButton(modifier: Modifier, item: BottomNavItem) {
data class BottomNavItem(val title: String, val icon: ImageVector, val screenType: ScreenType)
enum class ScreenType {
HOME,
MORE
GUIDE
}

@Composable
fun HomeScreenContent() {
var selectedBand by remember { mutableStateOf(4) }
Expand Down Expand Up @@ -191,9 +215,11 @@ fun HomeScreenContent() {
4 -> {
FourBandResistorCalculator()
}

5 -> {
FiveBandResistorCalculator()
}

6 -> {
SixBandResistorCalculator()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.ammar.resistorassistant.MR
import com.ammar.resistorassistant.data.MuseumObject
import com.ammar.resistorassistant.data.ResistorObject
import com.ammar.resistorassistant.screens.EmptyScreenContent
import dev.icerock.moko.resources.compose.stringResource
import io.kamel.image.KamelImage
Expand All @@ -60,7 +60,7 @@ data class DetailScreen(val objectId: Int) : Screen {

@Composable
private fun ObjectDetails(
obj: MuseumObject,
obj: ResistorObject,
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Expand All @@ -80,8 +80,8 @@ private fun ObjectDetails(
.padding(paddingValues)
) {
KamelImage(
resource = asyncPainterResource(data = obj.primaryImageSmall),
contentDescription = obj.title,
resource = asyncPainterResource(data = obj.image),
contentDescription = obj.name,
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
Expand All @@ -90,16 +90,14 @@ private fun ObjectDetails(

SelectionContainer {
Column(Modifier.padding(12.dp)) {
Text(obj.title, style = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold))
Text(
obj.name,
style = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold)
)
Spacer(Modifier.height(6.dp))
LabeledInfo(stringResource(MR.strings.label_title), obj.title)
LabeledInfo(stringResource(MR.strings.label_artist), obj.artistDisplayName)
LabeledInfo(stringResource(MR.strings.label_date), obj.objectDate)
LabeledInfo(stringResource(MR.strings.label_dimensions), obj.dimensions)
LabeledInfo(stringResource(MR.strings.label_medium), obj.medium)
LabeledInfo(stringResource(MR.strings.label_department), obj.department)
LabeledInfo(stringResource(MR.strings.label_repository), obj.repository)
LabeledInfo(stringResource(MR.strings.label_credits), obj.creditLine)
LabeledInfo(stringResource(MR.strings.label_title), obj.name)
LabeledInfo(stringResource(MR.strings.label_description), obj.description)

}
}
}
Expand All @@ -124,3 +122,4 @@ private fun LabeledInfo(
)
}
}

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.ammar.resistorassistant.screens.detail

import cafe.adriel.voyager.core.model.ScreenModel
import com.ammar.resistorassistant.data.MuseumObject
import com.ammar.resistorassistant.data.MuseumRepository
import com.ammar.resistorassistant.data.ResistorObject
import com.ammar.resistorassistant.data.AppRepository
import kotlinx.coroutines.flow.Flow

class DetailScreenModel(private val museumRepository: MuseumRepository) : ScreenModel {
fun getObject(objectId: Int): Flow<MuseumObject?> =
museumRepository.getObjectById(objectId)
class DetailScreenModel(private val appRepository: AppRepository) : ScreenModel {
fun getObject(objectId: Int): Flow<ResistorObject?> =
appRepository.getObjectById(objectId)
}
Loading