Skip to content

Commit

Permalink
Add more stock details including revenue, profits, earnings, descript…
Browse files Browse the repository at this point in the history
…ion, etc
  • Loading branch information
premnirmal committed Oct 25, 2022
1 parent 700f998 commit 15cb28e
Show file tree
Hide file tree
Showing 17 changed files with 326 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.github.premnirmal.ticker.home

import android.content.Context
import com.github.premnirmal.ticker.AppPreferences
import dagger.hilt.android.qualifiers.ApplicationContext

class AppReviewManager(@ApplicationContext context: Context, appPreferences: AppPreferences) : IAppReviewManager
class AppReviewManager(@ApplicationContext context: Context) : IAppReviewManager
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,7 @@ class AppPreferences @Inject constructor(
.apply()
}

fun userDidRate() {
sharedPreferences.edit()
.putBoolean(DID_RATE, true)
.apply()
}

fun shouldPromptRate(): Boolean = // if the user hasn't rated, ask them again but not too often.
!sharedPreferences.getBoolean(DID_RATE, false) && (Random.nextInt() % 5 == 0)
fun shouldPromptRate(): Boolean = Random.nextBoolean()

fun backOffAttemptCount(): Int = sharedPreferences.getInt(BACKOFF_ATTEMPTS, 1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class AppModule {

@Provides @Singleton fun provideQuoteDao(db: QuotesDB): QuoteDao = db.quoteDao()

@Provides @Singleton fun provideAppReviewManager(@ApplicationContext context: Context, appPreferences: AppPreferences): IAppReviewManager {
return AppReviewManager(context, appPreferences)
@Provides @Singleton fun providesAppReviewManager(@ApplicationContext context: Context): IAppReviewManager {
return AppReviewManager(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ class NetworkModule {
return yahooFinance
}

@Provides @Singleton internal fun provideYahooQuoteDetailsApi(
@ApplicationContext context: Context,
okHttpClient: OkHttpClient,
converterFactory: GsonConverterFactory
): YahooQuoteDetails {
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(context.getString(R.string.yahoo_endpoint_quote_details))
.addConverterFactory(converterFactory)
.build()
val yahooFinance = retrofit.create(YahooQuoteDetails::class.java)
return yahooFinance
}

@Provides @Singleton internal fun provideApeWisdom(
@ApplicationContext context: Context,
okHttpClient: OkHttpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.github.premnirmal.ticker.components.AppClock
import com.github.premnirmal.ticker.model.FetchException
import com.github.premnirmal.ticker.model.FetchResult
import com.github.premnirmal.ticker.network.data.Quote
import com.github.premnirmal.ticker.network.data.QuoteSummary
import com.github.premnirmal.ticker.network.data.SuggestionsNet.SuggestionNet
import com.github.premnirmal.ticker.network.data.YahooQuoteNet
import com.google.gson.Gson
Expand All @@ -20,6 +21,7 @@ import javax.inject.Singleton
class StocksApi @Inject constructor(
private val gson: Gson,
private val yahooFinance: YahooFinance,
private val yahooQuoteDetails: YahooQuoteDetails,
private val suggestionApi: SuggestionApi,
private val clock: AppClock
) {
Expand Down Expand Up @@ -61,6 +63,26 @@ class StocksApi @Inject constructor(
}
}

suspend fun getQuoteDetails(ticker: String): FetchResult<QuoteSummary> =
withContext(Dispatchers.IO) {
try {
val quoteSummaryResponse = yahooQuoteDetails.getAssetDetails(ticker)
val data = quoteSummaryResponse.quoteSummary.result.firstOrNull()
return@withContext data?.let {
FetchResult.success(it)
} ?: FetchResult.failure(
FetchException(
"Failed to fetch quote details for $ticker with error ${quoteSummaryResponse.quoteSummary.error}"
)
)
} catch (e: Exception) {
Timber.w(e)
return@withContext FetchResult.failure(
FetchException("Failed to fetch quote details for $ticker", e)
)
}
}

private suspend fun getStocksYahoo(tickerList: List<String>) = withContext(Dispatchers.IO) {
val query = tickerList.joinToString(",")
val quoteNets = yahooFinance.getStocks(query).quoteResponse.result ?: emptyList()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.github.premnirmal.ticker.network

import com.github.premnirmal.ticker.network.data.AssetDetailsResponse
import com.github.premnirmal.ticker.network.data.YahooResponse
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface YahooFinance {
Expand All @@ -17,4 +19,9 @@ interface YahooFinance {
"quote?format=json"
)
suspend fun getStocks(@Query(value = "symbols") query: String): YahooResponse
}

interface YahooQuoteDetails {
@GET("quoteSummary/{symbol}?modules=financialData,assetProfile")
suspend fun getAssetDetails(@Path(value = "symbol") symbol: String): AssetDetailsResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ data class YahooResponse(
@SerializedName("quoteResponse") val quoteResponse: QuoteResponse
)


data class QuoteResponse(
@SerializedName("result") val result: List<YahooQuoteNet>?
)
Expand Down Expand Up @@ -86,4 +85,54 @@ data class YahooQuoteNet(
val annualDividendRate: Float,
@SerializedName("trailingAnnualDividendYield")
val annualDividendYield: Float
)

data class AssetDetailsResponse(
@SerializedName("quoteSummary")
val quoteSummary: QuoteSummaryResult
)

data class QuoteSummaryResult(
@SerializedName("result")
val result: List<QuoteSummary>,
@SerializedName("error")
val error: String?
)

data class QuoteSummary(
@SerializedName("assetProfile")
val assetProfile: AssetProfile,
@SerializedName("financialData")
val financialData: FinancialData
)

data class AssetProfile(
@SerializedName("longBusinessSummary")
val longBusinessSummary: String?,
@SerializedName("website")
val website: String?
)

data class FinancialData(
@SerializedName("revenueGrowth")
val revenueGrowth: GrowthItem?,
@SerializedName("grossMargins")
val grossMargins: GrowthItem?,
@SerializedName("earningsGrowth")
val earningsGrowth: GrowthItem?,
@SerializedName("ebitdaMargins")
val ebitdaMargins: GrowthItem?,
@SerializedName("operatingMargins")
val operatingMargins: GrowthItem?,
@SerializedName("profitMargins")
val profitMargins: GrowthItem?,
@SerializedName("financialCurrency")
val financialCurrency: String?
)

data class GrowthItem(
@SerializedName("raw")
val raw: Float,
@SerializedName("fmt")
val fmt: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Paint
import android.os.Bundle
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
Expand All @@ -12,6 +13,7 @@ import androidx.appcompat.app.AlertDialog.Builder
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.asLiveData
import androidx.recyclerview.widget.LinearLayoutManager
Expand All @@ -29,6 +31,7 @@ import com.github.premnirmal.ticker.isNetworkOnline
import com.github.premnirmal.ticker.model.HistoryProvider.Range
import com.github.premnirmal.ticker.network.data.NewsArticle
import com.github.premnirmal.ticker.network.data.Quote
import com.github.premnirmal.ticker.network.data.QuoteSummary
import com.github.premnirmal.ticker.news.NewsFeedItem.ArticleNewsFeed
import com.github.premnirmal.ticker.portfolio.AddAlertsActivity
import com.github.premnirmal.ticker.portfolio.AddNotesActivity
Expand Down Expand Up @@ -65,6 +68,7 @@ class QuoteDetailActivity : BaseGraphActivity<ActivityQuoteDetailBinding>(), Tre
private lateinit var quoteDetailsAdapter: QuoteDetailsAdapter
private lateinit var ticker: String
private lateinit var quote: Quote
private var quoteSummary: QuoteSummary? = null
private val viewModel: QuoteDetailViewModel by viewModels()
override var range: Range = Range.ONE_MONTH

Expand Down Expand Up @@ -111,7 +115,8 @@ class QuoteDetailActivity : BaseGraphActivity<ActivityQuoteDetailBinding>(), Tre
updateToolbar()
viewModel.quote.observe(this) { result ->
if (result.wasSuccessful) {
quote = result.data
quote = result.data.quote
quoteSummary = result.data.quoteSummary
fetchNewsAndChartData()
setupQuoteUi()
viewModel.data.observe(this) { data ->
Expand Down Expand Up @@ -201,6 +206,21 @@ class QuoteDetailActivity : BaseGraphActivity<ActivityQuoteDetailBinding>(), Tre
binding.alertsContainer.setOnClickListener {
alertsOnClickListener()
}
quoteSummary?.let {
binding.description.isVisible = true
binding.description.text = it.assetProfile.longBusinessSummary ?: ""
it.assetProfile.website?.let { website ->
binding.website.isVisible = true
binding.website.text = website
binding.website.paintFlags = binding.website.paintFlags or Paint.UNDERLINE_TEXT_FLAG
binding.website.setOnClickListener {
CustomTabs.openTab(this, website)
}
}
} ?: run {
binding.description.isVisible = false
binding.website.isVisible = false
}
}

private fun updateToolbar() {
Expand Down
Loading

0 comments on commit 15cb28e

Please sign in to comment.