Skip to content

Commit 4670e85

Browse files
authored
Rewarded SDAI (#31)
* Rewarded feature * Update localization * Update * Added rewarded to settings * Update
1 parent f6833f2 commit 4670e85

File tree

59 files changed

+454
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+454
-88
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
buildscript {
22
ext {
3-
appVersion = "0.2.1"
3+
appVersion = "0.3.0"
44
minSdk = 26
55
targetSdk = 33
66
}

data/src/main/java/com/shifthackz/aisdv1/data/local/CoinLocalDataSource.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@ package com.shifthackz.aisdv1.data.local
22

33
import com.shifthackz.aisdv1.domain.datasource.CoinDataSource
44
import com.shifthackz.aisdv1.storage.db.coins.dao.CoinDao
5+
import com.shifthackz.aisdv1.storage.db.coins.dao.EarnedCoinDao
56
import com.shifthackz.aisdv1.storage.db.coins.entity.CoinEntity
7+
import com.shifthackz.aisdv1.storage.db.coins.entity.EarnedCoinEntity
68
import io.reactivex.rxjava3.core.Completable
9+
import io.reactivex.rxjava3.core.Single
710
import java.util.*
811

912
internal class CoinLocalDataSource(
1013
private val coinDao: CoinDao,
14+
private val earnedCoinDao: EarnedCoinDao,
1115
) : CoinDataSource.Local {
1216

13-
override fun querySpentCoinsForPeriod(start: Long, end: Long) = coinDao
17+
override fun querySpentDailyCoinsForPeriod(start: Long, end: Long) = coinDao
1418
.queryAvailableCoinsForPeriod(start, end)
1519
.map { it.size }
1620

17-
override fun onCoinSpent(): Completable = coinDao.insert(
18-
CoinEntity(0L, Date())
19-
)
21+
override fun queryEarnedCoins(): Single<Int> = earnedCoinDao.queryCount()
22+
23+
override fun onDailyCoinSpent(): Completable = coinDao.insert(CoinEntity(0L, Date()))
24+
25+
override fun onEarnedCoinSpent(): Completable = earnedCoinDao.deleteLast()
26+
27+
override fun onEarnedCoinsRewarded(amount: Int): Completable = (1..amount)
28+
.map { EarnedCoinEntity(0L, Date()) }
29+
.let(earnedCoinDao::insert)
2030
}

data/src/main/java/com/shifthackz/aisdv1/data/repository/CoinRepositoryImpl.kt

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,47 +20,68 @@ internal class CoinRepositoryImpl(
2020
private val sessionPreference: SessionPreference,
2121
) : CoinRepository {
2222

23-
private val eventCoinSpent: PublishSubject<Unit> = PublishSubject.create()
24-
25-
override fun observeAvailableCoinsForToday(): Flowable<Int> {
26-
val coinsPerDayProducer: () -> Single<Int> = {
27-
val availableCoinsPerDay = sessionPreference.coinsPerDay
28-
if (availableCoinsPerDay != -1) Single.just(availableCoinsPerDay)
29-
else coinRemoteDateSource
30-
.fetchCoinsConfig()
31-
.doOnSuccess { sessionPreference.coinsPerDay = it }
32-
}
23+
private val eventCoinsUpdated: PublishSubject<Unit> = PublishSubject.create()
3324

25+
override fun observeAvailableCoins(): Flowable<Int> {
3426
val coinsCalculationProducer: () -> Flowable<Int> = {
35-
val (start, end) = Date().getDayRange()
36-
coinsPerDayProducer()
37-
.zipWith(
38-
coinLocalDataSource.querySpentCoinsForPeriod(start.time, end.time),
39-
::Pair,
40-
)
41-
.map { (availableToday, spentToday) -> availableToday - spentToday }
42-
.map { coins -> if (coins < 0) 0 else coins }
27+
Single.zip(
28+
calculateAvailableDailyCoins(),
29+
calculateAvailableEarnedCoins(),
30+
::Pair,
31+
)
32+
.map { (daily, earned) -> daily + earned }
4333
.toFlowable()
4434
}
4535

46-
val coinSpentEventProducer: () -> Flowable<*> = {
47-
eventCoinSpent.toFlowable(BackpressureStrategy.LATEST)
36+
val coinsUpdatedEventProducer: () -> Flowable<*> = {
37+
eventCoinsUpdated.toFlowable(BackpressureStrategy.LATEST)
4838
}
4939

5040
val coreTickProducer: () -> Flowable<*> = {
51-
Flowable.interval(10L, TimeUnit.SECONDS)
41+
Flowable.interval(5L, TimeUnit.SECONDS)
5242
}
5343

5444
return Flowable
55-
.merge(coinsCalculationProducer(), coreTickProducer(), coinSpentEventProducer())
45+
.merge(coinsCalculationProducer(), coreTickProducer(), coinsUpdatedEventProducer())
5646
.flatMap { coinsCalculationProducer() }
5747
.replay(1)
5848
.refCount(1, TimeUnit.SECONDS)
5949
}
6050

6151
override fun spendCoin(): Completable {
62-
eventCoinSpent.onNext(Unit)
63-
return if (preferenceManager.useSdAiCloud) coinLocalDataSource.onCoinSpent()
52+
eventCoinsUpdated.onNext(Unit)
53+
return if (preferenceManager.useSdAiCloud) {
54+
calculateAvailableDailyCoins()
55+
.flatMapCompletable {
56+
if (it > 0) coinLocalDataSource.onDailyCoinSpent()
57+
else coinLocalDataSource.onEarnedCoinSpent()
58+
}
59+
.doOnComplete { eventCoinsUpdated.onNext(Unit) }
60+
}
6461
else Completable.complete()
6562
}
63+
64+
override fun earnCoins(amount: Int) = coinLocalDataSource.onEarnedCoinsRewarded(amount)
65+
66+
private fun getAvailableCoinsPerDay(): Single<Int> {
67+
val availableCoinsPerDay = sessionPreference.coinsPerDay
68+
return if (availableCoinsPerDay != -1) Single.just(availableCoinsPerDay)
69+
else coinRemoteDateSource
70+
.fetchCoinsConfig()
71+
.doOnSuccess { sessionPreference.coinsPerDay = it }
72+
}
73+
74+
private fun calculateAvailableDailyCoins(): Single<Int> {
75+
val (start, end) = Date().getDayRange()
76+
return getAvailableCoinsPerDay()
77+
.zipWith(
78+
coinLocalDataSource.querySpentDailyCoinsForPeriod(start.time, end.time),
79+
::Pair,
80+
)
81+
.map { (availableToday, spentToday) -> availableToday - spentToday }
82+
.map { coins -> if (coins < 0) 0 else coins }
83+
}
84+
85+
private fun calculateAvailableEarnedCoins(): Single<Int> =
86+
coinLocalDataSource.queryEarnedCoins()
6687
}

demo/src/main/java/com/shifthackz/aisdv1/demo/ImageToImageDemoImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.shifthackz.aisdv1.domain.entity.AiGenerationResult
66
import com.shifthackz.aisdv1.domain.entity.ImageToImagePayload
77
import java.util.*
88

9-
class ImageToImageDemoImpl(
9+
internal class ImageToImageDemoImpl(
1010
override val demoDataSerializer: DemoDataSerializer,
1111
) : ImageToImageDemo, DemoFeature<ImageToImagePayload> {
1212

demo/src/main/java/com/shifthackz/aisdv1/demo/serialize/DemoDataSerializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.google.gson.Gson
55
import com.google.gson.reflect.TypeToken
66
import java.io.BufferedReader
77

8-
class DemoDataSerializer(private val contextProvider: () -> Context) {
8+
internal class DemoDataSerializer(private val contextProvider: () -> Context) {
99

1010
fun readDemoAssets(): List<String> {
1111
val rawString = contextProvider().resources.assets

domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/CoinDataSource.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import io.reactivex.rxjava3.core.Single
66
sealed interface CoinDataSource {
77

88
interface Local : CoinDataSource {
9-
fun querySpentCoinsForPeriod(start: Long, end: Long): Single<Int>
10-
fun onCoinSpent(): Completable
9+
fun querySpentDailyCoinsForPeriod(start: Long, end: Long): Single<Int>
10+
fun queryEarnedCoins(): Single<Int>
11+
fun onDailyCoinSpent(): Completable
12+
fun onEarnedCoinSpent(): Completable
13+
fun onEarnedCoinsRewarded(amount: Int): Completable
1114
}
1215

1316
interface Remote : CoinDataSource {

domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.shifthackz.aisdv1.domain.usecase.caching.ClearAppCacheUseCase
44
import com.shifthackz.aisdv1.domain.usecase.caching.ClearAppCacheUseCaseImpl
55
import com.shifthackz.aisdv1.domain.usecase.caching.DataPreLoaderUseCase
66
import com.shifthackz.aisdv1.domain.usecase.caching.DataPreLoaderUseCaseImpl
7+
import com.shifthackz.aisdv1.domain.usecase.coin.EarnRewardedCoinsUseCase
8+
import com.shifthackz.aisdv1.domain.usecase.coin.EarnRewardedCoinsUseCaseImpl
79
import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase
810
import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCaseImpl
911
import com.shifthackz.aisdv1.domain.usecase.connectivity.*
@@ -48,4 +50,5 @@ val domainModule = module {
4850
factoryOf(::ObserveSeverConnectivityUseCaseImpl) bind ObserveSeverConnectivityUseCase::class
4951
factoryOf(::CheckAppVersionUpdateUseCaseImpl) bind CheckAppVersionUpdateUseCase::class
5052
factoryOf(::ObserveCoinsUseCaseImpl) bind ObserveCoinsUseCase::class
53+
factoryOf(::EarnRewardedCoinsUseCaseImpl) bind EarnRewardedCoinsUseCase::class
5154
}

domain/src/main/java/com/shifthackz/aisdv1/domain/feature/ad/AdFeature.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface AdFeature {
99
fun getHomeScreenBannerAd(context: Context): Ad
1010
fun getGalleryDetailBannerAd(context: Context): Ad
1111
fun loadAd(ad: Ad)
12+
fun showRewardedCoinsAd(activity: Activity, rewardCallback: (Int) -> Unit)
1213

1314
data class Ad(
1415
val id: String = "",

domain/src/main/java/com/shifthackz/aisdv1/domain/repository/CoinRepository.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.reactivex.rxjava3.core.Completable
44
import io.reactivex.rxjava3.core.Flowable
55

66
interface CoinRepository {
7-
fun observeAvailableCoinsForToday(): Flowable<Int>
7+
fun observeAvailableCoins(): Flowable<Int>
88
fun spendCoin(): Completable
9+
fun earnCoins(amount: Int): Completable
910
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.shifthackz.aisdv1.domain.usecase.coin
2+
3+
import io.reactivex.rxjava3.core.Completable
4+
5+
interface EarnRewardedCoinsUseCase {
6+
operator fun invoke(amount: Int): Completable
7+
}

0 commit comments

Comments
 (0)