From 15cb28ee295190f908252eba752d5490f6b13979 Mon Sep 17 00:00:00 2001 From: Prem Nirmal Date: Tue, 25 Oct 2022 13:54:52 +0100 Subject: [PATCH] Add more stock details including revenue, profits, earnings, description, etc --- .../ticker/home/AppReviewManager.kt | 3 +- .../premnirmal/ticker/AppPreferences.kt | 9 +- .../premnirmal/ticker/components/AppModule.kt | 4 +- .../ticker/network/NetworkModule.kt | 14 ++ .../premnirmal/ticker/network/StocksApi.kt | 22 ++ .../premnirmal/ticker/network/YahooFinance.kt | 7 + .../ticker/network/data/YahooQuoteResponse.kt | 51 +++- .../ticker/news/QuoteDetailActivity.kt | 22 +- .../ticker/news/QuoteDetailViewModel.kt | 221 +++++++++++------- .../res/layout-land/activity_quote_detail.xml | 20 ++ .../activity_quote_detail.xml | 20 ++ .../main/res/layout/activity_quote_detail.xml | 20 ++ app/src/main/res/values/strings.xml | 5 + .../ticker/home/AppReviewManager.kt | 4 +- .../ticker/home/AppReviewManager.kt | 3 +- .../ticker/network/StocksApiTest.kt | 4 +- app/version.properties | 4 +- 17 files changed, 326 insertions(+), 107 deletions(-) diff --git a/app/src/dev/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt b/app/src/dev/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt index 171d3a3f..8bf5983e 100644 --- a/app/src/dev/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt +++ b/app/src/dev/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt @@ -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 \ No newline at end of file +class AppReviewManager(@ApplicationContext context: Context) : IAppReviewManager \ No newline at end of file diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/AppPreferences.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/AppPreferences.kt index cedb4a47..d00b5291 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/AppPreferences.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/AppPreferences.kt @@ -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) diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/components/AppModule.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/components/AppModule.kt index 5378d6d0..cd76cd5b 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/components/AppModule.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/components/AppModule.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/network/NetworkModule.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/network/NetworkModule.kt index 9cdfcb37..99568ade 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/network/NetworkModule.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/network/NetworkModule.kt @@ -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, diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/network/StocksApi.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/network/StocksApi.kt index c36cd13b..57abf8db 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/network/StocksApi.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/network/StocksApi.kt @@ -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 @@ -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 ) { @@ -61,6 +63,26 @@ class StocksApi @Inject constructor( } } + suspend fun getQuoteDetails(ticker: String): FetchResult = + 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) = withContext(Dispatchers.IO) { val query = tickerList.joinToString(",") val quoteNets = yahooFinance.getStocks(query).quoteResponse.result ?: emptyList() diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/network/YahooFinance.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/network/YahooFinance.kt index 0cc51958..ba912cdf 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/network/YahooFinance.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/network/YahooFinance.kt @@ -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 { @@ -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 } \ No newline at end of file diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/network/data/YahooQuoteResponse.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/network/data/YahooQuoteResponse.kt index d8408c42..d76e0546 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/network/data/YahooQuoteResponse.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/network/data/YahooQuoteResponse.kt @@ -6,7 +6,6 @@ data class YahooResponse( @SerializedName("quoteResponse") val quoteResponse: QuoteResponse ) - data class QuoteResponse( @SerializedName("result") val result: List? ) @@ -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, + @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 ) \ No newline at end of file diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailActivity.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailActivity.kt index b2779cd9..164c9da0 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailActivity.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailActivity.kt @@ -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 @@ -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 @@ -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 @@ -65,6 +68,7 @@ class QuoteDetailActivity : BaseGraphActivity(), 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 @@ -111,7 +115,8 @@ class QuoteDetailActivity : BaseGraphActivity(), 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 -> @@ -201,6 +206,21 @@ class QuoteDetailActivity : BaseGraphActivity(), 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() { diff --git a/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailViewModel.kt b/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailViewModel.kt index 75cafeab..6b39bc3f 100644 --- a/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailViewModel.kt +++ b/app/src/main/kotlin/com/github/premnirmal/ticker/news/QuoteDetailViewModel.kt @@ -15,8 +15,10 @@ import com.github.premnirmal.ticker.model.HistoryProvider import com.github.premnirmal.ticker.model.HistoryProvider.Range import com.github.premnirmal.ticker.model.StocksProvider import com.github.premnirmal.ticker.network.NewsProvider +import com.github.premnirmal.ticker.network.StocksApi import com.github.premnirmal.ticker.network.data.DataPoint 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.widget.WidgetData import com.github.premnirmal.ticker.widget.WidgetDataProvider @@ -36,13 +38,14 @@ import javax.inject.Inject class QuoteDetailViewModel @Inject constructor( application: Application, private val stocksProvider: StocksProvider, + private val stocksApi: StocksApi, private val newsProvider: NewsProvider, private val historyProvider: HistoryProvider, private val widgetDataProvider: WidgetDataProvider ) : AndroidViewModel(application) { - private val _quote = MutableSharedFlow>() - val quote: LiveData> + private val _quote = MutableSharedFlow>() + val quote: LiveData> get() = _quote.asLiveData() private val _data = MutableLiveData>() val data: LiveData> @@ -57,96 +60,139 @@ class QuoteDetailViewModel @Inject constructor( val newsError: LiveData get() = _newsError - val details: Flow> = _quote.transform { quote -> - if (quote.wasSuccessful) { - quote.data.run { - val details = mutableListOf() - open?.let { - details.add( - QuoteDetail( - R.string.quote_details_open, - priceFormat.format(it) - ) - ) - } - if (dayLow != null && dayHigh != null) { - details.add( - QuoteDetail( - R.string.quote_details_day_range, - "${dayLow!!.format()} - ${dayHigh!!.format()}" - ) - ) - } - if (fiftyTwoWeekLow != null && fiftyTwoWeekHigh != null) { - details.add( - QuoteDetail( - R.string.quote_details_ftw_range, - "${fiftyTwoWeekLow!!.format()} - ${fiftyTwoWeekHigh!!.format()}" - ) - ) - } - regularMarketVolume?.let { - details.add( - QuoteDetail( - R.string.quote_details_volume, - it.format() - ) - ) - } - marketCap?.let { - details.add( - QuoteDetail( - R.string.quote_details_market_cap, - it.formatBigNumbers(application) - ) - ) - } - trailingPE?.let { - details.add( - QuoteDetail( - R.string.quote_details_pe_ratio, - it.format() - ) - ) - } - earningsTimestamp?.let { - details.add( - QuoteDetail( - R.string.quote_details_earnings_date, - it.formatDate(application.getString(R.string.date_format_long)) - ) - ) - } - if (annualDividendRate > 0f && annualDividendYield > 0f) { - details.add( - QuoteDetail( - R.string.quote_details_dividend_rate, - dividendInfo() - ) - ) - } - dividendDate?.let { - details.add( - QuoteDetail( - R.string.quote_details_dividend_date, - it.formatDate(application.getString(R.string.date_format_long)) - ) - ) - } - emit(details) + private var quoteSummary: QuoteSummary? = null + + val details: Flow> = _quote.transform { summary -> + if (summary.wasSuccessful) { + val quote = summary.data.quote + val quoteSummary = summary.data.quoteSummary + val details = mutableListOf() + quote.open?.let { + details.add( + QuoteDetail( + R.string.quote_details_open, + quote.priceFormat.format(it) + ) + ) + } + if (quote.dayLow != null && quote.dayHigh != null) { + details.add( + QuoteDetail( + R.string.quote_details_day_range, + "${quote.dayLow!!.format()} - ${quote.dayHigh!!.format()}" + ) + ) + } + if (quote.fiftyTwoWeekLow != null && quote.fiftyTwoWeekHigh != null) { + details.add( + QuoteDetail( + R.string.quote_details_ftw_range, + "${quote.fiftyTwoWeekLow!!.format()} - ${quote.fiftyTwoWeekHigh!!.format()}" + ) + ) + } + quote.regularMarketVolume?.let { + details.add( + QuoteDetail( + R.string.quote_details_volume, + it.format() + ) + ) + } + quote.marketCap?.let { + details.add( + QuoteDetail( + R.string.quote_details_market_cap, + it.formatBigNumbers(application) + ) + ) } + quote.trailingPE?.let { + details.add( + QuoteDetail( + R.string.quote_details_pe_ratio, + it.format() + ) + ) + } + quote.earningsTimestamp?.let { + details.add( + QuoteDetail( + R.string.quote_details_earnings_date, + it.formatDate(application.getString(R.string.date_format_long)) + ) + ) + } + if (quote.annualDividendRate > 0f && quote.annualDividendYield > 0f) { + details.add( + QuoteDetail( + R.string.quote_details_dividend_rate, + quote.dividendInfo() + ) + ) + } + quote.dividendDate?.let { + details.add( + QuoteDetail( + R.string.quote_details_dividend_date, + it.formatDate(application.getString(R.string.date_format_long)) + ) + ) + } + quoteSummary?.financialData?.earningsGrowth?.fmt?.let { + details.add( + QuoteDetail( + R.string.quote_details_earnings_growth, + it + ) + ) + } + quoteSummary?.financialData?.revenueGrowth?.fmt?.let { + details.add( + QuoteDetail( + R.string.quote_details_revenue_growth, + it + ) + ) + } + quoteSummary?.financialData?.profitMargins?.fmt?.let { + details.add( + QuoteDetail( + R.string.quote_details_profit_margins, + it + ) + ) + } + quoteSummary?.financialData?.grossMargins?.fmt?.let { + details.add( + QuoteDetail( + R.string.quote_details_gross_margins, + it + ) + ) + } + emit(details) } }.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1) - - fun loadQuote(ticker: String) = viewModelScope.launch { - _quote.emit(FetchResult.success(checkNotNull(stocksProvider.getStock(ticker)))) + _quote.emit(FetchResult.success(QuoteWithSummary(checkNotNull(stocksProvider.getStock(ticker)), quoteSummary))) } fun fetchQuote(ticker: String) { viewModelScope.launch { - _quote.emit(stocksProvider.fetchStock(ticker)) + val fetchStock = stocksProvider.fetchStock(ticker) + if (fetchStock.wasSuccessful) { + val fetchDetails = stocksApi.getQuoteDetails(ticker) + if (fetchDetails.wasSuccessful) { + quoteSummary = fetchDetails.data + _quote.emit(FetchResult.success(QuoteWithSummary(fetchStock.data, quoteSummary))) + } else { + _quote.emit(FetchResult.success(QuoteWithSummary(fetchStock.data, quoteSummary))) + } + } else { + _quote.emit(FetchResult.failure(fetchStock.error)) + } } } @@ -159,7 +205,7 @@ class QuoteDetailViewModel @Inject constructor( val result = stocksProvider.fetchStock(symbol, allowCache = false) if (result.wasSuccessful) { isMarketOpen = result.data.isMarketOpen - _quote.emit(result) + _quote.emit(FetchResult.success(QuoteWithSummary(result.data, quoteSummary))) } delay(StocksProvider.DEFAULT_INTERVAL_MS) } while (isActive && result.wasSuccessful && isMarketOpen) @@ -211,7 +257,7 @@ class QuoteDetailViewModel @Inject constructor( val result = newsProvider.fetchNewsForQuery(query) when { result.wasSuccessful -> { - _newsData.value = result.data.map { ArticleNewsFeed(it) } + _newsData.value = result.data.map { ArticleNewsFeed(it) }.take(8) } else -> { _newsError.value = result.error @@ -250,4 +296,9 @@ class QuoteDetailViewModel @Inject constructor( val data: String ) + + data class QuoteWithSummary( + val quote: Quote, + val quoteSummary: QuoteSummary? + ) } \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_quote_detail.xml b/app/src/main/res/layout-land/activity_quote_detail.xml index 49a1476f..fc99e22f 100644 --- a/app/src/main/res/layout-land/activity_quote_detail.xml +++ b/app/src/main/res/layout-land/activity_quote_detail.xml @@ -560,6 +560,26 @@ + + + + diff --git a/app/src/main/res/layout-sw600dp-land/activity_quote_detail.xml b/app/src/main/res/layout-sw600dp-land/activity_quote_detail.xml index 58e61dd0..9560a917 100644 --- a/app/src/main/res/layout-sw600dp-land/activity_quote_detail.xml +++ b/app/src/main/res/layout-sw600dp-land/activity_quote_detail.xml @@ -581,6 +581,26 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + + + + diff --git a/app/src/main/res/layout/activity_quote_detail.xml b/app/src/main/res/layout/activity_quote_detail.xml index 5aa48594..682c5ae5 100644 --- a/app/src/main/res/layout/activity_quote_detail.xml +++ b/app/src/main/res/layout/activity_quote_detail.xml @@ -565,6 +565,26 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c322e0e4..e78b9756 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ https://finance.yahoo.com/ https://query2.finance.yahoo.com/v1/finance/ https://query1.finance.yahoo.com/v7/finance/ + https://query1.finance.yahoo.com/v11/finance/ https://query1.finance.yahoo.com/v8/finance/ https://api.github.com/ https://apewisdom.io/api/v1.0/ @@ -210,6 +211,10 @@ Earnings Date Dividend Rate Dividend Date + Gross Margins + Profit Margins + Revenue Growth + Earnings Growth MMM dd, yyyy %1$.2fK %1$.2fM diff --git a/app/src/prod/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt b/app/src/prod/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt index 17ff6a70..265730d9 100644 --- a/app/src/prod/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt +++ b/app/src/prod/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt @@ -2,13 +2,12 @@ package com.github.premnirmal.ticker.home import android.app.Activity import android.content.Context -import com.github.premnirmal.ticker.AppPreferences import com.google.android.play.core.review.ReviewManager import com.google.android.play.core.review.ReviewManagerFactory import dagger.hilt.android.qualifiers.ApplicationContext import timber.log.Timber -class AppReviewManager(@ApplicationContext private val context: Context, private val appPreferences: AppPreferences) : IAppReviewManager { +class AppReviewManager(@ApplicationContext private val context: Context) : IAppReviewManager { private val manager: ReviewManager by lazy { ReviewManagerFactory.create(context) @@ -19,7 +18,6 @@ class AppReviewManager(@ApplicationContext private val context: Context, private if (task.isSuccessful) { val reviewInfo = task.result manager.launchReviewFlow(activity, reviewInfo).addOnCompleteListener { - appPreferences.userDidRate() Timber.i("Review left") } } else { diff --git a/app/src/purefoss/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt b/app/src/purefoss/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt index 171d3a3f..8bf5983e 100644 --- a/app/src/purefoss/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt +++ b/app/src/purefoss/kotlin/com/github/premnirmal/ticker/home/AppReviewManager.kt @@ -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 \ No newline at end of file +class AppReviewManager(@ApplicationContext context: Context) : IAppReviewManager \ No newline at end of file diff --git a/app/src/test/kotlin/com/github/premnirmal/ticker/network/StocksApiTest.kt b/app/src/test/kotlin/com/github/premnirmal/ticker/network/StocksApiTest.kt index 2485c8e8..b92a593d 100644 --- a/app/src/test/kotlin/com/github/premnirmal/ticker/network/StocksApiTest.kt +++ b/app/src/test/kotlin/com/github/premnirmal/ticker/network/StocksApiTest.kt @@ -26,6 +26,7 @@ class StocksApiTest : BaseUnitTest() { } internal lateinit var yahooFinance: YahooFinance + internal lateinit var yahooFinanceQuoteDetails: YahooQuoteDetails internal lateinit var mockPrefs: SharedPreferences private lateinit var stocksApi: StocksApi @@ -34,9 +35,10 @@ class StocksApiTest : BaseUnitTest() { runBlocking { yahooFinance = Mocker.provide(YahooFinance::class) mockPrefs = Mocker.provide(SharedPreferences::class) + yahooFinanceQuoteDetails = Mocker.provide(YahooQuoteDetails::class) val suggestionApi = Mocker.provide(SuggestionApi::class) val clock = Mocker.provide(AppClock::class) - stocksApi = StocksApi(Mocker.provide(Gson::class), yahooFinance, suggestionApi, clock) + stocksApi = StocksApi(Mocker.provide(Gson::class), yahooFinance, yahooFinanceQuoteDetails, suggestionApi, clock) val listType = object : TypeToken>() {}.type val yahooStockList = parseJsonFile(YahooResponse::class.java, "YahooQuotes.json") diff --git a/app/version.properties b/app/version.properties index 633ec4e6..cfea8807 100644 --- a/app/version.properties +++ b/app/version.properties @@ -1,3 +1,3 @@ # this file is purely for f-droid because it cannot infer the version name/code from the git tag -versionName=3.9.813 -versionCode=300900813 +versionName=3.9.814 +versionCode=300900814