Skip to content

Commit

Permalink
Clean up stocks provider usage
Browse files Browse the repository at this point in the history
  • Loading branch information
premnirmal committed Feb 1, 2022
1 parent 886bf0b commit 5309eda
Show file tree
Hide file tree
Showing 17 changed files with 136 additions and 116 deletions.
2 changes: 0 additions & 2 deletions app/src/main/kotlin/com/github/premnirmal/ticker/StocksApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ open class StocksApp : MultiDexApplication() {
class InjectionHolder {
@Inject lateinit var analytics: Analytics
@Inject lateinit var appPreferences: AppPreferences
@Inject lateinit var newsProvider: NewsProvider
@Inject lateinit var commitsProvider: CommitsProvider
@Inject lateinit var notificationsHandler: NotificationsHandler
@Inject lateinit var widgetDataProvider: WidgetDataProvider
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import com.github.premnirmal.ticker.portfolio.AddNotesActivity
import com.github.premnirmal.ticker.portfolio.AddPositionActivity
import com.github.premnirmal.ticker.portfolio.AlertsViewModel
import com.github.premnirmal.ticker.portfolio.NotesViewModel
import com.github.premnirmal.ticker.portfolio.PortfolioFragment
import com.github.premnirmal.ticker.portfolio.PortfolioViewModel
import com.github.premnirmal.ticker.portfolio.StocksAdapter
import com.github.premnirmal.ticker.portfolio.search.SearchActivity
import com.github.premnirmal.ticker.portfolio.search.SearchFragment
Expand All @@ -53,7 +53,7 @@ import com.google.gson.Gson
* Created by premnirmal on 3/3/16.
*/
@javax.inject.Singleton
@dagger.Component(modules = arrayOf(AppModule::class))
@dagger.Component(modules = [AppModule::class])
interface AppComponent {

// Activities
Expand Down Expand Up @@ -128,8 +128,6 @@ interface AppComponent {

fun inject(holder: BaseFragment.InjectionHolder)

fun inject(holder: PortfolioFragment.InjectionHolder)

fun inject(homeFragment: HomeFragment)

fun inject(fragment: SearchFragment)
Expand Down Expand Up @@ -163,4 +161,6 @@ interface AppComponent {
fun inject(alertsViewModel: AlertsViewModel)

fun inject(searchViewModel: SearchViewModel)

fun inject(viewModel: PortfolioViewModel)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import android.os.Handler
import android.os.Looper
import androidx.room.Room
import com.github.premnirmal.ticker.AppPreferences
import com.github.premnirmal.ticker.StocksApp
Expand All @@ -20,6 +18,8 @@ import com.github.premnirmal.ticker.repo.migrations.MIGRATION_1_2
import com.github.premnirmal.ticker.widget.WidgetDataProvider
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import javax.inject.Singleton

/**
Expand All @@ -30,10 +30,11 @@ class AppModule(private val app: StocksApp) {

@Provides fun provideApplicationContext(): Context = app

@Provides @Singleton fun provideClock(): AppClock = AppClockImpl
@Singleton @Provides fun provideApplicationScope(): CoroutineScope {
return CoroutineScope(Dispatchers.Unconfined)
}

@Provides @Singleton fun provideMainThreadHandler(): Handler =
Handler(Looper.getMainLooper())
@Provides @Singleton fun provideClock(): AppClock = AppClockImpl

@Provides @Singleton fun provideDefaultSharedPreferences(
context: Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class HomeFragment : BaseFragment(), ChildFragment, PortfolioFragment.Parent {
private var isTitleShowing = true

override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
val show = verticalOffset > -20
val show = verticalOffset > -tabs.height / 2
if (show && !isTitleShowing) {
subtitle.animate().alpha(1f).start()
tabs.animate().alpha(1f).start()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ interface IStocksProvider {

fun fetchStock(ticker: String): Flow<FetchResult<Quote>>

fun removeStock(ticker: String): Collection<String>
suspend fun removeStock(ticker: String): Collection<String>

fun removeStocks(symbols: Collection<String>)
suspend fun removeStocks(symbols: Collection<String>)

fun hasTicker(ticker: String): Boolean

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.coroutines.CoroutineContext

/**
* Created by premnirmal on 2/28/16.
*/
@Singleton
class StocksProvider : IStocksProvider, CoroutineScope {
class StocksProvider : IStocksProvider {

companion object {

Expand All @@ -49,9 +48,8 @@ class StocksProvider : IStocksProvider, CoroutineScope {
@Inject lateinit var alarmScheduler: AlarmScheduler
@Inject lateinit var clock: AppClock
@Inject lateinit var storage: StocksStorage
@Inject lateinit var coroutineScope: CoroutineScope

override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
private val exponentialBackoff: ExponentialBackoff

private val tickerSet: MutableSet<String> = HashSet()
Expand All @@ -75,12 +73,12 @@ class StocksProvider : IStocksProvider, CoroutineScope {
_lastFetched.tryEmit(lastFetched)
val nextFetch = preferences.getLong(NEXT_FETCH, 0L)
_nextFetch.tryEmit(nextFetch)
launch {
coroutineScope.launch {
alarmScheduler.enqueuePeriodicRefresh(context)
}
runBlocking { fetchLocal() }
if (lastFetched == 0L) {
launch {
coroutineScope.launch {
fetch().collect()
}
} else {
Expand Down Expand Up @@ -144,9 +142,7 @@ class StocksProvider : IStocksProvider, CoroutineScope {
/////////////////////

override fun hasTicker(ticker: String): Boolean {
synchronized(tickerSet) {
return tickerSet.contains(ticker)
}
return tickerSet.contains(ticker)
}

override fun fetch(): Flow<FetchResult<List<Quote>>> = flow {
Expand All @@ -169,6 +165,12 @@ class StocksProvider : IStocksProvider, CoroutineScope {
tickerSet.addAll(fetchedStocks.map { it.symbol })
}
_tickers.emit(tickerSet.toList())
// clean up existing tickers
ArrayList(tickerSet).forEach { ticker ->
if (!widgetDataProvider.containsTicker(ticker)) {
removeStock(ticker)
}
}
storage.saveQuotes(fetchedStocks)
fetchLocal()
_lastFetched.emit(api.lastFetched)
Expand All @@ -192,7 +194,7 @@ class StocksProvider : IStocksProvider, CoroutineScope {

override fun schedule() {
scheduleUpdate()
launch {
coroutineScope.launch {
alarmScheduler.enqueuePeriodicRefresh(context, force = true)
}
}
Expand All @@ -205,17 +207,17 @@ class StocksProvider : IStocksProvider, CoroutineScope {
quote.symbol = ticker
quoteMap[ticker] = quote
saveTickers()
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
launch {
fetchStockInternal(ticker, false).collect { result ->
if (result.wasSuccessful) {
val data = result.data
quoteMap[ticker] = data
storage.saveQuote(result.data)
_portfolio.tryEmit(quoteMap.values.toList())
}
}
}
}
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
coroutineScope.launch {
fetchStockInternal(ticker, false).collect { result ->
if (result.wasSuccessful) {
val data = result.data
quoteMap[ticker] = data
storage.saveQuote(result.data)
_portfolio.tryEmit(quoteMap.values.toList())
}
}
}
Expand All @@ -240,16 +242,16 @@ class StocksProvider : IStocksProvider, CoroutineScope {
position = getPosition(ticker) ?: Position(ticker)
if (!tickerSet.contains(ticker)) {
tickerSet.add(ticker)
_tickers.tryEmit(tickerSet.toList())
saveTickers()
}
}
_tickers.emit(tickerSet.toList())
saveTickers()
val holding = Holding(ticker, shares, price)
position.add(holding)
quote?.position = position
val id = storage.addHolding(holding)
holding.id = id
_portfolio.tryEmit(quoteMap.values.toList())
_portfolio.emit(quoteMap.values.toList())
return holding
}

Expand All @@ -273,43 +275,39 @@ class StocksProvider : IStocksProvider, CoroutineScope {
filterNot.forEach { this.tickerSet.add(it) }
saveTickers()
if (filterNot.isNotEmpty()) {
launch {
coroutineScope.launch {
fetch().collect()
}
}
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
}
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
return this.tickerSet
}

override fun removeStock(ticker: String): Collection<String> {
override suspend fun removeStock(ticker: String): Collection<String> {
synchronized(quoteMap) {
tickerSet.remove(ticker)
saveTickers()
quoteMap.remove(ticker)
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
}
launch {
storage.removeQuoteBySymbol(ticker)
}
storage.removeQuoteBySymbol(ticker)
_tickers.emit(tickerSet.toList())
_portfolio.emit(quoteMap.values.toList())
return tickerSet
}

override fun removeStocks(symbols: Collection<String>) {
override suspend fun removeStocks(symbols: Collection<String>) {
synchronized(quoteMap) {
symbols.forEach {
tickerSet.remove(it)
quoteMap.remove(it)
}
_tickers.tryEmit(tickerSet.toList())
_portfolio.tryEmit(quoteMap.values.toList())
}
storage.removeQuotesBySymbol(symbols.toList())
_tickers.emit(tickerSet.toList())
_portfolio.emit(quoteMap.values.toList())
saveTickers()
launch {
storage.removeQuotesBySymbol(symbols.toList())
}
}

override fun fetchStock(ticker: String): Flow<FetchResult<Quote>> {
Expand All @@ -334,7 +332,7 @@ class StocksProvider : IStocksProvider, CoroutineScope {
}
saveTickers()
widgetDataProvider.updateWidgets(tickerSet.toList())
launch {
coroutineScope.launch {
storage.saveQuotes(portfolio)
fetchLocal()
fetch().collect()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class CommitsProvider @Inject constructor(private val githubApi: GithubApi) {

private val coroutineScope = CoroutineScope(Dispatchers.IO)
class CommitsProvider @Inject constructor(
private val githubApi: GithubApi,
private val coroutineScope: CoroutineScope
) {
private var cachedChanges: List<RepoCommit>? = null

fun initCache() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import javax.inject.Singleton
@Singleton
class NewsProvider {

private val coroutineScope = CoroutineScope(Dispatchers.IO)
@Inject lateinit var coroutineScope: CoroutineScope
@Inject internal lateinit var newsApi: NewsApi

private var cachedBusinessArticles: List<NewsArticle> = emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import com.github.premnirmal.ticker.network.data.NewsArticle
import com.github.premnirmal.ticker.network.data.Quote
import com.github.premnirmal.ticker.widget.WidgetData
import com.github.premnirmal.ticker.widget.WidgetDataProvider
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand Down Expand Up @@ -77,7 +76,9 @@ class QuoteDetailViewModel : ViewModel() {
fun removeStock(ticker: String) {
val widgetData = widgetDataProvider.widgetDataWithStock(ticker)
widgetData.forEach { it.removeStock(ticker) }
stocksProvider.removeStock(ticker)
viewModelScope.launch {
stocksProvider.removeStock(ticker)
}
}

fun fetchChartData(symbol: String, range: Range) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import com.github.premnirmal.ticker.repo.StocksStorage
import com.github.premnirmal.tickerwidget.BuildConfig
import com.github.premnirmal.tickerwidget.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.threeten.bp.Duration
import org.threeten.bp.Instant
Expand All @@ -46,7 +44,8 @@ class NotificationsHandler @Inject constructor(
private val stocksStorage: StocksStorage,
private val alarmScheduler: AlarmScheduler,
private val appPreferences: AppPreferences,
private val clock: AppClock
private val clock: AppClock,
private val coroutineScope: CoroutineScope
) {

companion object {
Expand All @@ -56,8 +55,6 @@ class NotificationsHandler @Inject constructor(
private const val PREFS_NOTIFICATIONS = "${BuildConfig.APPLICATION_ID}.notifications.PREFS"
}

private val coroutineScope = CoroutineScope(Dispatchers.Default)

private val notificationFactory: NotificationFactory by lazy {
NotificationFactory(context, appPreferences)
}
Expand Down
Loading

0 comments on commit 5309eda

Please sign in to comment.