Skip to content

Commit

Permalink
Merge branch 'development' into release/1.190
Browse files Browse the repository at this point in the history
  • Loading branch information
rostikjoystick committed Sep 15, 2021
2 parents 2a6b1ba + 0525fa2 commit 9d8caca
Show file tree
Hide file tree
Showing 18 changed files with 123 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.stepik.android.data.course_payments.source.CoursePaymentsCacheDataSou
import org.stepik.android.data.course_payments.source.CoursePaymentsRemoteDataSource
import org.stepik.android.domain.base.DataSourceType
import org.stepik.android.domain.course_payments.model.CoursePayment
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.domain.course_payments.repository.CoursePaymentsRepository
import ru.nobird.android.domain.rx.doCompletableOnSuccess
import javax.inject.Inject
Expand Down Expand Up @@ -36,8 +36,8 @@ constructor(
throw IllegalArgumentException("Unsupported source type = $sourceType")
}

override fun checkPromoCodeValidity(courseId: Long, name: String): Single<PromoCode> =
override fun checkDeeplinkPromoCodeValidity(courseId: Long, name: String): Single<DeeplinkPromoCode> =
coursePaymentsRemoteDataSource
.checkPromoCodeValidity(courseId, name)
.onErrorReturnItem(PromoCode.EMPTY)
.checkDeeplinkPromoCodeValidity(courseId, name)
.onErrorReturnItem(DeeplinkPromoCode.EMPTY)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.reactivex.Single
import org.solovyev.android.checkout.Purchase
import org.solovyev.android.checkout.Sku
import org.stepik.android.domain.course_payments.model.CoursePayment
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode

