diff --git a/app/build.gradle b/app/build.gradle index e27ea97..396501f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,17 +6,17 @@ plugins { } android { - namespace 'dev.garousi.stock_watcher' + namespace 'dev.garousi.stockwatcher' compileSdk 33 defaultConfig { - applicationId "dev.garousi.stock_watcher" + applicationId "dev.garousi.stockwatcher" minSdk 23 targetSdk 33 versionCode 1 versionName "1.0" - testInstrumentationRunner "dev.garousi.stock_watcher.HiltTestRunner" + testInstrumentationRunner "dev.garousi.stockwatcher.HiltTestRunner" vectorDrawables { useSupportLibrary true } diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/HiltTestRunner.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/HiltTestRunner.kt similarity index 86% rename from app/src/androidTest/java/dev/garousi/stock_watcher/HiltTestRunner.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/HiltTestRunner.kt index 2d98ff4..7724784 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/HiltTestRunner.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/HiltTestRunner.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher +package dev.garousi.stockwatcher import android.app.Application import android.content.Context @@ -9,8 +9,8 @@ class HiltTestRunner : AndroidJUnitRunner() { override fun newApplication( cl: ClassLoader?, className: String?, - context: Context? + context: Context?, ): Application { return super.newApplication(cl, HiltTestApplication::class.java.name, context) } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItemTest.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItemTest.kt similarity index 84% rename from app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItemTest.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItemTest.kt index 297c5fe..bbf89ab 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItemTest.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItemTest.kt @@ -1,15 +1,14 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick import com.google.common.truth.Truth.assertThat -import dev.garousi.stock_watcher.feature.watchlist.domain.repository.stocks -import dev.garousi.stock_watcher.ui.theme.StockWatcherTheme +import dev.garousi.stockwatcher.feature.watchlist.domain.repository.stocks +import dev.garousi.stockwatcher.ui.theme.StockWatcherTheme import org.junit.Rule import org.junit.Test - class StockItemTest { @get:Rule val composeTestRule = createComposeRule() @@ -23,7 +22,8 @@ class StockItemTest { setContent { StockWatcherTheme(true) { StockItem( - stock = actualStockItem, index = 0 + stock = actualStockItem, + index = 0, ) } } @@ -50,4 +50,4 @@ class StockItemTest { assertThat(hasClickedOnStockItem).isTrue() } } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockListTest.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockListTest.kt similarity index 91% rename from app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockListTest.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockListTest.kt index f19e6ee..7dbe47a 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockListTest.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockListTest.kt @@ -1,16 +1,15 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performScrollToIndex -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock -import dev.garousi.stock_watcher.feature.watchlist.domain.repository.stocks -import dev.garousi.stock_watcher.ui.theme.StockWatcherTheme -import java.time.LocalTime -import java.util.UUID +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.feature.watchlist.domain.repository.stocks +import dev.garousi.stockwatcher.ui.theme.StockWatcherTheme import org.junit.Rule import org.junit.Test - +import java.time.LocalTime +import java.util.UUID class StockListTest { @get:Rule @@ -75,8 +74,8 @@ class StockListTest { min = min, max = max, ref = ref, - open = open - ) + open = open, + ), ) } with(composeTestRule) { @@ -105,10 +104,8 @@ class StockListTest { } } } - } - private val testStocks = arrayListOf().apply { add( Stock( @@ -124,8 +121,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1010.0 - ) + open = 1010.0, + ), ) add( Stock( @@ -141,8 +138,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -158,8 +155,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -175,8 +172,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -192,8 +189,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -209,8 +206,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -226,8 +223,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -243,8 +240,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -260,8 +257,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -277,8 +274,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -294,8 +291,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -311,8 +308,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -328,8 +325,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -345,7 +342,7 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockTestHelper.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockTestHelper.kt similarity index 83% rename from app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockTestHelper.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockTestHelper.kt index ce2affb..0b19f70 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockTestHelper.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockTestHelper.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed @@ -7,54 +7,51 @@ import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onChildren import androidx.compose.ui.test.onNodeWithTag -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock - +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock fun ComposeContentTestRule.assertArrowIsDisplayed( - actualStockItemIndex: Int + actualStockItemIndex: Int, ) = onNodeWithTag(StockItemTestTags.arrow + actualStockItemIndex, true) .assertIsDisplayed() fun ComposeContentTestRule.assertPriceChangeIsDisplayed( actualStockItemIndex: Int, - actualStockItem: Stock + actualStockItem: Stock, ) { val expectedPriceChange = buildString { append("+").append(actualStockItem.change) } onNodeWithTag( StockItemTestTags.priceChange + actualStockItemIndex, - true + true, ).assertIsDisplayed().assertTextEquals(expectedPriceChange) } fun ComposeContentTestRule.assertLastPriceIsDisplayed( actualStockItemIndex: Int, - actualStockItem: Stock + actualStockItem: Stock, ) { onNodeWithTag( StockItemTestTags.lastPrice + actualStockItemIndex, - true + true, ).assertIsDisplayed().assertTextEquals(actualStockItem.last.toString()) } fun ComposeContentTestRule.assertNameIsDisplayed( actualStockItemIndex: Int, - actualStockItem: Stock + actualStockItem: Stock, ) { onNodeWithTag( StockItemTestTags.name + actualStockItemIndex, - true + true, ).assertIsDisplayed().assertTextEquals(actualStockItem.name) } fun ComposeContentTestRule.assertCardIsDisplayed( - actualStockItemIndex: Int + actualStockItemIndex: Int, ) = onNodeWithTag(StockItemTestTags.card + actualStockItemIndex).assertIsDisplayed() .assertHasClickAction() - - fun ComposeTestRule.getVisibleStockListSize(testTag: String): Int { return onNodeWithTag(testTag).onChildren().fetchSemanticsNodes().size -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreenTest.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreenTest.kt similarity index 90% rename from app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreenTest.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreenTest.kt index cb81f6e..3f1d23b 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreenTest.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreenTest.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.activity.ComponentActivity import androidx.compose.ui.test.assertHasClickAction @@ -7,12 +7,12 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performScrollToKey import androidx.compose.ui.test.printToLog -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock -import dev.garousi.stock_watcher.ui.theme.StockWatcherTheme -import java.time.LocalTime -import java.util.UUID +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.ui.theme.StockWatcherTheme import org.junit.Rule import org.junit.Test +import java.time.LocalTime +import java.util.UUID class WatchlistScreenTest { @@ -26,7 +26,7 @@ class WatchlistScreenTest { StockWatcherTheme(true) { WatchlistScreen( stocks = emptyList(), - isLoading = true + isLoading = true, ) } } @@ -37,7 +37,7 @@ class WatchlistScreenTest { composeTestRule .onNodeWithTag( testTag = watchlistStocksLoadingWheel, - useUnmergedTree = true + useUnmergedTree = true, ) .assertExists() } @@ -49,7 +49,7 @@ class WatchlistScreenTest { StockWatcherTheme(true) { WatchlistScreen( stocks = testStocks, - isLoading = false + isLoading = false, ) } } @@ -85,20 +85,18 @@ class WatchlistScreenTest { StockWatcherTheme(true) { WatchlistScreen( stocks = emptyList(), - isLoading = false + isLoading = false, ) } } onNodeWithTag( testTag = watchlistStocksEmpty, - useUnmergedTree = true + useUnmergedTree = true, ).assertExists() } - } } - private val testStocks = arrayListOf().apply { add( Stock( @@ -114,8 +112,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1010.0 - ) + open = 1010.0, + ), ) add( Stock( @@ -131,8 +129,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -148,8 +146,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -165,8 +163,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -182,8 +180,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -199,8 +197,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -216,8 +214,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -233,8 +231,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -250,8 +248,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -267,8 +265,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -284,8 +282,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -301,8 +299,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -318,8 +316,8 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) add( Stock( @@ -335,7 +333,7 @@ private val testStocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/dev/garousi/stock_watcher/utils/ComposeTestExtensions.kt b/app/src/androidTest/java/dev/garousi/stockwatcher/utils/ComposeTestExtensions.kt similarity index 66% rename from app/src/androidTest/java/dev/garousi/stock_watcher/utils/ComposeTestExtensions.kt rename to app/src/androidTest/java/dev/garousi/stockwatcher/utils/ComposeTestExtensions.kt index 413b03e..222980c 100644 --- a/app/src/androidTest/java/dev/garousi/stock_watcher/utils/ComposeTestExtensions.kt +++ b/app/src/androidTest/java/dev/garousi/stockwatcher/utils/ComposeTestExtensions.kt @@ -1,15 +1,15 @@ -package dev.garousi.stock_watcher.utils +package dev.garousi.stockwatcher.utils import androidx.annotation.DrawableRes import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.test.SemanticsMatcher -import dev.garousi.stock_watcher.ui.ColorRes -import dev.garousi.stock_watcher.ui.DrawableId -import dev.garousi.stock_watcher.ui.ImageVectorId +import dev.garousi.stockwatcher.ui.ColorRes +import dev.garousi.stockwatcher.ui.DrawableId +import dev.garousi.stockwatcher.ui.ImageVectorId fun hasDrawable(@DrawableRes id: Int): SemanticsMatcher = SemanticsMatcher.expectValue(DrawableId, id) fun hasImageVector(imageVector: ImageVector): SemanticsMatcher = SemanticsMatcher.expectValue(ImageVectorId, imageVector) -fun hasBackgroundColor(expectedBackgroundColor: Color) = SemanticsMatcher.expectValue(ColorRes, expectedBackgroundColor) \ No newline at end of file +fun hasBackgroundColor(expectedBackgroundColor: Color) = SemanticsMatcher.expectValue(ColorRes, expectedBackgroundColor) diff --git a/app/src/debug/java/AndroidManifest.xml b/app/src/debug/java/AndroidManifest.xml index d3c0bac..0fc518c 100644 --- a/app/src/debug/java/AndroidManifest.xml +++ b/app/src/debug/java/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="dev.garousi.stockwatcher"> diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/SubscriptionMode.kt b/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/SubscriptionMode.kt deleted file mode 100644 index 69102ac..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/SubscriptionMode.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.garousi.stock_watcher.feature.watchlist.data - -enum class SubscriptionMode(mode: String) { - Merge("MERGE"), - Command("COMMAND") -} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepository.kt b/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepository.kt deleted file mode 100644 index 1344737..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.garousi.stock_watcher.feature.watchlist.domain.repository - -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock -import kotlinx.coroutines.flow.Flow - -interface StockRepository { - fun getStocks(): Flow> -} \ No newline at end of file diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt b/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt deleted file mode 100644 index 657e3f5..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.garousi.stock_watcher.feature.watchlist.domain.usecases - -import dev.garousi.stock_watcher.feature.watchlist.domain.repository.StockRepository -import dev.garousi.stock_watcher.feature.watchlist.presentation.WatchlistState -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow - -class GetStockListUseCase constructor( - private val repository: StockRepository -) { - operator fun invoke(): Flow { - return flow { } - } -} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/StockListUseCases.kt b/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/StockListUseCases.kt deleted file mode 100644 index 448830c..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/usecases/StockListUseCases.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.garousi.stock_watcher.feature.watchlist.domain.usecases - -data class StockListUseCases( - internal val getStockList: GetStockListUseCase -) diff --git a/app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherIcons.kt b/app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherIcons.kt deleted file mode 100644 index ee5229e..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherIcons.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.garousi.stock_watcher.navigation - -import androidx.annotation.DrawableRes -import androidx.compose.ui.graphics.vector.ImageVector - -/** - * A sealed class to make dealing with [ImageVector] and [DrawableRes] icons easier. - */ -sealed class Icon { - data class ImageVectorIcon(val imageVector: ImageVector) : Icon() - data class DrawableResourceIcon(@DrawableRes val id: Int) : Icon() -} diff --git a/app/src/main/java/dev/garousi/stock_watcher/navigation/TopLevelDestination.kt b/app/src/main/java/dev/garousi/stock_watcher/navigation/TopLevelDestination.kt deleted file mode 100644 index 791f0d3..0000000 --- a/app/src/main/java/dev/garousi/stock_watcher/navigation/TopLevelDestination.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.garousi.stock_watcher.navigation - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Home -import androidx.compose.material.icons.outlined.Home -import dev.garousi.stock_watcher.R - -enum class TopLevelDestination( - val selectedIcon: Icon, - val unselectedIcon: Icon, - val iconTextId: Int, - val titleTextId: Int -) { - WATCHLIST( - selectedIcon = Icon.ImageVectorIcon(Icons.Default.Home), - unselectedIcon = Icon.ImageVectorIcon(Icons.Outlined.Home), - iconTextId = R.string.home, - titleTextId = R.string.home, - ) -} \ No newline at end of file diff --git a/app/src/main/java/dev/garousi/stock_watcher/MainActivity.kt b/app/src/main/java/dev/garousi/stockwatcher/MainActivity.kt similarity index 84% rename from app/src/main/java/dev/garousi/stock_watcher/MainActivity.kt rename to app/src/main/java/dev/garousi/stockwatcher/MainActivity.kt index 27cd8a4..b9994b2 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/MainActivity.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/MainActivity.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher +package dev.garousi.stockwatcher import android.os.Bundle import androidx.activity.ComponentActivity @@ -6,8 +6,8 @@ import androidx.activity.compose.setContent import androidx.compose.ui.ExperimentalComposeUiApi import androidx.metrics.performance.JankStats import dagger.hilt.android.AndroidEntryPoint -import dev.garousi.stock_watcher.ui.StockWatcherApp -import dev.garousi.stock_watcher.ui.theme.StockWatcherTheme +import dev.garousi.stockwatcher.ui.StockWatcherApp +import dev.garousi.stockwatcher.ui.theme.StockWatcherTheme import javax.inject.Inject @OptIn(ExperimentalComposeUiApi::class) @@ -23,7 +23,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { StockWatcherTheme( - darkTheme = true + darkTheme = true, ) { StockWatcherApp() } @@ -39,4 +39,4 @@ class MainActivity : ComponentActivity() { super.onPause() lazyStats.get().isTrackingEnabled = false } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/StockWatcherApp.kt b/app/src/main/java/dev/garousi/stockwatcher/StockWatcherApp.kt similarity index 56% rename from app/src/main/java/dev/garousi/stock_watcher/StockWatcherApp.kt rename to app/src/main/java/dev/garousi/stockwatcher/StockWatcherApp.kt index 83a2c4b..f783653 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/StockWatcherApp.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/StockWatcherApp.kt @@ -1,7 +1,7 @@ -package dev.garousi.stock_watcher +package dev.garousi.stockwatcher import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class StockWatcherApp : Application() \ No newline at end of file +class StockWatcherApp : Application() diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptyClientListener.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptyClientListener.kt similarity index 88% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptyClientListener.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptyClientListener.kt index 07f500b..4ba1330 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptyClientListener.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptyClientListener.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import com.lightstreamer.client.ClientListener import com.lightstreamer.client.LightstreamerClient @@ -9,4 +9,4 @@ object EmptyClientListener : ClientListener { override fun onServerError(errorCode: Int, errorMessage: String) = Unit override fun onStatusChange(status: String) = Unit override fun onPropertyChange(property: String) = Unit -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptySubscriptionListener.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptySubscriptionListener.kt similarity index 94% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptySubscriptionListener.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptySubscriptionListener.kt index 49af670..1f7869c 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/EmptySubscriptionListener.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/EmptySubscriptionListener.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import com.lightstreamer.client.ItemUpdate import com.lightstreamer.client.Subscription @@ -28,4 +28,4 @@ object EmptySubscriptionListener : SubscriptionListener { override fun onUnsubscription() = Unit override fun onRealMaxFrequency(frequency: String?) = Unit -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerConnection.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerConnection.kt similarity index 92% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerConnection.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerConnection.kt index e19601a..19b0b9c 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerConnection.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerConnection.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import android.util.Log import com.lightstreamer.client.ClientListener @@ -19,7 +19,7 @@ interface LightStreamerConnection { requestedSnapshot: String? = null, requestedMaxFrequency: String? = null, itemNames: Array, - fieldNames: Array + fieldNames: Array, ): Subscription? fun subscribe( @@ -28,7 +28,7 @@ interface LightStreamerConnection { requestedSnapshot: String? = null, requestedMaxFrequency: String? = null, itemName: String, - fieldNames: Array + fieldNames: Array, ): Subscription? fun unsubscribe() @@ -36,22 +36,20 @@ interface LightStreamerConnection { fun setSubscription( subscriptionMode: SubscriptionMode, itemNames: Array, - fieldNames: Array + fieldNames: Array, ) fun setSubscription( subscriptionMode: SubscriptionMode, itemName: String, - fieldNames: Array + fieldNames: Array, ) fun setRequestedSnapshot(requestedSnapshot: String?) fun setRequestedMaxFrequency(requestedMaxFrequency: String?) } -class LightStreamerConnectionImpl @Inject constructor( - -) : LightStreamerConnection { +class LightStreamerConnectionImpl @Inject constructor() : LightStreamerConnection { override var lsClient: LightstreamerClient? = null override var subscription: Subscription? = null @@ -85,7 +83,7 @@ class LightStreamerConnectionImpl @Inject constructor( requestedSnapshot: String?, requestedMaxFrequency: String?, itemNames: Array, - fieldNames: Array + fieldNames: Array, ): Subscription? { this.setSubscription(subscriptionMode, itemNames, fieldNames) this.setDataAdapter(dataAdapter) @@ -103,7 +101,6 @@ class LightStreamerConnectionImpl @Inject constructor( } } - override fun setRequestedMaxFrequency(requestedMaxFrequency: String?) { if (requestedMaxFrequency != null) { this.subscription?.requestedMaxFrequency = requestedMaxFrequency @@ -118,7 +115,7 @@ class LightStreamerConnectionImpl @Inject constructor( requestedSnapshot: String?, requestedMaxFrequency: String?, itemName: String, - fieldNames: Array + fieldNames: Array, ): Subscription? { this.setSubscription(subscriptionMode, itemName, fieldNames) this.setDataAdapter(dataAdapter) @@ -150,7 +147,7 @@ class LightStreamerConnectionImpl @Inject constructor( override fun setSubscription( subscriptionMode: SubscriptionMode, itemNames: Array, - fieldNames: Array + fieldNames: Array, ) { subscription = Subscription(subscriptionMode.name, itemNames, fieldNames) } @@ -158,8 +155,8 @@ class LightStreamerConnectionImpl @Inject constructor( override fun setSubscription( subscriptionMode: SubscriptionMode, itemName: String, - fieldNames: Array + fieldNames: Array, ) { subscription = Subscription(subscriptionMode.name, itemName, fieldNames) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerService.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerService.kt similarity index 84% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerService.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerService.kt index a5f734d..aa3d9ba 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/LightStreamerService.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/LightStreamerService.kt @@ -1,13 +1,12 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import com.lightstreamer.client.ItemUpdate import kotlinx.coroutines.flow.StateFlow - interface LightStreamerService { val flow: StateFlow fun subscribe(vararg params: Any): LightStreamerService fun unsubscribe() fun observeSubscriptionUpdates() fun setFieldsToDto(itemUpdate: ItemUpdate) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StatefulData.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StatefulData.kt similarity index 54% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StatefulData.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StatefulData.kt index c90f6e0..e79805d 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StatefulData.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StatefulData.kt @@ -1,16 +1,16 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.transform sealed class StatefulData { - data class Success(val result : T) : StatefulData() - data class Error(val msg : String) : StatefulData() + data class Success(val result: T) : StatefulData() + data class Error(val msg: String) : StatefulData() object Loading : StatefulData() inline fun map(transform: (T) -> R): StatefulData { - return when(this) { + return when (this) { is Loading -> Loading is Error -> Error(this.msg) is Success -> Success(transform(this.result)) @@ -18,32 +18,31 @@ sealed class StatefulData { } suspend inline fun suspendMap(crossinline transform: suspend (T) -> R): StatefulData { - return when(this) { + return when (this) { is Loading -> Loading is Error -> Error(this.msg) is Success -> Success(transform(this.result)) } } - } -fun Flow.asStatefulData(): Flow> = wrapWithStatefulData() +fun Flow.asStatefulData(): Flow> = wrapWithStatefulData() .catch { emit(StatefulData.Error(it.message ?: "There was an error")) } -fun Flow.wrapWithStatefulData() : Flow> = transform { value -> +fun Flow.wrapWithStatefulData(): Flow> = transform { value -> return@transform emit(StatefulData.Success(value)) } -inline fun Flow>.mapState(crossinline transform: suspend (value: T) -> R): Flow> = transform { value -> +inline fun Flow>.mapState(crossinline transform: suspend (value: T) -> R): Flow> = transform { value -> return@transform emit(value.suspendMap(transform)) } -inline fun Flow>.onSuccessState(crossinline action: suspend (value: T) -> Unit): Flow> = onEach { +inline fun Flow>.onSuccessState(crossinline action: suspend (value: T) -> Unit): Flow> = onEach { if (it is StatefulData.Success) action(it.result) } -inline fun Flow>.onErrorState(crossinline action: suspend (error: String) -> Unit): Flow> = onEach { +inline fun Flow>.onErrorState(crossinline action: suspend (error: String) -> Unit): Flow> = onEach { if (it is StatefulData.Error) action(it.msg) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListDto.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListDto.kt similarity index 84% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListDto.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListDto.kt index 79b1a3f..a1dd754 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListDto.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListDto.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import java.time.LocalTime @@ -16,5 +16,5 @@ data class StockListDto( val min: Double? = null, val max: Double? = null, val ref: Double? = null, - val open: Double? = null + val open: Double? = null, ) diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListLightStreamerService.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListLightStreamerService.kt similarity index 96% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListLightStreamerService.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListLightStreamerService.kt index 8d67cc3..e1b702b 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/data/StockListLightStreamerService.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/StockListLightStreamerService.kt @@ -1,11 +1,9 @@ -package dev.garousi.stock_watcher.feature.watchlist.data +package dev.garousi.stockwatcher.feature.watchlist.data import android.util.Log import com.lightstreamer.client.ItemUpdate import com.lightstreamer.client.Subscription import com.lightstreamer.client.SubscriptionListener -import java.time.LocalTime -import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -13,9 +11,11 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import java.time.LocalTime +import javax.inject.Inject class StockListLightStreamerService @Inject constructor( - private val connection: LightStreamerConnection + private val connection: LightStreamerConnection, ) : LightStreamerService { private val scope = CoroutineScope(SupervisorJob()) @@ -59,7 +59,7 @@ class StockListLightStreamerService @Inject constructor( "item12", "item13", "item14", - "item15" + "item15", ) val fieldNames = arrayOf( LAST_PRICE, @@ -86,12 +86,11 @@ class StockListLightStreamerService @Inject constructor( fieldNames = fieldNames, dataAdapter = "QUOTE_ADAPTER", requestedSnapshot = "yes", - requestedMaxFrequency = "1" + requestedMaxFrequency = "1", ) return this } - override fun observeSubscriptionUpdates() { this.connection.subscriptionListener = object : SubscriptionListener by EmptySubscriptionListener { @@ -162,5 +161,4 @@ class StockListLightStreamerService @Inject constructor( connection.unsubscribe() scope.cancel() } - -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/SubscriptionMode.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/SubscriptionMode.kt new file mode 100644 index 0000000..1114eeb --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/data/SubscriptionMode.kt @@ -0,0 +1,6 @@ +package dev.garousi.stockwatcher.feature.watchlist.data + +enum class SubscriptionMode(mode: String) { + Merge("MERGE"), + Command("COMMAND"), +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/JankStatsModule.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/JankStatsModule.kt similarity index 93% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/JankStatsModule.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/JankStatsModule.kt index 3e8c5ce..52e1d0b 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/JankStatsModule.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/JankStatsModule.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package dev.garousi.stock_watcher.feature.watchlist.di +package dev.garousi.stockwatcher.feature.watchlist.di import android.app.Activity import android.util.Log @@ -47,7 +47,7 @@ object JankStatsModule { @Provides fun providesJankStats( window: Window, - frameListener: JankStats.OnFrameListener + frameListener: JankStats.OnFrameListener, ): JankStats { return JankStats.createAndTrack(window, frameListener) } diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/LightStreamerModule.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/LightStreamerModule.kt similarity index 62% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/LightStreamerModule.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/LightStreamerModule.kt index bab1dab..3407ab4 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/LightStreamerModule.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/LightStreamerModule.kt @@ -1,11 +1,11 @@ -package dev.garousi.stock_watcher.feature.watchlist.di +package dev.garousi.stockwatcher.feature.watchlist.di import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import dev.garousi.stock_watcher.feature.watchlist.data.LightStreamerConnection -import dev.garousi.stock_watcher.feature.watchlist.data.LightStreamerConnectionImpl +import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnection +import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnectionImpl import javax.inject.Singleton @Module @@ -14,4 +14,4 @@ abstract class LightStreamerModule { @Binds @Singleton abstract fun bindsLightStreamerService(impl: LightStreamerConnectionImpl): LightStreamerConnection -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/StockRepositoryModule.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/StockRepositoryModule.kt similarity index 59% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/StockRepositoryModule.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/StockRepositoryModule.kt index 96cccd6..2fd4184 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/StockRepositoryModule.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/StockRepositoryModule.kt @@ -1,11 +1,11 @@ -package dev.garousi.stock_watcher.feature.watchlist.di +package dev.garousi.stockwatcher.feature.watchlist.di import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import dev.garousi.stock_watcher.feature.watchlist.domain.repository.StockRepository -import dev.garousi.stock_watcher.feature.watchlist.domain.repository.StockRepositoryImpl +import dev.garousi.stockwatcher.feature.watchlist.domain.repository.StockRepository +import dev.garousi.stockwatcher.feature.watchlist.domain.repository.StockRepositoryImpl import javax.inject.Singleton @Module @@ -14,4 +14,4 @@ abstract class StockRepositoryModule { @Binds @Singleton abstract fun bindsStockRepository(impl: StockRepositoryImpl): StockRepository -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/WatchlistListModule.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/WatchlistListModule.kt similarity index 66% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/WatchlistListModule.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/WatchlistListModule.kt index 0974762..5a044b0 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/di/WatchlistListModule.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/di/WatchlistListModule.kt @@ -1,13 +1,13 @@ -package dev.garousi.stock_watcher.feature.watchlist.di +package dev.garousi.stockwatcher.feature.watchlist.di import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import dev.garousi.stock_watcher.feature.watchlist.data.LightStreamerConnection -import dev.garousi.stock_watcher.feature.watchlist.data.LightStreamerService -import dev.garousi.stock_watcher.feature.watchlist.data.StockListDto -import dev.garousi.stock_watcher.feature.watchlist.data.StockListLightStreamerService +import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnection +import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerService +import dev.garousi.stockwatcher.feature.watchlist.data.StockListDto +import dev.garousi.stockwatcher.feature.watchlist.data.StockListLightStreamerService import javax.inject.Singleton @Module @@ -30,8 +30,8 @@ object WatchlistListModule { @Provides @Singleton fun provideStockListLightStreamerService( - connection: LightStreamerConnection + connection: LightStreamerConnection, ): LightStreamerService { return StockListLightStreamerService(connection = connection) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/models/Stock.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/models/Stock.kt similarity index 82% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/models/Stock.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/models/Stock.kt index 104d426..6851c6a 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/models/Stock.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/models/Stock.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.domain.models +package dev.garousi.stockwatcher.feature.watchlist.domain.models import java.time.LocalTime @@ -15,5 +15,5 @@ data class Stock( val min: Double = Double.NaN, val max: Double = Double.NaN, val ref: Double = Double.NaN, - val open: Double = Double.NaN + val open: Double = Double.NaN, ) diff --git a/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepository.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepository.kt new file mode 100644 index 0000000..75dc214 --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepository.kt @@ -0,0 +1,8 @@ +package dev.garousi.stockwatcher.feature.watchlist.domain.repository + +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import kotlinx.coroutines.flow.Flow + +interface StockRepository { + fun getStocks(): Flow> +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt similarity index 78% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt index cb7fd17..1744e93 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/repository/StockRepositoryImpl.kt @@ -1,15 +1,13 @@ -package dev.garousi.stock_watcher.feature.watchlist.domain.repository +package dev.garousi.stockwatcher.feature.watchlist.domain.repository -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow import java.time.LocalTime import java.util.UUID import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow - -class StockRepositoryImpl @Inject constructor( -) : StockRepository { +class StockRepositoryImpl @Inject constructor() : StockRepository { override fun getStocks(): Flow> { return flow { emit(stocks) } } @@ -30,8 +28,8 @@ val stocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1010.0 - ) + open = 1010.0, + ), ) add( Stock( @@ -47,7 +45,7 @@ val stocks = arrayListOf().apply { min = 999.0, max = 1580.0, ref = 124.0, - open = 1710.0 - ) + open = 1710.0, + ), ) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt new file mode 100644 index 0000000..92f08e6 --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/GetStockListUseCase.kt @@ -0,0 +1,14 @@ +package dev.garousi.stockwatcher.feature.watchlist.domain.usecases + +import dev.garousi.stockwatcher.feature.watchlist.domain.repository.StockRepository +import dev.garousi.stockwatcher.feature.watchlist.presentation.WatchlistState +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow + +class GetStockListUseCase constructor( + private val repository: StockRepository, +) { + operator fun invoke(): Flow { + return flow { } + } +} diff --git a/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/StockListUseCases.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/StockListUseCases.kt new file mode 100644 index 0000000..e228f56 --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/domain/usecases/StockListUseCases.kt @@ -0,0 +1,5 @@ +package dev.garousi.stockwatcher.feature.watchlist.domain.usecases + +data class StockListUseCases( + internal val getStockList: GetStockListUseCase, +) diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItem.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItem.kt similarity index 84% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItem.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItem.kt index bf5bbfd..da7f5ef 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockItem.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockItem.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -35,9 +35,9 @@ import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock -import dev.garousi.stock_watcher.ui.colorRes -import dev.garousi.stock_watcher.ui.imageVectorId +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.ui.colorRes +import dev.garousi.stockwatcher.ui.imageVectorId @OptIn(ExperimentalMaterialApi::class) @Composable @@ -45,7 +45,7 @@ fun StockItem( stock: Stock, index: Int, backgroundColor: Color = MaterialTheme.colors.surface, - onClick: (Stock) -> Unit = {} + onClick: (Stock) -> Unit = {}, ) { val density = LocalDensity.current Card( @@ -53,7 +53,7 @@ fun StockItem( contentColor = MaterialTheme.colors.onSurface, modifier = Modifier .padding( - bottom = 8.dp + bottom = 8.dp, ) .testTag(StockItemTestTags.card + index) .drawBehind { @@ -69,7 +69,7 @@ fun StockItem( density.run { 8.dp.toPx() }, density.run { 2.dp.toPx() }, density.run { 2.dp.toPx() }, - shadowColor + shadowColor, ) it.drawRoundRect( 0f, @@ -78,27 +78,27 @@ fun StockItem( this.size.height, density.run { 2.dp.toPx() }, density.run { 2.dp.toPx() }, - paint + paint, ) } drawRoundRect( color = if (stock.change > 0) Color.Green else Color.Red, topLeft = Offset( x = size.width - density.run { 12.dp.toPx() }, - y = density.run { 4.dp.toPx() } + y = density.run { 4.dp.toPx() }, ), size = Size( width = density.run { 17.dp.toPx() }, - height = density.run { 48.dp.toPx() } + height = density.run { 48.dp.toPx() }, ), cornerRadius = CornerRadius( x = density.run { 8.dp.toPx() }, - y = density.run { 8.dp.toPx() } - ) + y = density.run { 8.dp.toPx() }, + ), ) }, onClick = { onClick(stock) }, - shape = RoundedCornerShape(8.dp) + shape = RoundedCornerShape(8.dp), ) { Row( modifier = Modifier @@ -106,23 +106,23 @@ fun StockItem( .height(56.dp) .padding(12.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = stock.name, style = MaterialTheme.typography.body1.copy( - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, ), modifier = Modifier .weight(0.5f) - .testTag(StockItemTestTags.name + index) + .testTag(StockItemTestTags.name + index), ) Row( modifier = Modifier .weight(0.5f) .fillMaxSize(), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = "${stock.last}", @@ -132,17 +132,21 @@ fun StockItem( .width(72.dp) .drawBehind { drawRoundRect( - color = if (stock.change > 0) Color(0XFF48BE62) else Color( - 0XFFBE4848 - ), + color = if (stock.change > 0) { + Color(0XFF48BE62) + } else { + Color( + 0XFFBE4848, + ) + }, cornerRadius = CornerRadius( x = density.run { 4.dp.toPx() }, - y = density.run { 4.dp.toPx() } - ) + y = density.run { 4.dp.toPx() }, + ), ) } .padding(vertical = 2.dp, horizontal = 16.dp) - .testTag(StockItemTestTags.lastPrice + index) + .testTag(StockItemTestTags.lastPrice + index), ) Spacer(modifier = Modifier.width(24.dp)) Text( @@ -152,7 +156,7 @@ fun StockItem( }, modifier = Modifier.testTag(StockItemTestTags.priceChange + index), style = MaterialTheme.typography.subtitle1, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Icon( imageVector = if (stock.change > 0) Icons.Filled.KeyboardArrowUp else Icons.Filled.KeyboardArrowDown, @@ -165,18 +169,17 @@ fun StockItem( if (stock.change > 0) Icons.Filled.KeyboardArrowUp else Icons.Filled.KeyboardArrowDown colorRes = if (stock.change > 0) Color(0XFF48BE62) else Color(0XFFBE4848) - } + }, ) } } } } - object StockItemTestTags { const val card = "stock_card_" const val name = "stock_name_" const val lastPrice = "stock_lastPrice_" const val priceChange = "stock_priceChange_" const val arrow = "stock_arrow_" -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockList.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockList.kt similarity index 82% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockList.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockList.kt index 3142dd2..720f9f1 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/StockList.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/StockList.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement @@ -22,40 +22,38 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import dev.garousi.stock_watcher.R -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.R +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock @Composable fun StockList( modifier: Modifier = Modifier, stocks: List, - onClick: (Stock) -> Unit = {} + onClick: (Stock) -> Unit = {}, ) { if (stocks.isNotEmpty()) { LazyColumn( modifier = modifier .fillMaxWidth() .testTag(watchlistStocks), - contentPadding = PaddingValues(16.dp) + contentPadding = PaddingValues(16.dp), ) { itemsIndexed( items = stocks, - key = { index, item -> item.itemName } + key = { index, item -> item.itemName }, ) { index, stock -> StockItem( stock = stock, index = index, - onClick = onClick + onClick = onClick, ) } } - } - else { + } else { EmptyState(modifier = modifier) } } - @Composable private fun EmptyState(modifier: Modifier = Modifier) { Column( @@ -63,12 +61,12 @@ private fun EmptyState(modifier: Modifier = Modifier) { .fillMaxSize() .testTag(watchlistStocksEmpty), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Image( modifier = Modifier.fillMaxWidth(), imageVector = Icons.Default.ShoppingCart, - contentDescription = null + contentDescription = null, ) Spacer(modifier = Modifier.height(16.dp)) @@ -78,7 +76,7 @@ private fun EmptyState(modifier: Modifier = Modifier) { modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, style = MaterialTheme.typography.body1, - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, ) Spacer(modifier = Modifier.height(8.dp)) @@ -87,7 +85,7 @@ private fun EmptyState(modifier: Modifier = Modifier) { text = stringResource(id = R.string.stocks_empty_description), modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = MaterialTheme.typography.body2 + style = MaterialTheme.typography.body2, ) } } diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreen.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreen.kt similarity index 78% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreen.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreen.kt index 198f7e7..cf6e1a3 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistScreen.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistScreen.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn @@ -36,33 +36,33 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock -import dev.garousi.stock_watcher.navigation.TrackScrollJank +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.navigation.TrackScrollJank @Composable fun WatchlistScreen( - viewModel: WatchlistViewModel = hiltViewModel() + viewModel: WatchlistViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsState() WatchlistScreen( stocks = uiState.stocks, - isLoading = uiState.isLoading + isLoading = uiState.isLoading, ) } @Composable fun WatchlistScreen( stocks: List, - isLoading: Boolean + isLoading: Boolean, ) { Column( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { WatchlistTopAppBar { Text( text = "Stock List", modifier = Modifier.align(CenterVertically), - style = MaterialTheme.typography.h6 + style = MaterialTheme.typography.h6, ) } val state = rememberLazyGridState() @@ -72,32 +72,32 @@ fun WatchlistScreen( AnimatedVisibility( visible = isLoading, enter = slideInVertically( - initialOffsetY = { fullHeight -> -fullHeight } + initialOffsetY = { fullHeight -> -fullHeight }, ) + fadeIn(), exit = slideOutVertically( - targetOffsetY = { fullHeight -> -fullHeight } - ) + fadeOut() + targetOffsetY = { fullHeight -> -fullHeight }, + ) + fadeOut(), ) { StockWatcherOverlayLoadingWheel( - modifier = Modifier.testTag(watchlistStocksLoadingWheel) + modifier = Modifier.testTag(watchlistStocksLoadingWheel), ) } } @Composable fun StockWatcherOverlayLoadingWheel( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Surface( color = MaterialTheme.colors.background, - modifier = modifier.fillMaxSize() + modifier = modifier.fillMaxSize(), ) { Box( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { CircularProgressIndicator( modifier = Modifier.align(Center), - strokeWidth = 1.dp + strokeWidth = 1.dp, ) } } @@ -110,14 +110,14 @@ private fun WatchlistTopAppBar( contentColor: Color = contentColorFor(backgroundColor), elevation: Dp = AppBarDefaults.TopAppBarElevation, contentPadding: PaddingValues = AppBarDefaults.ContentPadding, - content: @Composable RowScope.() -> Unit + content: @Composable RowScope.() -> Unit, ) { Surface( color = backgroundColor, contentColor = contentColor, elevation = elevation, shape = RectangleShape, - modifier = modifier + modifier = modifier, ) { Row( Modifier @@ -126,19 +126,18 @@ private fun WatchlistTopAppBar( .height(56.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = CenterVertically, - content = content + content = content, ) } } - @Composable private fun LoadingView() { Box( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { CircularProgressIndicator( - modifier = Modifier.align(Alignment.Center) + modifier = Modifier.align(Alignment.Center), ) } } @@ -146,11 +145,11 @@ private fun LoadingView() { @Composable private fun ErrorView() { Box( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { Text( text = "Error Happened", - modifier = Modifier.align(Alignment.Center) + modifier = Modifier.align(Alignment.Center), ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistState.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistState.kt similarity index 51% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistState.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistState.kt index c5d190a..1353e67 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistState.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistState.kt @@ -1,6 +1,6 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation -import dev.garousi.stock_watcher.feature.watchlist.domain.models.Stock +import dev.garousi.stockwatcher.feature.watchlist.domain.models.Stock data class WatchlistState( val stocks: List = arrayListOf().apply { @@ -8,5 +8,5 @@ data class WatchlistState( add(Stock(itemName = "itemName$it")) } }, - val isLoading: Boolean = false -) \ No newline at end of file + val isLoading: Boolean = false, +) diff --git a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistViewModel.kt b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistViewModel.kt similarity index 90% rename from app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistViewModel.kt rename to app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistViewModel.kt index 995718a..7ce8e1c 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/feature/watchlist/presentation/WatchlistViewModel.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/feature/watchlist/presentation/WatchlistViewModel.kt @@ -1,12 +1,11 @@ -package dev.garousi.stock_watcher.feature.watchlist.presentation +package dev.garousi.stockwatcher.feature.watchlist.presentation import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import dev.garousi.stock_watcher.feature.watchlist.data.LightStreamerService -import dev.garousi.stock_watcher.feature.watchlist.data.StockListDto -import javax.inject.Inject +import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerService +import dev.garousi.stockwatcher.feature.watchlist.data.StockListDto import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.asStateFlow @@ -14,10 +13,11 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update +import javax.inject.Inject @HiltViewModel class WatchlistViewModel @Inject constructor( - private val stockListLightStreamerService: LightStreamerService + private val stockListLightStreamerService: LightStreamerService, ) : ViewModel() { private val _uiState = MutableStateFlow(WatchlistState()) @@ -55,7 +55,7 @@ class WatchlistViewModel @Inject constructor( ref = stock.ref ?: it.stocks[updatedItemIndex].ref, open = stock.open ?: it.stocks[updatedItemIndex].open, ) - } + }, ) } } @@ -63,7 +63,7 @@ class WatchlistViewModel @Inject constructor( .stateIn( scope = viewModelScope, initialValue = StockListDto(), - started = SharingStarted.Eagerly + started = SharingStarted.Eagerly, ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/navigation/JankStatsExtensions.kt b/app/src/main/java/dev/garousi/stockwatcher/navigation/JankStatsExtensions.kt similarity index 97% rename from app/src/main/java/dev/garousi/stock_watcher/navigation/JankStatsExtensions.kt rename to app/src/main/java/dev/garousi/stockwatcher/navigation/JankStatsExtensions.kt index f486276..4079ce1 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/navigation/JankStatsExtensions.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/navigation/JankStatsExtensions.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package dev.garousi.stock_watcher.navigation +package dev.garousi.stockwatcher.navigation import androidx.compose.foundation.gestures.ScrollableState import androidx.compose.runtime.Composable @@ -51,7 +51,7 @@ fun rememberMetricsStateHolder(): Holder { @Composable fun TrackJank( vararg keys: Any?, - reportMetric: suspend CoroutineScope.(state: Holder) -> Unit + reportMetric: suspend CoroutineScope.(state: Holder) -> Unit, ) { val metrics = rememberMetricsStateHolder() LaunchedEffect(metrics, *keys) { @@ -66,7 +66,7 @@ fun TrackJank( @Composable fun TrackDisposableJank( vararg keys: Any?, - reportMetric: DisposableEffectScope.(state: Holder) -> DisposableEffectResult + reportMetric: DisposableEffectScope.(state: Holder) -> DisposableEffectResult, ) { val metrics = rememberMetricsStateHolder() DisposableEffect(metrics, *keys) { diff --git a/app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherIcons.kt b/app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherIcons.kt new file mode 100644 index 0000000..041e3fd --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherIcons.kt @@ -0,0 +1,12 @@ +package dev.garousi.stockwatcher.navigation + +import androidx.annotation.DrawableRes +import androidx.compose.ui.graphics.vector.ImageVector + +/** + * A sealed class to make dealing with [ImageVector] and [DrawableRes] icons easier. + */ +sealed class StockWatcherIcons { + data class ImageVectorStockWatcherIcons(val imageVector: ImageVector) : StockWatcherIcons() + data class DrawableResourceStockWatcherIcons(@DrawableRes val id: Int) : StockWatcherIcons() +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherNavHost.kt b/app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherNavHost.kt similarity index 82% rename from app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherNavHost.kt rename to app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherNavHost.kt index 2ebca00..c3e60a2 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/navigation/StockWatcherNavHost.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/navigation/StockWatcherNavHost.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.navigation +package dev.garousi.stockwatcher.navigation import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -10,7 +10,7 @@ fun StockWatcherNavHost( navController: NavHostController, onBackClick: () -> Unit, modifier: Modifier = Modifier, - startDestination: String = watchlistGraphRoutePattern + startDestination: String = watchlistGraphRoutePattern, ) { NavHost( navController = navController, @@ -18,7 +18,6 @@ fun StockWatcherNavHost( modifier = modifier, ) { watchlistGraph { - } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stockwatcher/navigation/TopLevelDestination.kt b/app/src/main/java/dev/garousi/stockwatcher/navigation/TopLevelDestination.kt new file mode 100644 index 0000000..fe713de --- /dev/null +++ b/app/src/main/java/dev/garousi/stockwatcher/navigation/TopLevelDestination.kt @@ -0,0 +1,20 @@ +package dev.garousi.stockwatcher.navigation + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.outlined.Home +import dev.garousi.stockwatcher.R + +enum class TopLevelDestination( + val selectedStockWatcherIcons: StockWatcherIcons, + val unselectedStockWatcherIcons: StockWatcherIcons, + val iconTextId: Int, + val titleTextId: Int, +) { + WATCHLIST( + selectedStockWatcherIcons = StockWatcherIcons.ImageVectorStockWatcherIcons(Icons.Default.Home), + unselectedStockWatcherIcons = StockWatcherIcons.ImageVectorStockWatcherIcons(Icons.Outlined.Home), + iconTextId = R.string.home, + titleTextId = R.string.home, + ), +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/navigation/WatchlistNavigation.kt b/app/src/main/java/dev/garousi/stockwatcher/navigation/WatchlistNavigation.kt similarity index 75% rename from app/src/main/java/dev/garousi/stock_watcher/navigation/WatchlistNavigation.kt rename to app/src/main/java/dev/garousi/stockwatcher/navigation/WatchlistNavigation.kt index 44d5bfd..989846a 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/navigation/WatchlistNavigation.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/navigation/WatchlistNavigation.kt @@ -1,12 +1,11 @@ -package dev.garousi.stock_watcher.navigation +package dev.garousi.stockwatcher.navigation import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.navigation -import dev.garousi.stock_watcher.feature.watchlist.presentation.WatchlistScreen - +import dev.garousi.stockwatcher.feature.watchlist.presentation.WatchlistScreen const val watchlistGraphRoutePattern = "watchlist_graph" const val watchlistListRoute = "stock_list_route" @@ -16,11 +15,11 @@ fun NavController.navigateToWatchlistGraph(navOptions: NavOptions? = null) { } fun NavGraphBuilder.watchlistGraph( - nestedGraphs: NavGraphBuilder.() -> Unit + nestedGraphs: NavGraphBuilder.() -> Unit, ) { navigation( route = watchlistGraphRoutePattern, - startDestination = watchlistListRoute + startDestination = watchlistListRoute, ) { composable(route = watchlistListRoute) { WatchlistScreen() diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/ComposeTestExtensions.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/ComposeTestExtensions.kt similarity index 85% rename from app/src/main/java/dev/garousi/stock_watcher/ui/ComposeTestExtensions.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/ComposeTestExtensions.kt index 0f4abfc..94218b0 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/ComposeTestExtensions.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/ComposeTestExtensions.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui +package dev.garousi.stockwatcher.ui import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector @@ -8,10 +8,8 @@ import androidx.compose.ui.semantics.SemanticsPropertyReceiver val DrawableId = SemanticsPropertyKey("DrawableResId") var SemanticsPropertyReceiver.drawableId by DrawableId - val ImageVectorId = SemanticsPropertyKey("ImageVectorId") var SemanticsPropertyReceiver.imageVectorId by ImageVectorId - val ColorRes = SemanticsPropertyKey("ColorRes") -var SemanticsPropertyReceiver.colorRes by ColorRes \ No newline at end of file +var SemanticsPropertyReceiver.colorRes by ColorRes diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherApp.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherApp.kt similarity index 87% rename from app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherApp.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherApp.kt index 7716cbe..a233ac3 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherApp.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherApp.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui +package dev.garousi.stockwatcher.ui import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -17,13 +17,13 @@ import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId -import dev.garousi.stock_watcher.navigation.StockWatcherNavHost +import dev.garousi.stockwatcher.navigation.StockWatcherNavHost @OptIn(ExperimentalLayoutApi::class) @ExperimentalComposeUiApi @Composable fun StockWatcherApp( - appState: StockWatcherAppState = rememberStockWatcherAppState() + appState: StockWatcherAppState = rememberStockWatcherAppState(), ) { Scaffold( modifier = Modifier @@ -33,9 +33,8 @@ fun StockWatcherApp( }, bottomBar = { if (appState.shouldShowBottomBar) { - } - } + }, ) { padding -> Row( Modifier @@ -44,21 +43,20 @@ fun StockWatcherApp( .consumedWindowInsets(padding) .windowInsetsPadding( WindowInsets.safeDrawing.only( - WindowInsetsSides.Horizontal - ) - ) + WindowInsetsSides.Horizontal, + ), + ), ) { Column(Modifier.fillMaxSize()) { // Show the top app bar on top level destinations. val destination = appState.currentTopLevelDestination if (destination != null) { - } StockWatcherNavHost( navController = appState.navController, - onBackClick = appState::onBackClick + onBackClick = appState::onBackClick, ) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherAppState.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherAppState.kt similarity index 88% rename from app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherAppState.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherAppState.kt index 24abca1..6134c91 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/StockWatcherAppState.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/StockWatcherAppState.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui +package dev.garousi.stockwatcher.ui import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable @@ -12,17 +12,17 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions import androidx.tracing.trace -import dev.garousi.stock_watcher.navigation.TopLevelDestination -import dev.garousi.stock_watcher.navigation.TopLevelDestination.WATCHLIST -import dev.garousi.stock_watcher.navigation.TrackDisposableJank -import dev.garousi.stock_watcher.navigation.navigateToWatchlistGraph -import dev.garousi.stock_watcher.navigation.watchlistListRoute +import dev.garousi.stockwatcher.navigation.TopLevelDestination +import dev.garousi.stockwatcher.navigation.TopLevelDestination.WATCHLIST +import dev.garousi.stockwatcher.navigation.TrackDisposableJank +import dev.garousi.stockwatcher.navigation.navigateToWatchlistGraph +import dev.garousi.stockwatcher.navigation.watchlistListRoute import kotlinx.coroutines.CoroutineScope @Composable fun rememberStockWatcherAppState( navController: NavHostController = rememberNavController(), - coroutineScope: CoroutineScope = rememberCoroutineScope() + coroutineScope: CoroutineScope = rememberCoroutineScope(), ): StockWatcherAppState { NavigationTrackingSideEffect(navController) return remember(navController, coroutineScope) { @@ -33,14 +33,13 @@ fun rememberStockWatcherAppState( @Stable class StockWatcherAppState( val navController: NavHostController, - val coroutineScope: CoroutineScope + val coroutineScope: CoroutineScope, ) { val shouldShowBottomBar: Boolean = false val currentDestination: NavDestination? @Composable get() = navController .currentBackStackEntryAsState().value?.destination - val currentTopLevelDestination: TopLevelDestination? @Composable get() = when (currentDestination?.route) { watchlistListRoute -> WATCHLIST @@ -56,7 +55,6 @@ class StockWatcherAppState( */ val topLevelDestinations: List = TopLevelDestination.values().asList() - /** * UI logic for navigating to a top level destination in the app. Top level destinations have * only one copy of the destination of the back stack, and save and restore state whenever you @@ -107,4 +105,4 @@ private fun NavigationTrackingSideEffect(navController: NavHostController) { navController.removeOnDestinationChangedListener(listener) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Color.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Color.kt similarity index 66% rename from app/src/main/java/dev/garousi/stock_watcher/ui/theme/Color.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/theme/Color.kt index 6e35642..d2e813a 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Color.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Color.kt @@ -1,8 +1,8 @@ -package dev.garousi.stock_watcher.ui.theme +package dev.garousi.stockwatcher.ui.theme import androidx.compose.ui.graphics.Color val Purple200 = Color(0xFFBB86FC) val Purple500 = Color(0xFF6200EE) val Purple700 = Color(0xFF3700B3) -val Teal200 = Color(0xFF03DAC5) \ No newline at end of file +val Teal200 = Color(0xFF03DAC5) diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Shape.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Shape.kt similarity index 74% rename from app/src/main/java/dev/garousi/stock_watcher/ui/theme/Shape.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/theme/Shape.kt index 8c12cfb..f38eb65 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Shape.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Shape.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui.theme +package dev.garousi.stockwatcher.ui.theme import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes @@ -7,5 +7,5 @@ import androidx.compose.ui.unit.dp val Shapes = Shapes( small = RoundedCornerShape(4.dp), medium = RoundedCornerShape(4.dp), - large = RoundedCornerShape(0.dp) -) \ No newline at end of file + large = RoundedCornerShape(0.dp), +) diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Theme.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Theme.kt similarity index 90% rename from app/src/main/java/dev/garousi/stock_watcher/ui/theme/Theme.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/theme/Theme.kt index d561241..1482006 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Theme.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Theme.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui.theme +package dev.garousi.stockwatcher.ui.theme import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.MaterialTheme @@ -13,13 +13,13 @@ private val DarkColorPalette = darkColors( secondary = Teal200, background = Color(0xFF222222), surface = Color(0xFF333333), - onSurface = Color.White + onSurface = Color.White, ) private val LightColorPalette = lightColors( primary = Purple500, primaryVariant = Purple700, - secondary = Teal200 + secondary = Teal200, /* Other default colors to override background = Color.White, @@ -43,6 +43,6 @@ fun StockWatcherTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Comp colors = colors, typography = Typography, shapes = Shapes, - content = content + content = content, ) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Type.kt b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Type.kt similarity index 90% rename from app/src/main/java/dev/garousi/stock_watcher/ui/theme/Type.kt rename to app/src/main/java/dev/garousi/stockwatcher/ui/theme/Type.kt index 8c9bba0..2a50197 100644 --- a/app/src/main/java/dev/garousi/stock_watcher/ui/theme/Type.kt +++ b/app/src/main/java/dev/garousi/stockwatcher/ui/theme/Type.kt @@ -1,4 +1,4 @@ -package dev.garousi.stock_watcher.ui.theme +package dev.garousi.stockwatcher.ui.theme import androidx.compose.material.Typography import androidx.compose.ui.text.TextStyle @@ -11,8 +11,8 @@ val Typography = Typography( body1 = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, - fontSize = 16.sp - ) + fontSize = 16.sp, + ), /* Other default text styles to override button = TextStyle( fontFamily = FontFamily.Default, @@ -25,4 +25,4 @@ val Typography = Typography( fontSize = 12.sp ) */ -) \ No newline at end of file +) diff --git a/app/src/test/java/dev/garousi/stock_watcher/ExampleUnitTest.kt b/app/src/test/java/dev/garousi/stockwatcher/ExampleUnitTest.kt similarity index 79% rename from app/src/test/java/dev/garousi/stock_watcher/ExampleUnitTest.kt rename to app/src/test/java/dev/garousi/stockwatcher/ExampleUnitTest.kt index acb2511..b763530 100644 --- a/app/src/test/java/dev/garousi/stock_watcher/ExampleUnitTest.kt +++ b/app/src/test/java/dev/garousi/stockwatcher/ExampleUnitTest.kt @@ -1,9 +1,8 @@ -package dev.garousi.stock_watcher +package dev.garousi.stockwatcher +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +13,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/build.gradle b/build.gradle index 944971f..676960a 100644 --- a/build.gradle +++ b/build.gradle @@ -9,8 +9,10 @@ plugins { id 'org.jetbrains.kotlin.android' version '1.7.20' apply false id 'com.google.dagger.hilt.android' version '2.44.2' apply false id "com.github.ben-manes.versions" version "0.44.0" + id "com.diffplug.spotless" version "6.12.1" } subprojects { apply from: "../buildscripts/versionsplugin.gradle" + apply from: "../buildscripts/spotless.gradle" } \ No newline at end of file diff --git a/buildscripts/spotless.gradle b/buildscripts/spotless.gradle new file mode 100644 index 0000000..695e251 --- /dev/null +++ b/buildscripts/spotless.gradle @@ -0,0 +1,14 @@ +apply plugin: "com.diffplug.spotless" + +afterEvaluate { + spotlessApply { + spotless { + kotlin { + target("**/*.kt") + targetExclude("**/build/**/*.kt") + // version, setUseExperimental, userData and editorConfigOverride are all optional + ktlint("0.48.1") + } + } + } +}