position 值 修改。
This commit is contained in:
parent
2b3b5f905f
commit
10b42951a8
|
|
@ -144,7 +144,7 @@ class SplashActivity : AppViewsEmptyViewModelActivity<ViewBinding>(), OnTabStyle
|
|||
if (AdConfigManager.shouldShowInterstitialAfterAppOpenFailure()) {
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
when (val interstitialResult = AdShowExt.showInterstitialAd(this@SplashActivity)) {
|
||||
when (val interstitialResult = AdShowExt.showInterstitialAd(this@SplashActivity, "kkkkkkkkkkkkkkkkkkkkkk")) {
|
||||
is AdResult.Success -> {
|
||||
delayAndJumpToMain(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ class HomeFragment : AppViewsFragment<ViewBinding, UiState, ViewModel>(), OnSwit
|
|||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
when (val result = AdShowExt.showInterstitialAd(requireActivity())) {
|
||||
when (val result = AdShowExt.showInterstitialAd(requireActivity(), "kkkkkkkk")) {
|
||||
is AdResult.Success -> {
|
||||
callback.invoke()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class InterstitialAdController private constructor() {
|
|||
/**
|
||||
* 预加载广告
|
||||
*/
|
||||
suspend fun preloadAd(context: Context, adUnitId: String? = null): AdResult<Unit> {
|
||||
suspend fun preloadAd(context: Context, positionStr: String, adUnitId: String? = null): AdResult<Unit> {
|
||||
if(!GlobalAdSwitchInterceptor.isGlobalAdEnabled()){
|
||||
return AdResult.Failure(
|
||||
AdException(
|
||||
|
|
@ -116,13 +116,13 @@ class InterstitialAdController private constructor() {
|
|||
))
|
||||
}
|
||||
val finalAdUnitId = adUnitId ?: BuildConfig.ADMOB_INTERSTITIAL_ID
|
||||
return loadAdToCache(context, finalAdUnitId)
|
||||
return loadAdToCache(context, positionStr, finalAdUnitId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示广告
|
||||
*/
|
||||
suspend fun showAd(activity: Activity, adUnitId: String? = null,ignoreFullNative: Boolean = false): AdResult<Unit> {
|
||||
suspend fun showAd(activity: Activity, positionStr: String, adUnitId: String? = null,ignoreFullNative: Boolean = false): AdResult<Unit> {
|
||||
val finalAdUnitId = adUnitId ?: BuildConfig.ADMOB_INTERSTITIAL_ID
|
||||
|
||||
// 累积触发统计
|
||||
|
|
@ -133,7 +133,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_position",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalAdUnitId,
|
||||
"position" to activity::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalShowTriggerCount
|
||||
)
|
||||
)
|
||||
|
|
@ -149,7 +149,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalAdUnitId,
|
||||
"position" to activity::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to interceptResult.error.message
|
||||
)
|
||||
|
|
@ -179,7 +179,7 @@ class InterstitialAdController private constructor() {
|
|||
// 插页阻塞loading
|
||||
ADLoadingDialog.show(activity)
|
||||
AdLogger.d("Admob缓存为空,立即加载插页广告,广告位ID: %s", finalAdUnitId)
|
||||
loadAdToCache(activity, finalAdUnitId)
|
||||
loadAdToCache(activity, positionStr, finalAdUnitId)
|
||||
cachedAd = getCachedAd(finalAdUnitId)
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ class InterstitialAdController private constructor() {
|
|||
AdLogger.d("Admob使用缓存中的插页广告,广告位ID: %s", finalAdUnitId)
|
||||
|
||||
// 3. 显示广告
|
||||
val result = showAdInternal(activity, cachedAd.ad, finalAdUnitId)
|
||||
val result = showAdInternal(activity, positionStr, cachedAd.ad, finalAdUnitId)
|
||||
|
||||
result
|
||||
} else {
|
||||
|
|
@ -205,7 +205,7 @@ class InterstitialAdController private constructor() {
|
|||
/**
|
||||
* 基础广告加载方法(可复用)
|
||||
*/
|
||||
private suspend fun loadAd(context: Context, adUnitId: String): InterstitialAd? {
|
||||
private suspend fun loadAd(context: Context, positionStr: String, adUnitId: String): InterstitialAd? {
|
||||
// 累积加载次数统计
|
||||
totalLoadCount++
|
||||
AdLogger.d("Admob插页广告累积加载次数: $totalLoadCount")
|
||||
|
|
@ -251,7 +251,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_impression",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to context::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalShowCount,
|
||||
"ad_source" to (interstitialAd.responseInfo?.loadedAdapterResponseInfo?.adSourceName.orEmpty()),
|
||||
"value" to (currentAdValue?.let { it.valueMicros / 1_000_000.0 } ?: 0.0),
|
||||
|
|
@ -290,7 +290,7 @@ class InterstitialAdController private constructor() {
|
|||
/**
|
||||
* 加载广告到缓存
|
||||
*/
|
||||
suspend fun loadAdToCache(context: Context, adUnitId: String): AdResult<Unit> {
|
||||
suspend fun loadAdToCache(context: Context, positionStr: String, adUnitId: String): AdResult<Unit> {
|
||||
return try {
|
||||
|
||||
// 检查缓存是否已满
|
||||
|
|
@ -301,7 +301,7 @@ class InterstitialAdController private constructor() {
|
|||
}
|
||||
|
||||
// 加载广告
|
||||
val interstitialAd = loadAd(context, adUnitId)
|
||||
val interstitialAd = loadAd(context, positionStr, adUnitId)
|
||||
if (interstitialAd != null) {
|
||||
synchronized(adCachePool) {
|
||||
adCachePool.add(CachedInterstitialAd(interstitialAd, adUnitId))
|
||||
|
|
@ -361,7 +361,7 @@ class InterstitialAdController private constructor() {
|
|||
/**
|
||||
* 显示广告的内部实现
|
||||
*/
|
||||
private suspend fun showAdInternal(activity: Activity, interstitialAd: InterstitialAd, adUnitId: String): AdResult<Unit> {
|
||||
private suspend fun showAdInternal(activity: Activity, positionStr: String, interstitialAd: InterstitialAd, adUnitId: String): AdResult<Unit> {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
interstitialAd.fullScreenContentCallback = object : FullScreenContentCallback() {
|
||||
override fun onAdDismissedFullScreenContent() {
|
||||
|
|
@ -376,7 +376,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_close",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to activity::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalCloseCount,
|
||||
"ad_source" to (interstitialAd.responseInfo?.loadedAdapterResponseInfo?.adSourceName.orEmpty()),
|
||||
"value" to (currentAdValue?.let { it.valueMicros / 1_000_000.0 } ?: 0.0),
|
||||
|
|
@ -401,7 +401,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to activity::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"ad_source" to (interstitialAd.responseInfo?.loadedAdapterResponseInfo?.adSourceName.orEmpty()),
|
||||
"reason" to adError.message
|
||||
|
|
@ -433,7 +433,7 @@ class InterstitialAdController private constructor() {
|
|||
eventName = "ad_click",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to activity::class.java.simpleName,
|
||||
"position" to positionStr,
|
||||
"number" to totalClickCount,
|
||||
"ad_source" to (interstitialAd.responseInfo?.loadedAdapterResponseInfo?.adSourceName.orEmpty()),
|
||||
"value" to (currentAdValue?.let { it.valueMicros / 1_000_000.0 } ?: 0.0),
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ object InterstitialBiddingManager {
|
|||
|
||||
suspend fun bidding(
|
||||
activity: Activity,
|
||||
positionStr: String,
|
||||
admobAdUnitId: String = BuildConfig.ADMOB_INTERSTITIAL_ID,
|
||||
pangleAdUnitId: String = BuildConfig.PANGLE_INTERSTITIAL_ID,
|
||||
toponPlacementId: String = BuildConfig.TOPON_INTERSTITIAL_ID,
|
||||
|
|
@ -38,17 +39,18 @@ object InterstitialBiddingManager {
|
|||
AdSourceController.AdSource.TOPON -> BiddingWinner.TOPON
|
||||
AdSourceController.AdSource.BIDDING -> {
|
||||
// 不会执行到这里,但为了完整性保留
|
||||
performBidding(activity, admobAdUnitId, pangleAdUnitId, toponPlacementId)
|
||||
performBidding(activity, positionStr, admobAdUnitId, pangleAdUnitId, toponPlacementId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用竞价逻辑
|
||||
return performBidding(activity, admobAdUnitId, pangleAdUnitId, toponPlacementId)
|
||||
return performBidding(activity, positionStr, admobAdUnitId, pangleAdUnitId, toponPlacementId)
|
||||
}
|
||||
|
||||
private suspend fun performBidding(
|
||||
activity: Activity,
|
||||
positionStr: String,
|
||||
admobAdUnitId: String,
|
||||
pangleAdUnitId: String,
|
||||
toponPlacementId: String,
|
||||
|
|
@ -67,7 +69,7 @@ object InterstitialBiddingManager {
|
|||
val (admobLoadResult, pangleLoadResult, toponLoadResult) = coroutineScope {
|
||||
val admobDeferred = async {
|
||||
if (admobEnabled) {
|
||||
runCatching { admobController.loadAdToCache(context, admobAdUnitId) }.getOrNull()
|
||||
runCatching { admobController.loadAdToCache(context, positionStr, admobAdUnitId) }.getOrNull()
|
||||
} else null
|
||||
}
|
||||
val pangleDeferred = async {
|
||||
|
|
|
|||
|
|
@ -102,18 +102,19 @@ object AdShowExt {
|
|||
*/
|
||||
suspend fun showInterstitialAd(
|
||||
activity: Activity,
|
||||
positionStr: String = "defaultPosition",
|
||||
ignoreFullNative: Boolean = false
|
||||
): AdResult<Unit> {
|
||||
AdLogger.d("插页广告竞价开始")
|
||||
|
||||
val winner = InterstitialBiddingManager.bidding(activity)
|
||||
val winner = InterstitialBiddingManager.bidding(activity, positionStr)
|
||||
AdLogger.d("插页广告竞价结果: $winner")
|
||||
|
||||
return when (winner) {
|
||||
BiddingWinner.ADMOB -> {
|
||||
AdLogger.d("使用 AdMob 展示插页广告")
|
||||
InterstitialAdController.getInstance().showAd(
|
||||
activity,
|
||||
activity, positionStr,
|
||||
BuildConfig.ADMOB_INTERSTITIAL_ID,
|
||||
ignoreFullNative = ignoreFullNative
|
||||
)
|
||||
|
|
@ -121,7 +122,7 @@ object AdShowExt {
|
|||
BiddingWinner.PANGLE -> {
|
||||
AdLogger.d("使用 Pangle 展示插页广告")
|
||||
PangleInterstitialAdController.getInstance().showAd(
|
||||
activity,
|
||||
activity, positionStr,
|
||||
BuildConfig.PANGLE_INTERSTITIAL_ID,
|
||||
ignoreFullNative = ignoreFullNative
|
||||
)
|
||||
|
|
@ -129,7 +130,7 @@ object AdShowExt {
|
|||
BiddingWinner.TOPON -> {
|
||||
AdLogger.d("使用 TopOn 展示插页广告")
|
||||
TopOnInterstitialAdController.getInstance().showAd(
|
||||
activity,
|
||||
activity, positionStr,
|
||||
BuildConfig.TOPON_INTERSTITIAL_ID,
|
||||
ignoreFullNative = ignoreFullNative
|
||||
)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,8 @@ class PangleInterstitialAdController private constructor() {
|
|||
* @param ignoreFullNative 是否忽略全屏原生广告
|
||||
*/
|
||||
suspend fun showAd(
|
||||
activity: Activity,
|
||||
activity: Activity,
|
||||
positionStr: String,
|
||||
adUnitId: String? = null,
|
||||
ignoreFullNative: Boolean = false
|
||||
): AdResult<Unit> {
|
||||
|
|
@ -226,7 +227,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_position",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalAdUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowTriggerCount
|
||||
)
|
||||
)
|
||||
|
|
@ -242,7 +243,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalAdUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to interceptResult.error.message
|
||||
)
|
||||
|
|
@ -282,7 +283,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
AdLogger.d("显示Pangle插页广告,广告位ID: %s", finalAdUnitId)
|
||||
|
||||
// 2. 显示广告
|
||||
val result = showAdInternal(activity, ad, finalAdUnitId)
|
||||
val result = showAdInternal(activity, positionStr,ad, finalAdUnitId)
|
||||
|
||||
// 清空当前广告,Pangle SDK会自动加载下一个
|
||||
currentInterstitialAd = null
|
||||
|
|
@ -305,7 +306,8 @@ class PangleInterstitialAdController private constructor() {
|
|||
*/
|
||||
@Suppress("RedundantNullableInit")
|
||||
private suspend fun showAdInternal(
|
||||
activity: Activity,
|
||||
activity: Activity,
|
||||
positionStr: String,
|
||||
interstitialAd: PAGInterstitialAd,
|
||||
adUnitId: String
|
||||
): AdResult<Unit> {
|
||||
|
|
@ -341,7 +343,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_impression",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowCount,
|
||||
"ad_source" to (currentAdSource ?: "Pangle"),
|
||||
"value" to impressionValue,
|
||||
|
|
@ -388,7 +390,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_click",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalClickCount,
|
||||
"ad_source" to (currentAdSource ?: "Pangle"),
|
||||
"value" to revenueValue,
|
||||
|
|
@ -413,7 +415,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_close",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalCloseCount,
|
||||
"ad_source" to (currentAdSource ?: "Pangle"),
|
||||
"value" to revenueValue,
|
||||
|
|
@ -449,7 +451,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to error.errorMessage.orEmpty(),
|
||||
"ad_source" to (currentAdSource ?: "Pangle")
|
||||
|
|
@ -465,7 +467,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to "interstitial_not_ready",
|
||||
"ad_source" to (currentAdSource ?: "Pangle")
|
||||
|
|
@ -488,7 +490,7 @@ class PangleInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to adUnitId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to e.message.orEmpty(),
|
||||
"ad_source" to (currentAdSource ?: "Pangle")
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
/**
|
||||
* 预加载广告
|
||||
*/
|
||||
suspend fun preloadAd(context: Context, placementId: String? = null): AdResult<Unit> {
|
||||
suspend fun preloadAd(context: Context, positionStr: String, placementId: String? = null): AdResult<Unit> {
|
||||
if (!GlobalAdSwitchInterceptor.isGlobalAdEnabled()) {
|
||||
return AdResult.Failure(
|
||||
AdException(
|
||||
|
|
@ -120,7 +120,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
return AdResult.Success(Unit)
|
||||
}
|
||||
|
||||
return if (loadAd(context, finalPlacementId) != null) {
|
||||
return if (loadAd(context, positionStr, finalPlacementId) != null) {
|
||||
AdResult.Success(Unit)
|
||||
} else {
|
||||
AdResult.Failure(createAdException("广告加载失败"))
|
||||
|
|
@ -132,6 +132,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
*/
|
||||
suspend fun showAd(
|
||||
activity: Activity,
|
||||
positionStr: String,
|
||||
placementId: String? = null,
|
||||
ignoreFullNative: Boolean = false
|
||||
): AdResult<Unit> {
|
||||
|
|
@ -147,7 +148,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_position",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalPlacementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowTriggerCount
|
||||
)
|
||||
)
|
||||
|
|
@ -162,7 +163,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to finalPlacementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"reason" to interceptResult.error.message
|
||||
)
|
||||
|
|
@ -191,7 +192,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
|
||||
if (entry == null) {
|
||||
ADLoadingDialog.show(activity)
|
||||
loadAd(activity, finalPlacementId)
|
||||
loadAd(activity, positionStr, finalPlacementId)
|
||||
entry = synchronized(adCache) {
|
||||
adCache[finalPlacementId]?.takeUnless { it.isExpired() }
|
||||
}
|
||||
|
|
@ -216,7 +217,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
/**
|
||||
* 加载广告
|
||||
*/
|
||||
private suspend fun loadAd(context: Context, placementId: String): TopOnAdEntry? {
|
||||
private suspend fun loadAd(context: Context, positionStr: String, placementId: String): TopOnAdEntry? {
|
||||
totalLoadCount++
|
||||
AdLogger.d("TopOn插页广告开始加载,广告位ID: %s,当前累计加载次数: %d", placementId, totalLoadCount)
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
val applicationContext = context.applicationContext
|
||||
val interstitial = TUInterstitial(applicationContext, placementId)
|
||||
val listener = TopOnInterstitialListener(
|
||||
placementId = placementId,
|
||||
placementId = placementId, positionStr,
|
||||
startLoadTime = System.currentTimeMillis(),
|
||||
interstitial = interstitial,
|
||||
applicationContext = applicationContext
|
||||
|
|
@ -301,6 +302,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
*/
|
||||
private inner class TopOnInterstitialListener(
|
||||
private val placementId: String,
|
||||
private val positionStr: String,
|
||||
private val startLoadTime: Long,
|
||||
private val interstitial: TUInterstitial,
|
||||
private val applicationContext: Context
|
||||
|
|
@ -443,7 +445,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_click",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to placementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalClickCount,
|
||||
"ad_source" to (adInfo.networkName ?: ""),
|
||||
"value" to (adInfo.publisherRevenue ?: 0.0),
|
||||
|
|
@ -462,7 +464,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_close",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to placementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalCloseCount,
|
||||
"ad_source" to (adInfo.networkName ?: ""),
|
||||
"value" to (adInfo.publisherRevenue ?: 0.0),
|
||||
|
|
@ -496,7 +498,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_show_fail",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to placementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowFailCount,
|
||||
"ad_source" to (lastAdInfo?.networkName ?: ""),
|
||||
"reason" to (adError.desc ?: adError.getFullErrorInfo())
|
||||
|
|
@ -529,7 +531,7 @@ class TopOnInterstitialAdController private constructor() {
|
|||
eventName = "ad_impression",
|
||||
params = mapOf(
|
||||
"ad_unit_name" to placementId,
|
||||
"position" to PositionGet.get(),
|
||||
"position" to positionStr,
|
||||
"number" to totalShowCount,
|
||||
"ad_source" to (adInfo.networkName ?: ""),
|
||||
"value" to (adInfo.publisherRevenue ?: 0.0),
|
||||
|
|
|
|||
Loading…
Reference in New Issue