interface CoursePaymentsRemoteDataSource {

Expand All @@ -17,5 +17,5 @@ interface CoursePaymentsRemoteDataSource {
*/
fun getCoursePaymentsByCourseId(courseId: Long, coursePaymentStatus: CoursePayment.Status? = null): Single<List<CoursePayment>>

fun checkPromoCodeValidity(courseId: Long, name: String): Single<PromoCode>
fun checkDeeplinkPromoCodeValidity(courseId: Long, name: String): Single<DeeplinkPromoCode>
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.stepik.android.domain.base.DataSourceType
import org.stepik.android.domain.course.model.CourseHeaderData
import org.stepik.android.domain.course.repository.CourseRepository
import org.stepik.android.domain.course_payments.mapper.DefaultPromoCodeMapper
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.domain.solutions.interactor.SolutionsInteractor
import org.stepik.android.domain.solutions.model.SolutionItem
import org.stepik.android.domain.wishlist.model.WishlistEntity
Expand Down Expand Up @@ -62,9 +62,8 @@ constructor(
zip(
courseStatsInteractor.getCourseStats(listOf(course)),
solutionsInteractor.fetchAttemptCacheItems(course.id, localOnly = true),
if (promo == null) Single.just(PromoCode.EMPTY) else courseStatsInteractor.checkPromoCodeValidity(course.id, promo),
if (promo == null) Single.just(DeeplinkPromoCode.EMPTY) else courseStatsInteractor.checkDeeplinkPromoCodeValidity(course.id, promo),
(requireAuthorization() then wishlistRepository.getWishlistRecord(DataSourceType.CACHE)).onErrorReturnItem(WishlistEntity.EMPTY)
// if (sharedPreferenceHelper.authResponseFromStore != null) wishlistRepository.getWishlistRecord(DataSourceType.CACHE) else Single.just(WishlistEntity.EMPTY)
) { courseStats, localSubmissions, promoCode, wishlistEntity ->
CourseHeaderData(
courseId = course.id,
Expand All @@ -74,7 +73,7 @@ constructor(

stats = courseStats.first(),
localSubmissionsCount = localSubmissions.count { it is SolutionItem.SubmissionItem },
promoCode = promoCode,
deeplinkPromoCode = promoCode,
defaultPromoCode = defaultPromoCodeMapper.mapToDefaultPromoCode(course),
isWishlistUpdating = false,
wishlistEntity = wishlistEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.stepik.android.domain.course.model.EnrollmentState
import org.stepik.android.domain.course.model.SourceTypeComposition
import org.stepik.android.domain.course.repository.CourseReviewSummaryRepository
import org.stepik.android.domain.course_payments.model.CoursePayment
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.domain.course_payments.repository.CoursePaymentsRepository
import org.stepik.android.domain.progress.mapper.getProgresses
import org.stepik.android.domain.profile.repository.ProfileRepository
Expand Down Expand Up @@ -70,9 +70,9 @@ constructor(
}
}

fun checkPromoCodeValidity(courseId: Long, promo: String): Single<PromoCode> =
fun checkDeeplinkPromoCodeValidity(courseId: Long, promo: String): Single<DeeplinkPromoCode> =
coursePaymentsRepository
.checkPromoCodeValidity(courseId, promo)
.checkDeeplinkPromoCodeValidity(courseId, promo)

/**
* Load course reviews for not enrolled [courses]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import org.stepik.android.domain.wishlist.model.WishlistEntity
import org.stepik.android.domain.course_payments.model.DefaultPromoCode
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.model.Course

@Parcelize
Expand All @@ -16,7 +16,7 @@ data class CourseHeaderData(

val stats: CourseStats,
val localSubmissionsCount: Int,
val promoCode: PromoCode,
val deeplinkPromoCode: DeeplinkPromoCode,
val defaultPromoCode: DefaultPromoCode,
val isWishlistUpdating: Boolean,
val wishlistEntity: WishlistEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize

@Parcelize
data class PromoCode(
data class DeeplinkPromoCode(
@SerializedName("price")
val price: String,
@SerializedName("currency_code")
val currencyCode: String
) : Parcelable {
companion object {
val EMPTY = PromoCode("", "")
val EMPTY = DeeplinkPromoCode("", "")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.solovyev.android.checkout.Purchase
import org.solovyev.android.checkout.Sku
import org.stepik.android.domain.base.DataSourceType
import org.stepik.android.domain.course_payments.model.CoursePayment
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode

interface CoursePaymentsRepository {
fun createCoursePayment(courseId: Long, sku: Sku, purchase: Purchase): Single<CoursePayment>
Expand All @@ -17,5 +17,5 @@ interface CoursePaymentsRepository {
*/
fun getCoursePaymentsByCourseId(courseId: Long, coursePaymentStatus: CoursePayment.Status? = null, sourceType: DataSourceType = DataSourceType.CACHE): Single<List<CoursePayment>>

fun checkPromoCodeValidity(courseId: Long, name: String): Single<PromoCode>
fun checkDeeplinkPromoCodeValidity(courseId: Long, name: String): Single<DeeplinkPromoCode>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.solovyev.android.checkout.Purchase
import org.solovyev.android.checkout.Sku
import org.stepik.android.data.course_payments.source.CoursePaymentsRemoteDataSource
import org.stepik.android.domain.course_payments.model.CoursePayment
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.remote.course_payments.model.CoursePaymentRequest
import org.stepik.android.remote.course_payments.model.CoursePaymentsResponse
import org.stepik.android.remote.course_payments.model.PromoCodeRequest
Expand Down Expand Up @@ -47,9 +47,9 @@ constructor(
}
}

override fun checkPromoCodeValidity(courseId: Long, name: String): Single<PromoCode> =
override fun checkDeeplinkPromoCodeValidity(courseId: Long, name: String): Single<DeeplinkPromoCode> =
coursePaymentService
.checkPromoCodeValidity(PromoCodeRequest(
.checkDeeplinkPromoCodeValidity(PromoCodeRequest(
course = courseId,
name = name
))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.stepik.android.remote.course_payments.service

import io.reactivex.Single
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.remote.course_payments.model.CoursePaymentRequest
import org.stepik.android.remote.course_payments.model.CoursePaymentsResponse
import org.stepik.android.remote.course_payments.model.PromoCodeRequest
Expand All @@ -22,7 +22,7 @@ interface CoursePaymentService {
): Single<CoursePaymentsResponse>

@POST("api/promo-codes/check")
fun checkPromoCodeValidity(
fun checkDeeplinkPromoCodeValidity(
@Body promoCodeRequest: PromoCodeRequest
): Single<PromoCode>
): Single<DeeplinkPromoCode>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.stepik.android.view.course.mapper

import android.content.Context
import android.text.SpannedString
import androidx.core.text.buildSpannedString
import androidx.core.text.scale
import androidx.core.text.strikeThrough
import org.stepic.droid.R
import javax.inject.Inject

Expand All @@ -22,4 +26,18 @@ constructor(
else ->
"$price $currencyCode"
}

fun mapToDiscountedDisplayPriceSpannedString(originalDisplayPrice: String, currencyCode: String, promoPrice: String): SpannedString {
val promoDisplayPrice = mapToDisplayPrice(currencyCode, promoPrice)
return buildSpannedString {
append(context.getString(R.string.course_payments_purchase_in_web_with_price_promo))
append(promoDisplayPrice)
append(" ")
scale(0.9f) {
strikeThrough {
append(originalDisplayPrice)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.stepik.android.view.course.model

data class CoursePromoCodeInfo(
val currencyCode: String,
val price: String,
val hasPromo: Boolean
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.stepik.android.view.course.resolver

import org.stepic.droid.util.DateTimeHelper
import org.stepik.android.domain.course_payments.model.DeeplinkPromoCode
import org.stepik.android.domain.course_payments.model.DefaultPromoCode
import org.stepik.android.model.Course
import org.stepik.android.view.course.model.CoursePromoCodeInfo
import javax.inject.Inject

class CoursePromoCodeResolver
@Inject
constructor() {
fun resolvePromoCodeInfo(deeplinkPromoCode: DeeplinkPromoCode, defaultPromoCode: DefaultPromoCode, course: Course): CoursePromoCodeInfo =
when {
deeplinkPromoCode != DeeplinkPromoCode.EMPTY ->
CoursePromoCodeInfo(deeplinkPromoCode.currencyCode, deeplinkPromoCode.price, true)

defaultPromoCode != DefaultPromoCode.EMPTY &&
(defaultPromoCode.defaultPromoCodeExpireDate == null || defaultPromoCode.defaultPromoCodeExpireDate.time > DateTimeHelper.nowUtc()) && course.currencyCode != null ->
CoursePromoCodeInfo(course.currencyCode!!, defaultPromoCode.defaultPromoCodePrice, true)

else ->
CoursePromoCodeInfo("", "", false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package org.stepik.android.view.course.ui.delegates

import android.app.Activity
import android.text.SpannableString
import android.text.SpannedString
import android.text.style.ForegroundColorSpan
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.text.buildSpannedString
import androidx.core.text.scale
import androidx.core.text.strikeThrough
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
Expand Down Expand Up @@ -39,14 +37,13 @@ import org.stepik.android.domain.course.analytic.batch.BuyCoursePressedAnalyticB
import org.stepik.android.domain.course.model.CourseHeaderData
import org.stepik.android.domain.course.model.EnrollmentState
import org.stepik.android.domain.course_continue.analytic.CourseContinuePressedEvent
import org.stepik.android.domain.course_payments.model.DefaultPromoCode
import org.stepik.android.domain.course_payments.model.PromoCode
import org.stepik.android.presentation.course.CoursePresenter
import org.stepik.android.presentation.course_continue.model.CourseContinueInteractionSource
import org.stepik.android.presentation.user_courses.model.UserCourseAction
import org.stepik.android.presentation.wishlist.model.WishlistAction
import org.stepik.android.view.base.ui.extension.ColorExtensions
import org.stepik.android.view.course.mapper.DisplayPriceMapper
import org.stepik.android.view.course.resolver.CoursePromoCodeResolver
import org.stepik.android.view.ui.delegate.ViewStateDelegate
import ru.nobird.android.core.model.safeCast
import ru.nobird.android.view.base.ui.extension.getAllQueryParameters
Expand All @@ -61,6 +58,7 @@ constructor(
@Assisted private val coursePresenter: CoursePresenter,
private val discountButtonAppearanceSplitTest: DiscountButtonAppearanceSplitTest,
private val displayPriceMapper: DisplayPriceMapper,
private val coursePromoCodeResolver: CoursePromoCodeResolver,
@Assisted private val courseViewSource: CourseViewSource,
@Assisted private val isAuthorized: Boolean,
@Assisted private val mustShowCourseBenefits: Boolean,
Expand Down Expand Up @@ -206,25 +204,18 @@ constructor(
courseStatsDelegate.setStats(courseHeaderData.stats)
}

val (currencyCode, promoPrice, hasPromo) = when {
courseHeaderData.promoCode != PromoCode.EMPTY ->
Triple(courseHeaderData.promoCode.currencyCode, courseHeaderData.promoCode.price, true)

courseHeaderData.defaultPromoCode != DefaultPromoCode.EMPTY &&
(courseHeaderData.defaultPromoCode.defaultPromoCodeExpireDate == null || courseHeaderData.defaultPromoCode.defaultPromoCodeExpireDate.time > DateTimeHelper.nowUtc()) &&
courseHeaderData.course.currencyCode != null ->
Triple(courseHeaderData.course.currencyCode!!, courseHeaderData.defaultPromoCode.defaultPromoCodePrice, true)

else ->
Triple("", "", false)
}
val (currencyCode, promoPrice, hasPromo) = coursePromoCodeResolver.resolvePromoCodeInfo(
courseHeaderData.deeplinkPromoCode,
courseHeaderData.defaultPromoCode,
courseHeaderData.course
)

val courseDisplayPrice = courseHeaderData.course.displayPrice

courseBuyInWebAction.text =
if (courseDisplayPrice != null) {
if (hasPromo) {
getPurchaseButtonText(courseDisplayPrice, currencyCode, promoPrice)
displayPriceMapper.mapToDiscountedDisplayPriceSpannedString(courseDisplayPrice, currencyCode, promoPrice)
} else {
getString(R.string.course_payments_purchase_in_web_with_price, courseDisplayPrice)
}
Expand Down Expand Up @@ -293,20 +284,6 @@ constructor(
shareCourseMenuItem?.isVisible = true
}

private fun getPurchaseButtonText(originalDisplayPrice: String, currencyCode: String, promoPrice: String): SpannedString {
val promoDisplayPrice = displayPriceMapper.mapToDisplayPrice(currencyCode, promoPrice)
return buildSpannedString {
append(courseActivity.getString(R.string.course_payments_purchase_in_web_with_price_promo))
append(promoDisplayPrice)
append(" ")
scale(0.9f) {
strikeThrough {
append(originalDisplayPrice)
}
}
}
}

fun showCourseShareTooltip() {
val menuItemView = courseActivity
.courseToolbar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ class DownloadActivity : FragmentActivityBase(), DownloadView, RemoveCachedConte
downloadPresenter.fetchStorage()
downloadPresenter.fetchDownloadedCourses()

TextViewCompat.setCompoundDrawableTintList(downloadsOtherApps, ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_on_surface_alpha_12)))
TextViewCompat.setCompoundDrawableTintList(downloadsOtherApps, ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_overlay_yellow)))
TextViewCompat.setCompoundDrawableTintList(downloadsStepik, ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_overlay_green)))
TextViewCompat.setCompoundDrawableTintList(downloadsFree, ColorStateList.valueOf(ContextCompat.getColor(this, R.color.grey04)))
TextViewCompat.setCompoundDrawableTintList(downloadsFree, ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_elevation_overlay_2dp)))
}

private fun injectComponent() {
Expand Down
Loading

0 comments on commit 9d8caca

Please sign in to comment.