FIX: Don't render the connector when we shouldn't display an ad in the topic list item. (#146)

We expose the ad-slot logic to determine which ads are potentially available for each slot and don't render the connector when there are none. Leaking the component logic is not ideal, but I don't see a better solution given the
current design.
This commit is contained in:
Roman Rizzi 2022-07-12 16:13:18 -03:00 committed by GitHub
parent a4aa6332bb
commit d9b739f803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 148 additions and 100 deletions

View File

@ -2,6 +2,10 @@ import Component from "@ember/component";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import { alias, or } from "@ember/object/computed"; import { alias, or } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import {
isNthPost,
isNthTopicListItem,
} from "discourse/plugins/discourse-adplugin/discourse/helpers/slot-position";
export default Component.extend({ export default Component.extend({
router: service(), router: service(),
@ -93,20 +97,10 @@ export default Component.extend({
}, },
isNthPost(n) { isNthPost(n) {
if (n && n > 0) { return isNthPost(n, this.get("postNumber"));
return this.get("postNumber") % n === 0;
} else {
return false;
}
}, },
isNthTopicListItem(n) { isNthTopicListItem(n) {
let indexNumber = this.get("indexNumber"); return isNthTopicListItem(n, this.get("indexNumber"));
indexNumber = indexNumber + 1;
if (n && n > 0 && indexNumber > 0) {
return indexNumber % n === 0;
} else {
return false;
}
}, },
}); });

View File

@ -2,6 +2,10 @@ import EmberObject from "@ember/object";
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component"; import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
import discourseComputed, { observes } from "discourse-common/utils/decorators"; import discourseComputed, { observes } from "discourse-common/utils/decorators";
import { isBlank } from "@ember/utils"; import { isBlank } from "@ember/utils";
import {
isNthPost,
isNthTopicListItem,
} from "discourse/plugins/discourse-adplugin/discourse/helpers/slot-position";
const adConfig = EmberObject.create({ const adConfig = EmberObject.create({
"google-adsense": { "google-adsense": {
@ -66,18 +70,40 @@ const displayCounts = {
allAds: 0, allAds: 0,
}; };
export default AdComponent.extend({ function _isNetworkAvailable(siteSettings, enabledNetworkSettingName) {
needsUpdate: false, // False means there's no setting to enable or disable this ad network.
tagName: "", // Assume it's always enabled.
if (enabledNetworkSettingName === false) {
return true;
} else {
return (
enabledNetworkSettingName &&
!isBlank(siteSettings[enabledNetworkSettingName])
);
}
}
/** function _shouldPlaceAdInSlot(
* For a given ad placement and optionally a post number if in between posts, siteSettings,
* list all ad network names that are configured to show there. currentPostNumber,
*/ positionToPlace
@discourseComputed("placement", "postNumber", "indexNumber") ) {
availableAdTypes(placement, postNumber, indexNumber) { return (
!currentPostNumber ||
!positionToPlace ||
isNthPost(parseInt(siteSettings[positionToPlace], 10), currentPostNumber)
);
}
export function slotContenders(
site,
siteSettings,
placement,
postNumber,
indexNumber
) {
let types = []; let types = [];
const houseAds = this.site.get("house_creatives"), const houseAds = site.get("house_creatives"),
placeUnderscored = placement.replace(/-/g, "_"); placeUnderscored = placement.replace(/-/g, "_");
if (houseAds && houseAds.settings) { if (houseAds && houseAds.settings) {
@ -92,15 +118,16 @@ export default AdComponent.extend({
const canBePlacedInBetweenTopics = const canBePlacedInBetweenTopics =
placeUnderscored === "topic_list_between" && placeUnderscored === "topic_list_between" &&
this.isNthTopicListItem( isNthTopicListItem(
parseInt(houseAds.settings.after_nth_topic, 10) parseInt(houseAds.settings.after_nth_topic, 10),
indexNumber
); );
if ( if (
adAvailable && adAvailable &&
(notPlacingBetweenTopics || (notPlacingBetweenTopics ||
this.isNthPost(parseInt(houseAds.settings.after_nth_post, 10)) || canBePlacedInBetweenTopics ||
canBePlacedInBetweenTopics) isNthPost(parseInt(houseAds.settings.after_nth_post, 10), postNumber))
) { ) {
types.push("house-ad"); types.push("house-ad");
} }
@ -112,10 +139,10 @@ export default AdComponent.extend({
name; name;
if ( if (
this._isNetworkAvailable(config.enabledSetting) && _isNetworkAvailable(siteSettings, config.enabledSetting) &&
this._shouldPlaceAdInSlot(postNumber, config.nthPost) _shouldPlaceAdInSlot(siteSettings, postNumber, config.nthPost)
) { ) {
if (this.site.mobileView) { if (site.mobileView) {
settingNames = config.mobile || config.desktop; settingNames = config.mobile || config.desktop;
} else { } else {
settingNames = config.desktop; settingNames = config.desktop;
@ -128,14 +155,14 @@ export default AdComponent.extend({
if (name === undefined) { if (name === undefined) {
// follows naming convention: prefix_(mobile_)_{placement}_code // follows naming convention: prefix_(mobile_)_{placement}_code
name = `${config.settingPrefix}_${ name = `${config.settingPrefix}_${
this.site.mobileView ? "mobile_" : "" site.mobileView ? "mobile_" : ""
}${placeUnderscored}_code`; }${placeUnderscored}_code`;
} }
if ( if (
name !== false && name !== false &&
this.siteSettings[name] !== false && siteSettings[name] !== false &&
!isBlank(this.siteSettings[name]) !isBlank(siteSettings[name])
) { ) {
types.push(adNetwork); types.push(adNetwork);
} }
@ -143,6 +170,25 @@ export default AdComponent.extend({
}); });
return types; return types;
}
export default AdComponent.extend({
needsUpdate: false,
tagName: "",
/**
* For a given ad placement and optionally a post number if in between posts,
* list all ad network names that are configured to show there.
*/
@discourseComputed("placement", "postNumber", "indexNumber")
availableAdTypes(placement, postNumber, indexNumber) {
return slotContenders(
this.site,
this.siteSettings,
placement,
postNumber,
indexNumber
);
}, },
/** /**
@ -205,25 +251,4 @@ export default AdComponent.extend({
return networkNames; return networkNames;
}, },
_isNetworkAvailable(enabledNetworkSettingName) {
// False means there's no setting to enable or disable this ad network.
// Assume it's always enabled.
if (enabledNetworkSettingName === false) {
return true;
} else {
return (
enabledNetworkSettingName &&
!isBlank(this.siteSettings[enabledNetworkSettingName])
);
}
},
_shouldPlaceAdInSlot(currentPostNumber, positionToPlace) {
return (
!currentPostNumber ||
!positionToPlace ||
this.isNthPost(parseInt(this.siteSettings[positionToPlace], 10))
);
},
}); });

View File

@ -0,0 +1,15 @@
export function isNthPost(every, currentPostNumber) {
if (every && every > 0) {
return currentPostNumber % every === 0;
} else {
return false;
}
}
export function isNthTopicListItem(every, currentIndexPosition) {
if (every && every > 0 && currentIndexPosition > 0) {
return (currentIndexPosition + 1) % every === 0;
} else {
return false;
}
}

View File

@ -0,0 +1,14 @@
import { slotContenders } from "discourse/plugins/discourse-adplugin/discourse/components/ad-slot";
export default {
shouldRender(args, component) {
return (
slotContenders(
component.site,
component.siteSettings,
"topic-list-between",
args.index
).length === 0
);
},
};