Integrated api for ads data.
Cached data globally and inflated ads on Home1Fragment, WebSeriesFragment, KaraokeActivity, AudioBooksActivity and GamesActivity and ShopFragment1 Implemented local database for ads impressions and clicks. Implemented remote sync for ads clicks and impressions. Tested thw working of database and syncing of data. Shared build with client. Solved bug for clearing cart when user logs out. Implemented dialog for session expired.
This commit is contained in:
@@ -17,6 +17,10 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Woka"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".utils.SessionExpiredActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/TransparentActivity"/>
|
||||
<activity
|
||||
android:name=".home.mylist.view.FavoritesActivity"
|
||||
android:exported="false" />
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import com.jwplayer.pub.api.license.LicenseUtil
|
||||
import com.onesignal.OneSignal
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.database.AppDatabase
|
||||
import com.woka.streamingurls.StreamingUrlRepository
|
||||
import com.woka.userPreference.UserPreference
|
||||
@@ -30,6 +31,10 @@ class WokaApp: Application() {
|
||||
|
||||
StreamingUrlRepository.loadLiveStreamingUrls()
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
AdsRepository.getADs()
|
||||
}
|
||||
|
||||
initOneSignal()
|
||||
}
|
||||
|
||||
|
||||
12
app/src/main/java/com/woka/advertisements/AdsApiService.kt
Normal file
12
app/src/main/java/com/woka/advertisements/AdsApiService.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.woka.advertisements
|
||||
|
||||
import com.woka.advertisements.models.AdsResponse
|
||||
import com.woka.networking.ApiResponse
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface AdsApiService {
|
||||
|
||||
@GET("get_ad_data")
|
||||
suspend fun getAdsData() : Response<ApiResponse<AdsResponse>>
|
||||
}
|
||||
31
app/src/main/java/com/woka/advertisements/AdsRepository.kt
Normal file
31
app/src/main/java/com/woka/advertisements/AdsRepository.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.woka.advertisements
|
||||
|
||||
import com.woka.advertisements.models.AdData
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.networking.RetrofitHelper
|
||||
import com.woka.networking.RetrofitHelper.handleApiCall
|
||||
|
||||
object AdsRepository {
|
||||
|
||||
private val apiService = RetrofitHelper.getRetrofit().create(AdsApiService::class.java)
|
||||
|
||||
@Volatile
|
||||
private var adsData: List<AdData>? = null
|
||||
|
||||
suspend fun getADs(): List<AdData>?{
|
||||
if (adsData != null){
|
||||
return adsData
|
||||
}
|
||||
|
||||
when (val response = handleApiCall{ apiService.getAdsData() }){
|
||||
is ApiResult.Error -> {}
|
||||
is ApiResult.Loading -> {}
|
||||
is ApiResult.Success -> {
|
||||
adsData = response.data?.result?.filterNotNull()
|
||||
}
|
||||
}
|
||||
|
||||
return adsData
|
||||
}
|
||||
|
||||
}
|
||||
11
app/src/main/java/com/woka/advertisements/models/AdData.kt
Normal file
11
app/src/main/java/com/woka/advertisements/models/AdData.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.woka.advertisements.models
|
||||
|
||||
data class AdData(
|
||||
val ad_company: String?,
|
||||
val ad_link: String?,
|
||||
val banner_image: String?,
|
||||
val button_image: String?,
|
||||
val for_page: String?,
|
||||
val id: Int?,
|
||||
val title: String?
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.woka.advertisements.models
|
||||
|
||||
data class AdsResponse(
|
||||
val result: List<AdData?>?,
|
||||
val total_records: Int?
|
||||
)
|
||||
11
app/src/main/java/com/woka/advertisements/models/ForPage.kt
Normal file
11
app/src/main/java/com/woka/advertisements/models/ForPage.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.woka.advertisements.models
|
||||
|
||||
enum class ForPage(val value: String) {
|
||||
THEME_1("theme-1"),
|
||||
THEME_2("theme-2"),
|
||||
WEB_SERIES("web-series"),
|
||||
KARAOKE("karaoke"),
|
||||
AUDIO_BOOKS("audio-books"),
|
||||
GAMES("games"),
|
||||
SHOP_SUPER_CATEGORY("shop-super-category");
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.InsetDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.WindowManager
|
||||
@@ -14,17 +15,21 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.jwplayer.pub.api.media.playlists.PlaylistItem
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.audiobooks.AudioBookRepository
|
||||
import com.woka.audiobooks.adapters.AudioBooksAdapter
|
||||
import com.woka.audiobooks.adapters.ContinueAudioAdapter
|
||||
import com.woka.audiobooks.models.audiodata.AudioBookData
|
||||
import com.woka.audiobooks.models.continuedata.ContinueAudioData
|
||||
import com.woka.audiobooks.viewmodels.AudioBookViewModel
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.ActivityAudioBooksBinding
|
||||
@@ -42,6 +47,7 @@ import com.woka.utils.setVisibility
|
||||
import com.woka.utils.shareWokaApp
|
||||
import com.woka.utils.show
|
||||
import com.woka.utils.toast
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
@@ -62,6 +68,8 @@ class AudioBooksActivity : WokaBaseActivity() {
|
||||
|
||||
private lateinit var playerLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
private var adLoaded = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
@@ -101,6 +109,8 @@ class AudioBooksActivity : WokaBaseActivity() {
|
||||
|
||||
setObservers()
|
||||
|
||||
loadAds()
|
||||
|
||||
if (!viewModel.audioBookLiveData.isInitialized) {
|
||||
viewModel.loadAudioSongs()
|
||||
}
|
||||
@@ -182,6 +192,47 @@ class AudioBooksActivity : WokaBaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAds(){
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let { ads ->
|
||||
val theme1ads = ads.filter { it.for_page == ForPage.AUDIO_BOOKS.value}
|
||||
|
||||
if (theme1ads.isNotEmpty()){
|
||||
val adDetails = theme1ads.first()
|
||||
|
||||
AdClicksHelper.addImpression(adDetails.id)
|
||||
|
||||
adLoaded = true
|
||||
|
||||
binding.trailerBtn.hide()
|
||||
binding.trailerName.hide()
|
||||
|
||||
binding.adButtonView.show()
|
||||
|
||||
binding.trailerView.show()
|
||||
adjustTrailerImage()
|
||||
|
||||
adDetails.banner_image?.let {url ->
|
||||
binding.trailerImage.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.button_image?.let {url ->
|
||||
binding.adButtonImg.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.ad_link?.let {url ->
|
||||
binding.adBtn.setOnClickListener {
|
||||
AdClicksHelper.addClick(adDetails.id)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setObservers() {
|
||||
viewModel.audioBookLiveData.observe(this) {
|
||||
when (it) {
|
||||
@@ -275,6 +326,8 @@ class AudioBooksActivity : WokaBaseActivity() {
|
||||
}
|
||||
|
||||
private fun loadTrailerData(audioBookData: AudioBookData) {
|
||||
if (adLoaded) return
|
||||
|
||||
binding.apply {
|
||||
trailerView.show()
|
||||
adjustTrailerImage()
|
||||
|
||||
@@ -4,14 +4,16 @@ import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.woka.database.dao.AdClickDao
|
||||
import com.woka.database.dao.ClicksDao
|
||||
import com.woka.database.dao.VideoViewDao
|
||||
import com.woka.database.models.adclicks.AdClickEvent
|
||||
import com.woka.database.models.clicks.ClickEvent
|
||||
import com.woka.database.models.videoview.VideoViewEvent
|
||||
|
||||
private const val DATABASE_NAME = "woka_local_db"
|
||||
|
||||
@Database(entities = [ClickEvent::class, VideoViewEvent::class], version = 1)
|
||||
@Database(entities = [ClickEvent::class, VideoViewEvent::class, AdClickEvent::class], version = 1)
|
||||
abstract class AppDatabase : RoomDatabase(){
|
||||
|
||||
companion object{
|
||||
@@ -35,4 +37,6 @@ abstract class AppDatabase : RoomDatabase(){
|
||||
abstract fun clicksDao(): ClicksDao
|
||||
|
||||
abstract fun videoViewDao(): VideoViewDao
|
||||
|
||||
abstract fun adClicksDao(): AdClickDao
|
||||
}
|
||||
43
app/src/main/java/com/woka/database/dao/AdClickDao.kt
Normal file
43
app/src/main/java/com/woka/database/dao/AdClickDao.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.woka.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import com.woka.database.models.adclicks.AdClickEvent
|
||||
import com.woka.database.models.clicks.ClickEvent
|
||||
|
||||
@Dao
|
||||
interface AdClickDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insert(vararg adClickEvent: AdClickEvent)
|
||||
|
||||
@Query("UPDATE ad_click_events " +
|
||||
"SET no_of_click = no_of_click + :clicksCount, " +
|
||||
"no_of_impression = no_of_impression + :impressionCount " +
|
||||
"WHERE ad_id = :adId")
|
||||
suspend fun updateAndGetRowCount(adId: Int, clicksCount: Int, impressionCount: Int): Int
|
||||
|
||||
@Transaction
|
||||
suspend fun upsertClickEvent(adId: Int, clicksCount: Int, impressionCount: Int){
|
||||
val count = updateAndGetRowCount(adId, clicksCount, impressionCount)
|
||||
if (count == 0){
|
||||
insert(
|
||||
AdClickEvent(
|
||||
adId,
|
||||
clicksCount,
|
||||
impressionCount
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Query("select * from ad_click_events limit :batchSize")
|
||||
suspend fun getAdClickEventBatch(batchSize: Int): List<AdClickEvent>
|
||||
|
||||
@Delete
|
||||
suspend fun deleteAdClickEvents(clickEvent: List<AdClickEvent>): Int
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.woka.database.helpers
|
||||
|
||||
import com.woka.WokaApp.Companion.appDatabase
|
||||
import com.woka.database.dao.AdClickDao
|
||||
import com.woka.database.dao.ClicksDao
|
||||
import com.woka.database.models.ContentType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object AdClicksHelper {
|
||||
private val adClicksDao: AdClickDao? = appDatabase?.adClicksDao()
|
||||
|
||||
fun addImpression(adId: Int?, impressionCount: Int = 1){
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (adId != null){
|
||||
adClicksDao?.upsertClickEvent(
|
||||
adId,
|
||||
0,
|
||||
impressionCount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addClick(adId: Int?, clickCount: Int = 1){
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (adId != null){
|
||||
adClicksDao?.upsertClickEvent(
|
||||
adId,
|
||||
clickCount,
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,16 @@ private const val SYNC_BATCH_COUNT = 15
|
||||
|
||||
object RemoteSync {
|
||||
|
||||
private const val TAG = "aditya_RemoteSync"
|
||||
private const val CLICKS_TAG = "aditya_RemoteSync_clicks"
|
||||
private const val AD_CLICKS_TAG = "aditya_RemoteSync_ad_clicks"
|
||||
|
||||
private val clicksDao = appDatabase?.clicksDao()
|
||||
private val adClickDao = appDatabase?.adClicksDao()
|
||||
|
||||
private val apiService = RetrofitHelper.getRetrofit().create(RemoteApiService::class.java)
|
||||
|
||||
suspend fun syncClickEvents(){
|
||||
Log.d(TAG, "syncClickEvents: CLICK EVENTS SYNC CALLED")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: CLICK EVENTS SYNC CALLED")
|
||||
|
||||
var roundCount = 0
|
||||
|
||||
@@ -26,36 +29,77 @@ object RemoteSync {
|
||||
val clicksBatch = clicksDao?.getClickEventBatch(SYNC_BATCH_COUNT)
|
||||
|
||||
if (clicksDao == null || clicksBatch.isNullOrEmpty()){
|
||||
Log.d(TAG, "syncClickEvents: RECEIVED BATCH IS EMPTY")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: RECEIVED BATCH IS EMPTY")
|
||||
break
|
||||
}
|
||||
|
||||
Log.d(TAG, "syncClickEvents: BATCH COUNT FROM DATABASE ${clicksBatch.size}")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: BATCH COUNT FROM DATABASE ${clicksBatch.size}")
|
||||
when (val response = handleApiCall{ apiService.sendClickEvents(clicksBatch.map { RemoteClickEvent(it) })}){
|
||||
is ApiResult.Error -> {
|
||||
Log.e(TAG, "syncClickEvents: BATCH SYNC FAILED due to ${response.errorMessage}", response.error)
|
||||
Log.e(CLICKS_TAG, "syncClickEvents: BATCH SYNC FAILED due to ${response.errorMessage}", response.error)
|
||||
break
|
||||
}
|
||||
is ApiResult.Loading -> {}
|
||||
is ApiResult.Success -> {
|
||||
Log.d(TAG, "syncClickEvents: BATCH SYNC IS SUCCESSFUL")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: BATCH SYNC IS SUCCESSFUL")
|
||||
|
||||
Log.d(TAG, "syncClickEvents: DELETING SYNCED DATA FROM LOCAL DATABASE")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: DELETING SYNCED DATA FROM LOCAL DATABASE")
|
||||
val deleteCount = clicksDao.deleteClickEvents(clicksBatch)
|
||||
Log.d(TAG, "syncClickEvents: $deleteCount ENTRIES ARE DELETED FROM LOCAL DATABASE")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: $deleteCount ENTRIES ARE DELETED FROM LOCAL DATABASE")
|
||||
|
||||
if (deleteCount <= 0){
|
||||
Log.e(TAG, "syncClickEvents: NO ENTRIES WERE DELETED FROM LOCAL DATABASE")
|
||||
Log.e(CLICKS_TAG, "syncClickEvents: NO ENTRIES WERE DELETED FROM LOCAL DATABASE")
|
||||
}
|
||||
|
||||
roundCount++
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "syncClickEvents: \n")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: \n")
|
||||
}
|
||||
|
||||
Log.d(TAG, "syncClickEvents: NUMBER OF ROUND : $roundCount")
|
||||
Log.d(CLICKS_TAG, "syncClickEvents: NUMBER OF ROUND : $roundCount")
|
||||
}
|
||||
|
||||
suspend fun syncAdClickEvents() {
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: AD CLICK EVENTS SYNC CALLED")
|
||||
|
||||
var roundCount = 0
|
||||
|
||||
while (true){
|
||||
val clicksBatch = adClickDao?.getAdClickEventBatch(SYNC_BATCH_COUNT)
|
||||
|
||||
if (adClickDao == null || clicksBatch.isNullOrEmpty()){
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: RECEIVED BATCH IS EMPTY")
|
||||
break
|
||||
}
|
||||
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: BATCH COUNT FROM DATABASE ${clicksBatch.size}")
|
||||
when (val response = handleApiCall{ apiService.updateAdsCount(clicksBatch)}){
|
||||
is ApiResult.Error -> {
|
||||
Log.e(AD_CLICKS_TAG, "syncClickEvents: BATCH SYNC FAILED due to ${response.errorMessage}", response.error)
|
||||
break
|
||||
}
|
||||
is ApiResult.Loading -> {}
|
||||
is ApiResult.Success -> {
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: BATCH SYNC IS SUCCESSFUL")
|
||||
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: DELETING SYNCED DATA FROM LOCAL DATABASE")
|
||||
val deleteCount = adClickDao.deleteAdClickEvents(clicksBatch)
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: $deleteCount ENTRIES ARE DELETED FROM LOCAL DATABASE")
|
||||
|
||||
if (deleteCount <= 0){
|
||||
Log.e(AD_CLICKS_TAG, "syncClickEvents: NO ENTRIES WERE DELETED FROM LOCAL DATABASE")
|
||||
}
|
||||
|
||||
roundCount++
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: \n")
|
||||
}
|
||||
|
||||
Log.d(AD_CLICKS_TAG, "syncClickEvents: NUMBER OF ROUND : $roundCount")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.woka.database.models.adclicks
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
|
||||
private const val DB_TABLE_NAME = "ad_click_events"
|
||||
|
||||
@Entity(tableName = DB_TABLE_NAME)
|
||||
data class AdClickEvent(
|
||||
@PrimaryKey
|
||||
val ad_id: Int,
|
||||
val no_of_click: Int?,
|
||||
val no_of_impression: Int?
|
||||
)
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.woka.database.remote
|
||||
|
||||
import com.woka.database.models.adclicks.AdClickEvent
|
||||
import com.woka.database.remote.models.RemoteClickEvent
|
||||
import com.woka.networking.ApiResponse
|
||||
import retrofit2.Response
|
||||
@@ -10,4 +11,7 @@ interface RemoteApiService {
|
||||
|
||||
@POST("v2/user_clicks")
|
||||
suspend fun sendClickEvents(@Body clickEventList: List<RemoteClickEvent>): Response<ApiResponse<Any>>
|
||||
|
||||
@POST("update_ad_count")
|
||||
suspend fun updateAdsCount(@Body adClickEvents: List<AdClickEvent>): Response<ApiResponse<Any>>
|
||||
}
|
||||
@@ -17,10 +17,14 @@ import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.bumptech.glide.Glide
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.audiobooks.views.AudioBooksActivity
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.FragmentHome1Binding
|
||||
@@ -40,9 +44,9 @@ import com.woka.utils.changeLocale
|
||||
import com.woka.utils.hide
|
||||
import com.woka.utils.scaleAnimate
|
||||
import com.woka.utils.show
|
||||
import com.woka.utils.toast
|
||||
import com.woka.webseries.views.WebSeriesActivity
|
||||
import com.woka.wokagames.views.GamesActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class Home1Fragment : Fragment() {
|
||||
@@ -62,6 +66,7 @@ class Home1Fragment : Fragment() {
|
||||
private lateinit var progressView: ProgressView
|
||||
|
||||
private val clickHelper = ClicksHelper
|
||||
private val adClickHelper = AdClicksHelper
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
@@ -88,6 +93,8 @@ class Home1Fragment : Fragment() {
|
||||
|
||||
clickEvents()
|
||||
|
||||
loadAds()
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@@ -219,12 +226,6 @@ class Home1Fragment : Fragment() {
|
||||
liveTv.performClick()
|
||||
}
|
||||
|
||||
adView.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com/"))
|
||||
)
|
||||
}
|
||||
|
||||
more.setOnClickListener {
|
||||
activity?.let {
|
||||
startActivity(
|
||||
@@ -522,6 +523,36 @@ class Home1Fragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAds(){
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let {ads ->
|
||||
val homeAds = ads.filter { it.for_page == ForPage.THEME_1.value }
|
||||
|
||||
if (homeAds.isNotEmpty()){
|
||||
val adDetails = homeAds.first()
|
||||
|
||||
adClickHelper.addImpression(adDetails.id)
|
||||
|
||||
adDetails.banner_image?.let {url ->
|
||||
binding.imgAd.loadImage(url)
|
||||
binding.adView.show()
|
||||
}
|
||||
|
||||
adDetails.ad_link?.let {url ->
|
||||
binding.adView.setOnClickListener {
|
||||
|
||||
adClickHelper.addClick(adDetails.id)
|
||||
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getInstance() = Home1Fragment()
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ class HomeViewModel : ViewModel() {
|
||||
viewModelScope.launch {
|
||||
_logoutLiveData.postValue(ApiResult.Loading())
|
||||
RemoteSync.syncClickEvents()
|
||||
RemoteSync.syncAdClickEvents()
|
||||
_logoutLiveData.postValue(UserRepository.logout())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.net.Network
|
||||
import android.net.NetworkRequest
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
@@ -165,7 +166,7 @@ class HomeActivity : WokaBaseActivity(),
|
||||
decisionDialog.setPositiveButton(getString(R.string.yes)){
|
||||
lifecycleScope.launch {
|
||||
RemoteSync.syncClickEvents()
|
||||
|
||||
RemoteSync.syncAdClickEvents()
|
||||
@Suppress("DEPRECATION")
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.InsetDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.WindowManager
|
||||
@@ -15,10 +16,15 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.ActivityKaraokeBinding
|
||||
@@ -41,6 +47,7 @@ import com.woka.utils.setVisibility
|
||||
import com.woka.utils.shareWokaApp
|
||||
import com.woka.utils.show
|
||||
import com.woka.utils.toast
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
@@ -62,6 +69,8 @@ class KaraokeActivity : WokaBaseActivity() {
|
||||
|
||||
private lateinit var playerLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
private var adLoaded = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityKaraokeBinding.inflate(layoutInflater)
|
||||
@@ -103,6 +112,8 @@ class KaraokeActivity : WokaBaseActivity() {
|
||||
|
||||
setObservers()
|
||||
|
||||
loadAds()
|
||||
|
||||
if (!viewModel.karaokeLiveData.isInitialized) {
|
||||
viewModel.loadKaraokeSongs()
|
||||
}
|
||||
@@ -192,6 +203,8 @@ class KaraokeActivity : WokaBaseActivity() {
|
||||
}
|
||||
|
||||
private fun loadTrailerData(karaokeData: KaraokeData) {
|
||||
if (adLoaded) return
|
||||
|
||||
binding.apply {
|
||||
trailerView.show()
|
||||
adjustTrailerImage()
|
||||
@@ -542,4 +555,45 @@ class KaraokeActivity : WokaBaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAds(){
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let { ads ->
|
||||
val theme1ads = ads.filter { it.for_page == ForPage.KARAOKE.value}
|
||||
|
||||
if (theme1ads.isNotEmpty()){
|
||||
val adDetails = theme1ads.first()
|
||||
|
||||
AdClicksHelper.addImpression(adDetails.id)
|
||||
|
||||
adLoaded = true
|
||||
|
||||
binding.trailerBtn.hide()
|
||||
binding.trailerName.hide()
|
||||
|
||||
binding.adButtonView.show()
|
||||
|
||||
binding.trailerView.show()
|
||||
adjustTrailerImage()
|
||||
|
||||
adDetails.banner_image?.let {url ->
|
||||
binding.trailerImage.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.button_image?.let {url ->
|
||||
binding.adButtonImg.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.ad_link?.let {url ->
|
||||
binding.adBtn.setOnClickListener {
|
||||
AdClicksHelper.addClick(adDetails.id)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
package com.woka.shop.views.fragments.shop
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.woka.R
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.FragmentShop1Binding
|
||||
@@ -17,6 +23,7 @@ import com.woka.shop.models.BaseCategory
|
||||
import com.woka.shop.viewmodels.ShopViewModel
|
||||
import com.woka.utils.hide
|
||||
import com.woka.utils.show
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ShopFragment1 : Fragment() {
|
||||
|
||||
@@ -24,6 +31,9 @@ class ShopFragment1 : Fragment() {
|
||||
private lateinit var viewModel: ShopViewModel
|
||||
private lateinit var adapter: CategoryAdapter
|
||||
|
||||
private var adId: Int? = null
|
||||
private var adLink: String? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -67,9 +77,25 @@ class ShopFragment1 : Fragment() {
|
||||
ClicksHelper.upsertClickEvent(ContentType.OTHERS)
|
||||
}
|
||||
|
||||
adapter.onCategoryClickListener = {id, _ ->
|
||||
findNavController().navigate(ShopFragment1Directions.actionShopFragment1ToShopFragment2(id))
|
||||
ClicksHelper.upsertClickEvent(ContentType.SHOP_PRODUCT, id)
|
||||
adapter.onCategoryClickListener = { id, _ ->
|
||||
if (id == -1){
|
||||
// ad clicked
|
||||
AdClicksHelper.addClick(adId)
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(adLink)
|
||||
)
|
||||
)
|
||||
}else{
|
||||
// normal click
|
||||
findNavController().navigate(
|
||||
ShopFragment1Directions.actionShopFragment1ToShopFragment2(
|
||||
id
|
||||
)
|
||||
)
|
||||
ClicksHelper.upsertClickEvent(ContentType.SHOP_PRODUCT, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,16 +118,19 @@ class ShopFragment1 : Fragment() {
|
||||
|
||||
is ApiResult.Success -> {
|
||||
it.data?.let { categoryList ->
|
||||
adapter.submitList(categoryList.map { category ->
|
||||
val baseCategoryList = categoryList.map { category ->
|
||||
BaseCategory(
|
||||
category.id,
|
||||
category.super_category_thumbnail,
|
||||
category.super_category_name
|
||||
)
|
||||
}
|
||||
) {
|
||||
}.toMutableList()
|
||||
|
||||
adapter.submitList(baseCategoryList) {
|
||||
rvSuperCategory.show()
|
||||
|
||||
loadAds(baseCategoryList)
|
||||
|
||||
shimmer.hide()
|
||||
errorView.hide()
|
||||
}
|
||||
@@ -112,8 +141,23 @@ class ShopFragment1 : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance() = ShopFragment1()
|
||||
private fun loadAds(categoryList: MutableList<BaseCategory>) {
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let { ads ->
|
||||
val superShopAds = ads.filter { it.for_page == ForPage.SHOP_SUPER_CATEGORY.value }
|
||||
|
||||
if (superShopAds.isNotEmpty()) {
|
||||
val adDetails = superShopAds.first()
|
||||
|
||||
AdClicksHelper.addImpression(adDetails.id)
|
||||
adId = adDetails.id
|
||||
|
||||
categoryList.add(0, BaseCategory(-1, adDetails.banner_image, adDetails.title))
|
||||
adLink = adDetails.ad_link
|
||||
|
||||
adapter.notifyItemInserted(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,17 @@ import android.content.SharedPreferences
|
||||
import android.provider.Settings.Secure
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.woka.R
|
||||
import com.woka.home.models.Theme
|
||||
import com.woka.home.mylist.MyListRepository
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.onboard.views.OnboardActivity
|
||||
import com.woka.shop.ShopRepository
|
||||
import com.woka.userdata.UserRepository
|
||||
import com.woka.userdata.userDataModels.UserData
|
||||
import com.woka.userdata.userDataModels.UserDataResponse
|
||||
import com.woka.utils.DecisionDialog
|
||||
import com.woka.utils.SessionExpiredActivity
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -108,8 +112,8 @@ class UserPreference(val context: Context) {
|
||||
_userLiveData.postValue(null)
|
||||
|
||||
if (openLoginScreen){
|
||||
context.startActivity(Intent(context, OnboardActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
context.startActivity(Intent(context, SessionExpiredActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -118,5 +122,6 @@ class UserPreference(val context: Context) {
|
||||
|
||||
private fun clearData(){
|
||||
MyListRepository.clearData()
|
||||
ShopRepository.clearCart()
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,6 @@ class AdiImageView: FrameLayout {
|
||||
private var progressView: ProgressBar? = null
|
||||
private var cardView: CardView? = null
|
||||
|
||||
// variables
|
||||
var onLoadSuccessListener: (() -> Unit)? = null
|
||||
|
||||
constructor(context: Context?) : super(context!!)
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(
|
||||
context!!, attrs
|
||||
@@ -69,7 +66,7 @@ class AdiImageView: FrameLayout {
|
||||
|
||||
}
|
||||
|
||||
fun loadImage(url: String?) {
|
||||
fun loadImage(url: String?, successListener: (() -> Unit)? = null) {
|
||||
imageView?.let {
|
||||
|
||||
progressView?.show()
|
||||
@@ -96,7 +93,7 @@ class AdiImageView: FrameLayout {
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
progressView?.hide()
|
||||
onLoadSuccessListener?.invoke()
|
||||
successListener?.invoke()
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -83,6 +83,10 @@ class DecisionDialog(context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun setCancelable(cancelable: Boolean){
|
||||
dialog.setCancelable(cancelable)
|
||||
}
|
||||
|
||||
fun show(titleTxt: String, messageTxt: String): DecisionDialog{
|
||||
binding.apply {
|
||||
title.text = titleTxt
|
||||
|
||||
36
app/src/main/java/com/woka/utils/SessionExpiredActivity.kt
Normal file
36
app/src/main/java/com/woka/utils/SessionExpiredActivity.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.woka.utils
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.woka.R
|
||||
import com.woka.onboard.views.OnboardActivity
|
||||
|
||||
class SessionExpiredActivity : WokaBaseActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_session_expired)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
val decisionDialog = DecisionDialog(this)
|
||||
decisionDialog.setCancelable(false)
|
||||
|
||||
decisionDialog.setPositiveButton(getString(R.string.login)){
|
||||
startActivity(Intent(this, OnboardActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
})
|
||||
}
|
||||
|
||||
decisionDialog.show(getString(R.string.session_expired), getString(R.string.please_login_again))
|
||||
|
||||
onBackPressedDispatcher.addCallback{}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.InsetDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.LayoutInflater
|
||||
@@ -17,12 +18,17 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.jwplayer.pub.api.media.playlists.PlaylistItem
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.DialogContinueEpisodeBinding
|
||||
@@ -45,6 +51,7 @@ import com.woka.webseries.adapters.WebSeriesShowAdapter
|
||||
import com.woka.webseries.models.ContinueEpisodeData
|
||||
import com.woka.webseries.models.ShowData
|
||||
import com.woka.webseries.viewmodel.WebSeriesViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class WebSeriesFragment : Fragment() {
|
||||
|
||||
@@ -103,6 +110,8 @@ class WebSeriesFragment : Fragment() {
|
||||
|
||||
setObservers()
|
||||
|
||||
loadAds()
|
||||
|
||||
if (!viewModel.showCategoryLiveData.isInitialized) {
|
||||
viewModel.loadCategories()
|
||||
}
|
||||
@@ -379,6 +388,44 @@ class WebSeriesFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAds(){
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let { ads ->
|
||||
val theme1ads = ads.filter { it.for_page == ForPage.WEB_SERIES.value}
|
||||
|
||||
if (theme1ads.isNotEmpty()){
|
||||
val adDetails = theme1ads.first()
|
||||
|
||||
AdClicksHelper.addImpression(adDetails.id)
|
||||
|
||||
binding.trailerBtn.hide()
|
||||
binding.trailerTxt.hide()
|
||||
|
||||
binding.adButtonView.show()
|
||||
|
||||
adDetails.banner_image?.let {url ->
|
||||
Glide.with(binding.masilaImage)
|
||||
.load(url)
|
||||
.into(binding.masilaImage)
|
||||
}
|
||||
|
||||
adDetails.button_image?.let {url ->
|
||||
binding.adButtonImg.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.ad_link?.let {url ->
|
||||
binding.adBtn.setOnClickListener {
|
||||
AdClicksHelper.addClick(adDetails.id)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onShowClicked(showData: ShowData, categoryId: String) {
|
||||
findNavController().navigate(
|
||||
WebSeriesFragmentDirections.actionWebSeriesFragment2ToWebShowFragment(
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.InsetDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.WindowManager
|
||||
@@ -13,10 +14,14 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.woka.R
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import com.woka.advertisements.AdsRepository
|
||||
import com.woka.advertisements.models.ForPage
|
||||
import com.woka.database.helpers.AdClicksHelper
|
||||
import com.woka.database.helpers.ClicksHelper
|
||||
import com.woka.database.models.ContentType
|
||||
import com.woka.databinding.ActivityGamesBinding
|
||||
@@ -38,6 +43,7 @@ import com.woka.wokagames.playerr.GamePlayerActivity
|
||||
import com.woka.wokagames.playerr.GamePlayerActivity.Companion.EXTRA_GAME_PLAYER_DATA
|
||||
import com.woka.wokagames.playerr.GamePlayerData
|
||||
import com.woka.wokagames.viewmodels.GamesViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
@@ -55,6 +61,8 @@ class GamesActivity : WokaBaseActivity() {
|
||||
|
||||
private lateinit var noSignInDialog: NoSignInDialog
|
||||
|
||||
private var adLoaded = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityGamesBinding.inflate(layoutInflater)
|
||||
@@ -90,6 +98,8 @@ class GamesActivity : WokaBaseActivity() {
|
||||
|
||||
setObservers()
|
||||
|
||||
loadAds()
|
||||
|
||||
if (!viewModel.gamesLiveData.isInitialized){
|
||||
viewModel.loadGames()
|
||||
}
|
||||
@@ -170,6 +180,8 @@ class GamesActivity : WokaBaseActivity() {
|
||||
}
|
||||
|
||||
private fun loadTrailerData(gameData: GameData) {
|
||||
if (adLoaded) return
|
||||
|
||||
binding.apply {
|
||||
trailerView.show()
|
||||
adjustTrailerImage()
|
||||
@@ -432,4 +444,45 @@ class GamesActivity : WokaBaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAds(){
|
||||
lifecycleScope.launch {
|
||||
AdsRepository.getADs()?.let { ads ->
|
||||
val theme1ads = ads.filter { it.for_page == ForPage.GAMES.value}
|
||||
|
||||
if (theme1ads.isNotEmpty()){
|
||||
val adDetails = theme1ads.first()
|
||||
|
||||
AdClicksHelper.addImpression(adDetails.id)
|
||||
|
||||
adLoaded = true
|
||||
|
||||
binding.trailerBtn.hide()
|
||||
binding.trailerName.hide()
|
||||
|
||||
binding.adButtonView.show()
|
||||
|
||||
binding.trailerView.show()
|
||||
adjustTrailerImage()
|
||||
|
||||
adDetails.banner_image?.let {url ->
|
||||
binding.trailerImage.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.button_image?.let {url ->
|
||||
binding.adButtonImg.loadImage(url)
|
||||
}
|
||||
|
||||
adDetails.ad_link?.let {url ->
|
||||
binding.adBtn.setOnClickListener {
|
||||
AdClicksHelper.addClick(adDetails.id)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +202,31 @@
|
||||
|
||||
/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/ad_button_view"
|
||||
android:layout_width="@dimen/_135sdp"
|
||||
android:layout_height="@dimen/_45sdp"
|
||||
android:visibility="gone"
|
||||
app:cardBackgroundColor="@android:color/transparent"
|
||||
app:cardCornerRadius="@dimen/_25sdp">
|
||||
|
||||
<com.woka.utils.PressableCard
|
||||
android:id="@+id/ad_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:isHapticEnabled="true">
|
||||
|
||||
<com.woka.utils.AdiImageView
|
||||
android:id="@+id/ad_button_img"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
</com.woka.utils.PressableCard>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
@@ -202,6 +202,31 @@
|
||||
|
||||
/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/ad_button_view"
|
||||
android:layout_width="@dimen/_135sdp"
|
||||
android:layout_height="@dimen/_45sdp"
|
||||
android:visibility="gone"
|
||||
app:cardBackgroundColor="@android:color/transparent"
|
||||
app:cardCornerRadius="@dimen/_25sdp">
|
||||
|
||||
<com.woka.utils.PressableCard
|
||||
android:id="@+id/ad_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:isHapticEnabled="true">
|
||||
|
||||
<com.woka.utils.AdiImageView
|
||||
android:id="@+id/ad_button_img"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
</com.woka.utils.PressableCard>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
@@ -9,72 +9,66 @@
|
||||
android:orientation="vertical"
|
||||
tools:context=".webseries.views.WebSeriesActivity">
|
||||
|
||||
<include android:id="@+id/toolbar"
|
||||
layout="@layout/layout_toolbar"/>
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/layout_toolbar" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/shimmer"
|
||||
android:visibility="gone"
|
||||
android:background="@color/color_primary_dark"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_primary_dark"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:shimmer_auto_start="true"
|
||||
app:shimmer_duration="1500"
|
||||
app:shimmer_highlight_alpha="0.5"
|
||||
>
|
||||
app:shimmer_highlight_alpha="0.5">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="none">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_160sdp"
|
||||
android:background="@color/white_50"
|
||||
/>
|
||||
android:background="@color/white_50" />
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/_100sdp"
|
||||
android:layout_height="@dimen/_37sdp"
|
||||
android:background="@color/white_50"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
/>
|
||||
android:background="@color/white_50" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_140sdp"
|
||||
android:background="@color/white_50"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
/>
|
||||
android:background="@color/white_50" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_140sdp"
|
||||
android:background="@color/white_50"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
android:layout_marginTop="15dp"
|
||||
/>
|
||||
android:background="@color/white_50" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_140sdp"
|
||||
android:background="@color/white_50"
|
||||
android:layout_marginVertical="15dp"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
/>
|
||||
android:layout_marginVertical="15dp"
|
||||
android:background="@color/white_50" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -86,20 +80,19 @@
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/error_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_primary_dark"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
>
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/something_went_wrong"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:text="@string/something_went_wrong"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
|
||||
@@ -110,15 +103,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/retry"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
|
||||
android:paddingHorizontal="25dp"
|
||||
android:layout_marginTop="15dp"
|
||||
|
||||
android:background="@drawable/grad_btn_bg_4"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:paddingHorizontal="25dp"
|
||||
|
||||
android:text="@string/retry"
|
||||
android:textColor="@color/white"
|
||||
|
||||
android:textSize="@dimen/_14ssp"
|
||||
|
||||
/>
|
||||
|
||||
@@ -127,15 +120,13 @@
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_primary_dark"
|
||||
>
|
||||
android:background="@color/color_primary_dark">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/trailer_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
android:visibility="gone">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -146,42 +137,40 @@
|
||||
android:id="@+id/trailer_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_160sdp"
|
||||
android:contentDescription="@string/image"
|
||||
android:src="@drawable/img_masila_full"
|
||||
android:scaleType="fitXY"
|
||||
app:layout_collapseMode="parallax"
|
||||
android:layout_gravity="top"
|
||||
/>
|
||||
android:contentDescription="@string/image"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/img_masila_full"
|
||||
app:layout_collapseMode="parallax" />
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/top_pinned_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@color/color_primary_dark"
|
||||
app:layout_collapseMode="pin"
|
||||
app:contentInsetStart="0dp"
|
||||
app:contentInsetLeft="0dp"
|
||||
app:contentInsetStart="0dp"
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
android:layout_gravity="bottom">
|
||||
app:layout_collapseMode="pin">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="15dp"
|
||||
android:gravity="center"
|
||||
>
|
||||
android:orientation="vertical"
|
||||
android:padding="15dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/trailer_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
tools:text="@string/masila"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_16ssp"
|
||||
android:textAlignment="center"
|
||||
tools:text="@string/masila"
|
||||
|
||||
/>
|
||||
|
||||
@@ -190,18 +179,43 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/sing"
|
||||
android:layout_marginTop="15dp"
|
||||
android:background="@drawable/play_btn_bg"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:paddingHorizontal="25dp"
|
||||
|
||||
android:text="@string/sing"
|
||||
android:textColor="@color/white"
|
||||
|
||||
android:textSize="@dimen/_12ssp"
|
||||
|
||||
android:paddingHorizontal="25dp"
|
||||
android:layout_marginTop="15dp"
|
||||
|
||||
android:background="@drawable/play_btn_bg"
|
||||
|
||||
/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/ad_button_view"
|
||||
android:layout_width="@dimen/_135sdp"
|
||||
android:layout_height="@dimen/_45sdp"
|
||||
android:visibility="gone"
|
||||
app:cardBackgroundColor="@android:color/transparent"
|
||||
app:cardCornerRadius="@dimen/_25sdp">
|
||||
|
||||
<com.woka.utils.PressableCard
|
||||
android:id="@+id/ad_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:isHapticEnabled="true">
|
||||
|
||||
<com.woka.utils.AdiImageView
|
||||
android:id="@+id/ad_button_img"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
</com.woka.utils.PressableCard>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
@@ -223,91 +237,89 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/continue_sing_txt"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/sing_again"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
|
||||
android:layout_marginHorizontal="15dp"
|
||||
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:text="@string/sing_again"
|
||||
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
android:visibility="gone"
|
||||
|
||||
/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_continue_sing"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/continue_show_view_holder"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginStart="15dp"
|
||||
/>
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/continue_show_view_holder" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sing_txt"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/sing_along_and_dance"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
|
||||
android:layout_marginHorizontal="15dp"
|
||||
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:text="@string/sing_along_and_dance"
|
||||
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
android:visibility="gone"
|
||||
|
||||
/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_karaoke"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/show_view_holder"
|
||||
/>
|
||||
tools:listitem="@layout/show_view_holder" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/load_more_progress"
|
||||
android:visibility="gone"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="@color/white"
|
||||
|
||||
android:layout_gravity="center_horizontal"
|
||||
|
||||
android:layout_marginVertical="15dp"
|
||||
android:indeterminate="true"
|
||||
|
||||
android:indeterminateTint="@color/white"
|
||||
|
||||
android:visibility="gone"
|
||||
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/load_more_btn"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
|
||||
android:text="@string/load_more"
|
||||
android:layout_marginVertical="15dp"
|
||||
android:background="@drawable/round_25"
|
||||
android:backgroundTint="@color/night_status"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
|
||||
android:paddingHorizontal="25dp"
|
||||
android:text="@string/load_more"
|
||||
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_12ssp"
|
||||
|
||||
android:paddingHorizontal="25dp"
|
||||
android:layout_marginVertical="15dp"
|
||||
|
||||
android:background="@drawable/round_25"
|
||||
android:backgroundTint="@color/night_status"
|
||||
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:visibility="gone"
|
||||
|
||||
/>
|
||||
|
||||
|
||||
8
app/src/main/res/layout/activity_session_expired.xml
Normal file
8
app/src/main/res/layout/activity_session_expired.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".utils.SessionExpiredActivity"/>
|
||||
@@ -3,7 +3,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:layout_marginVertical="5dp"
|
||||
app:cardCornerRadius="5dp"
|
||||
@@ -14,7 +13,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.woka.utils.AdiImageView
|
||||
@@ -36,7 +35,9 @@
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
|
||||
android:layout_margin="10dp"
|
||||
android:visibility="visible"
|
||||
|
||||
android:layout_marginTop="10dp"
|
||||
|
||||
/>
|
||||
|
||||
|
||||
@@ -593,6 +593,7 @@
|
||||
|
||||
<com.woka.utils.PressableCard
|
||||
android:id="@+id/ad_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="@dimen/_70sdp"
|
||||
android:layout_height="@dimen/_70sdp"
|
||||
|
||||
@@ -605,13 +606,12 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
<com.woka.utils.AdiImageView
|
||||
android:id="@+id/img_ad"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:src="@drawable/img_ad_round_banner">
|
||||
|
||||
</ImageView>
|
||||
/>
|
||||
|
||||
</com.woka.utils.PressableCard>
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_160sdp"
|
||||
android:contentDescription="@string/image"
|
||||
android:src="@drawable/img_ad_banner_1"
|
||||
android:src="@drawable/img_masila_full"
|
||||
android:scaleType="fitXY"
|
||||
app:layout_collapseMode="parallax"
|
||||
android:layout_gravity="top"
|
||||
@@ -170,6 +170,7 @@
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/trailer_txt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -182,7 +183,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/trailer_btn"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -198,14 +199,32 @@
|
||||
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ad_button"
|
||||
android:visibility="visible"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/ad_button_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="@dimen/_135sdp"
|
||||
android:layout_height="@dimen/_45sdp"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:src="@drawable/img_ad_button"
|
||||
android:layout_marginTop="15dp"/>
|
||||
app:cardCornerRadius="@dimen/_25sdp"
|
||||
app:cardBackgroundColor="@android:color/transparent"
|
||||
>
|
||||
|
||||
<com.woka.utils.PressableCard
|
||||
android:id="@+id/ad_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:isHapticEnabled="true"
|
||||
>
|
||||
|
||||
<com.woka.utils.AdiImageView
|
||||
android:id="@+id/ad_button_img"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/advertisement"
|
||||
android:scaleType="fitXY"/>
|
||||
|
||||
</com.woka.utils.PressableCard>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:cardBackgroundColor="@android:color/transparent"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
|
||||
@@ -314,4 +314,6 @@
|
||||
<string name="blogs_all_caps">BLOGS</string>
|
||||
<string name="password_is_required">Password is required</string>
|
||||
<string name="advertisement">Advertisement</string>
|
||||
<string name="session_expired">Session Expired</string>
|
||||
<string name="please_login_again">Please login again.</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user