Compare commits
212
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cecd2db6ab | ||
|
|
165ecdefc5 | ||
|
|
c519b4bc92 | ||
|
|
dc48bea931 | ||
|
|
c73ac98748 | ||
|
|
ff6b767796 | ||
|
|
116795aff3 | ||
|
|
fd6ac11ee9 | ||
|
|
203eedb915 | ||
|
|
8ac32a06c3 | ||
|
|
f52ac0775f | ||
|
|
fa2ec23ebc | ||
|
|
f7d9d13de8 | ||
|
|
a647813ce7 | ||
|
|
a570a46ad2 | ||
|
|
3b50a509f2 | ||
|
|
4940d0ea19 | ||
|
|
d9b739f803 | ||
|
|
a4aa6332bb | ||
|
|
469771db1d | ||
|
|
5901a52dbc | ||
|
|
c27f5717e4 | ||
|
|
a514c7aee2 | ||
|
|
3f951116fa | ||
|
|
fb73dda584 | ||
|
|
b9ac5516bf | ||
|
|
e56197505f | ||
|
|
208b56b130 | ||
|
|
898de0c9c8 | ||
|
|
8ca041846a | ||
|
|
7e2a490b67 | ||
|
|
c788b7bf1f | ||
|
|
03ec825e8e | ||
|
|
912e68e587 | ||
|
|
9be37644d8 | ||
|
|
58085298f0 | ||
|
|
62a4eff705 | ||
|
|
0d8e33c661 | ||
|
|
713d2951e7 | ||
|
|
0983b26180 | ||
|
|
8c3f2b691f | ||
|
|
d5cf5776d9 | ||
|
|
55045bba3c | ||
|
|
f2171a51c3 | ||
|
|
a01058f041 | ||
|
|
1d47138cb7 | ||
|
|
d7c127cc48 | ||
|
|
f4247ab7d2 | ||
|
|
190aa503ce | ||
|
|
d74deaad20 | ||
|
|
c25c041f98 | ||
|
|
43189e0f56 | ||
|
|
a43a5d2edc | ||
|
|
1741deecfe | ||
|
|
8a3ca77a60 | ||
|
|
9e30a576da | ||
|
|
fbdff69540 | ||
|
|
c4e88ba82c | ||
|
|
7f90994154 | ||
|
|
a16ed5f0bf | ||
|
|
d3730993a6 | ||
|
|
4ac7779cc9 | ||
|
|
6438000ed4 | ||
|
|
1654937788 | ||
|
|
112fe8f4cb | ||
|
|
4bf6420b91 | ||
|
|
4131f8403a | ||
|
|
2390a9d1d9 | ||
|
|
7b912d9252 | ||
|
|
9adaef17cc | ||
|
|
9ad0133624 | ||
|
|
e692fdf64f | ||
|
|
059b04468a | ||
|
|
fb7f4e5766 | ||
|
|
12f15a0306 | ||
|
|
c66c651c5b | ||
|
|
a626b8e79d | ||
|
|
1f49cf94db | ||
|
|
15b2c1a05e | ||
|
|
22dfb3aa5e | ||
|
|
3a7e642ae3 | ||
|
|
87c1478743 | ||
|
|
30dad0281d | ||
|
|
88e2bab0d6 | ||
|
|
a36c34bedc | ||
|
|
5afca0aaa1 | ||
|
|
8439608f17 | ||
|
|
50788a876e | ||
|
|
501ad7878e | ||
|
|
20ebd91f8f | ||
|
|
b28039e86a | ||
|
|
914735767a | ||
|
|
db4f5f990d | ||
|
|
c27d5f8e85 | ||
|
|
1d073e2a96 | ||
|
|
0a23be6008 | ||
|
|
75fb2bf892 | ||
|
|
1e6e3bb3e9 | ||
|
|
06ea132309 | ||
|
|
24cb463ddb | ||
|
|
dd5fb1f785 | ||
|
|
3fc872520e | ||
|
|
3d0ee3f28a | ||
|
|
05967a8d52 | ||
|
|
cff1459dbc | ||
|
|
5273d52f28 | ||
|
|
4ded0bdba9 | ||
|
|
5b99fd5bbd | ||
|
|
ef316ab4ac | ||
|
|
f11382e224 | ||
|
|
f7582f0df8 | ||
|
|
270799166b | ||
|
|
cd82a905ae | ||
|
|
bec86bd59a | ||
|
|
f2ccce4beb | ||
|
|
af346fc1c2 | ||
|
|
63ae1672ad | ||
|
|
3fdd0f35f3 | ||
|
|
275921ac70 | ||
|
|
116f9dd238 | ||
|
|
cf27a7be64 | ||
|
|
db1bf99277 | ||
|
|
73aa618aef | ||
|
|
155d9f904c | ||
|
|
b59f841944 | ||
|
|
a3e3dbf24b | ||
|
|
0d534ce52a | ||
|
|
8d4df6df91 | ||
|
|
edc549b269 | ||
|
|
02f9145751 | ||
|
|
cc09403757 | ||
|
|
9a02cae641 | ||
|
|
6704238c94 | ||
|
|
51c1b89a62 | ||
|
|
19f0457e8c | ||
|
|
b500ea171f | ||
|
|
0612054da8 | ||
|
|
62888e734f | ||
|
|
2ad24e4a60 | ||
|
|
2ceb99e151 | ||
|
|
4991941d03 | ||
|
|
71c51ebd8b | ||
|
|
dee02ac3ba | ||
|
|
93af4587fa | ||
|
|
09a92f3438 | ||
|
|
3aa9cb8a0c | ||
|
|
e8295c600c | ||
|
|
1929ac405c | ||
|
|
333f6cef81 | ||
|
|
6f786b2f4d | ||
|
|
ad939a851a | ||
|
|
2ba276b0fb | ||
|
|
89200f3b99 | ||
|
|
3054f2539a | ||
|
|
8ab28f4fda | ||
|
|
25090a55a1 | ||
|
|
92609c7af4 | ||
|
|
ca345f273c | ||
|
|
d34b45627e | ||
|
|
31efc7025d | ||
|
|
574500ba08 | ||
|
|
203e14b639 | ||
|
|
8c3fe62e90 | ||
|
|
3a04f95916 | ||
|
|
0432256adb | ||
|
|
35c1af6648 | ||
|
|
04525d0cf1 | ||
|
|
7af8f1d46b | ||
|
|
f745ecfbdc | ||
|
|
ab9cf6459e | ||
|
|
546101a357 | ||
|
|
d3a5927ede | ||
|
|
2ca0adca05 | ||
|
|
896e5a9838 | ||
|
|
10ab104cd8 | ||
|
|
365f441924 | ||
|
|
4bd2035866 | ||
|
|
cdc14398ba | ||
|
|
d9d7f4c8f4 | ||
|
|
26d42e9ed7 | ||
|
|
171656304b | ||
|
|
1bd80e1afe | ||
|
|
5272995e74 | ||
|
|
369d5dfc9e | ||
|
|
b105da53e8 | ||
|
|
e6bcd96d8e | ||
|
|
50d258dc37 | ||
|
|
63e604d81b | ||
|
|
8ef02aa351 | ||
|
|
881a8e5d4c | ||
|
|
4fd7caffd6 | ||
|
|
6097e6f097 | ||
|
|
943acbfeb1 | ||
|
|
8f2e4c5a49 | ||
|
|
147b1350ea | ||
|
|
23ece34f53 | ||
|
|
7ee19d79c3 | ||
|
|
a1649f7cce | ||
|
|
79a4c228a6 | ||
|
|
608feb2e54 | ||
|
|
40c0af2177 | ||
|
|
0980914d0c | ||
|
|
c5272db7f3 | ||
|
|
4516dbca26 | ||
|
|
cd35666059 | ||
|
|
8fda5c3b7d | ||
|
|
2065b8bd41 | ||
|
|
ec10ef4483 | ||
|
|
3f70312c84 | ||
|
|
9b7a8830b8 | ||
|
|
9a695cc67d | ||
|
|
ccad3ca226 |
@@ -1,105 +1,3 @@
|
||||
{
|
||||
"env": {
|
||||
"jasmine": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"browser": true,
|
||||
"builtin": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 7,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"globals":
|
||||
{"Ember":true,
|
||||
"jQuery":true,
|
||||
"$":true,
|
||||
"RSVP":true,
|
||||
"Discourse":true,
|
||||
"Em":true,
|
||||
"PreloadStore":true,
|
||||
"Handlebars":true,
|
||||
"I18n":true,
|
||||
"bootbox":true,
|
||||
"module":true,
|
||||
"moduleFor":true,
|
||||
"moduleForComponent":true,
|
||||
"Pretender":true,
|
||||
"sandbox":true,
|
||||
"controllerFor":true,
|
||||
"test":true,
|
||||
"ok":true,
|
||||
"not":true,
|
||||
"expect":true,
|
||||
"equal":true,
|
||||
"visit":true,
|
||||
"andThen":true,
|
||||
"click":true,
|
||||
"currentPath":true,
|
||||
"currentRouteName":true,
|
||||
"currentURL":true,
|
||||
"fillIn":true,
|
||||
"keyEvent":true,
|
||||
"triggerEvent":true,
|
||||
"count":true,
|
||||
"exists":true,
|
||||
"visible":true,
|
||||
"invisible":true,
|
||||
"asyncRender":true,
|
||||
"selectDropdown":true,
|
||||
"asyncTestDiscourse":true,
|
||||
"fixture":true,
|
||||
"find":true,
|
||||
"sinon":true,
|
||||
"moment":true,
|
||||
"start":true,
|
||||
"_":true,
|
||||
"alert":true,
|
||||
"containsInstance":true,
|
||||
"deepEqual":true,
|
||||
"notEqual":true,
|
||||
"define":true,
|
||||
"require":true,
|
||||
"requirejs":true,
|
||||
"hasModule":true,
|
||||
"Blob":true,
|
||||
"File":true},
|
||||
"rules": {
|
||||
"block-scoped-var": 2,
|
||||
"dot-notation": 0,
|
||||
"eqeqeq": [
|
||||
2,
|
||||
"allow-null"
|
||||
],
|
||||
"guard-for-in": 2,
|
||||
"no-bitwise": 2,
|
||||
"no-caller": 2,
|
||||
"no-cond-assign": 0,
|
||||
"no-debugger": 2,
|
||||
"no-empty": 0,
|
||||
"no-eval": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-loop-func": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-new": 2,
|
||||
"no-plusplus": 0,
|
||||
"no-proto": 2,
|
||||
"no-script-url": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 2,
|
||||
"no-undef": 2,
|
||||
"no-unused-vars": 2,
|
||||
"no-with": 2,
|
||||
"semi": 2,
|
||||
"strict": 0,
|
||||
"valid-typeof": 2,
|
||||
"wrap-iife": [
|
||||
2,
|
||||
"inside"
|
||||
]
|
||||
},
|
||||
"parser": "babel-eslint"
|
||||
"extends": "eslint-config-discourse"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
name: Discourse Plugin
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1
|
||||
+3
-2
@@ -2,7 +2,8 @@
|
||||
log/*.log
|
||||
pkg/
|
||||
auto_generated
|
||||
Gemfile.lock
|
||||
.DS_Store
|
||||
*.swp
|
||||
.rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml
|
||||
node_modules
|
||||
yarn-error.log
|
||||
.rubocop-https---raw-githubusercontent-com-discourse-*
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
inherit_from: https://raw.githubusercontent.com/discourse/discourse/master/.rubocop.yml
|
||||
inherit_gem:
|
||||
rubocop-discourse: stree-compat.yml
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
plugins: ["ember-template-lint-plugin-discourse"],
|
||||
extends: "discourse:recommended",
|
||||
};
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = el_GR: el, es_ES: es, fr_FR: fr, hu_HU: hu, ko_KR: ko, pt_PT: pt, sk_SK: sk, vi_VN: vi
|
||||
|
||||
[discourse-org.discourse-adpluginclientenyml]
|
||||
file_filter = config/locales/client.<lang>.yml
|
||||
source_file = config/locales/client.en.yml
|
||||
source_lang = en
|
||||
type = YML
|
||||
|
||||
[discourse-org.discourse-adpluginserverenyml]
|
||||
file_filter = config/locales/server.<lang>.yml
|
||||
source_file = config/locales/server.en.yml
|
||||
source_lang = en
|
||||
type = YML
|
||||
@@ -1,5 +1,8 @@
|
||||
source 'https://rubygems.org'
|
||||
# frozen_string_literal: true
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
group :development do
|
||||
gem 'translations-manager', git: 'https://github.com/discourse/translations-manager.git'
|
||||
gem "rubocop-discourse"
|
||||
gem "syntax_tree"
|
||||
end
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ast (2.4.2)
|
||||
json (2.6.2)
|
||||
parallel (1.22.1)
|
||||
parser (3.1.2.1)
|
||||
ast (~> 2.4.1)
|
||||
prettier_print (1.2.0)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.6.0)
|
||||
rexml (3.2.5)
|
||||
rubocop (1.36.0)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.1.2.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.20.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.21.0)
|
||||
parser (>= 3.1.1.0)
|
||||
rubocop-discourse (3.0)
|
||||
rubocop (>= 1.1.0)
|
||||
rubocop-rspec (>= 2.0.0)
|
||||
rubocop-rspec (2.13.2)
|
||||
rubocop (~> 1.33)
|
||||
ruby-progressbar (1.11.0)
|
||||
syntax_tree (5.1.0)
|
||||
prettier_print (>= 1.2.0)
|
||||
unicode-display_width (2.3.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
rubocop-discourse
|
||||
syntax_tree
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2019 Discourse
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,17 +1,26 @@
|
||||
# Official Discourse Advertising Plugin
|
||||
|
||||
Official Plugin Topic & Documentation: https://meta.discourse.org/t/official-advertising-ad-plugin-for-discourse/33734
|
||||
|
||||
This is the official Discourse advertising plugin. It allows advertisements to be served by supported advertising platforms for users with a Discourse forum.
|
||||
|
||||
**Authors**: [Sarah Ni](https://github.com/cyberkoi) & [Vi Nguyen](https://github.com/ladydanger)
|
||||
**Version**: 1.0.1
|
||||
**Contributors**: See credits section below
|
||||
|
||||
**Version**: 1.2.5
|
||||
|
||||
**Contributors**: See [credits section](#credits) below
|
||||
|
||||
**License**: MIT License
|
||||
|
||||
**Supported Discourse Version**: 1.4
|
||||
|
||||
**Supported Ad Platforms**:
|
||||
* House Ads: Your own ads served from Discourse
|
||||
* [Google Adsense](http://www.google.com.au/adsense/start/why-adsense.html)
|
||||
* [Google Double Click for Publishers](https://www.google.com/dfp)
|
||||
* [Amazon Affiliates](http://affiliate-program.amazon.com) - Banner and Product Link Ads
|
||||
* [CodeFund](https://codefund.io) - Ethical Ad Platform for Developers
|
||||
* [Carbon Ads](https://www.carbonads.net/)
|
||||
* [AdButler](https://www.adbutler.com/)
|
||||
|
||||
|
||||
## Quick Start in 3 Steps
|
||||
@@ -27,7 +36,7 @@ For non-docker or local development installation (those with programming experie
|
||||
### Step 1 - Install the Official Discourse Advertising Plugin
|
||||
|
||||
|
||||
As seen in a [how-to on meta.discourse.org](https://meta.discourse.org/t/advanced-troubleshooting-with-docker/15927#Example:%20Install%20a%20plugin), simply **add the plugin's repository url to your container's app.yml file**:
|
||||
As seen in a [how-to on meta.discourse.org](https://meta.discourse.org/t/install-plugins-in-discourse/19157), simply **add the plugin's repository url to your container's app.yml file**:
|
||||
|
||||
```yml
|
||||
hooks:
|
||||
@@ -50,6 +59,18 @@ git pull
|
||||
|
||||
There are 2 easy steps for configuring your Discourse settings to enable advertisements to display in your Discourse forum.
|
||||
|
||||
#### House Ads
|
||||
|
||||
If you don't want to use an external ad platform, but want to show your own ads, then House Ads are for you!
|
||||
Define your ads by going to the Admin section of your Discourse forum, and go to the Plugins section.
|
||||
On the left, you should see a link called "House Ads".
|
||||
|
||||
Begin by creating your ads. Give each a short descriptive name and enter the html for each.
|
||||
Style them using a custom theme (Admin > Customize > Themes).
|
||||
Lastly, click the Settings button in the House Ads UI and choose which of your ads to show in each of
|
||||
the ad slots. The ads will start showing as soon as you add them to slots.
|
||||
|
||||
|
||||
#### Step 2(a) - Choose Your Advertisement Platform
|
||||
|
||||
<ul>
|
||||
@@ -57,9 +78,11 @@ There are 2 easy steps for configuring your Discourse settings to enable adverti
|
||||
<li>Click on Settings and a left vertical navigation bar should appear.</li>
|
||||
<li>Choose your advertisement platform.</li>
|
||||
<ul>
|
||||
<li>House Ads - if you want to create and serve ads from your Discourse instance.</li>
|
||||
<li>Adsense - if using Adsense as your advertisement platform.</li>
|
||||
<li>DFP - if using the DoubleClick for Publishers advertisement platform.</li>
|
||||
<li>CodeFund - if using the CodeFund ethical advertisement platform.</li>
|
||||
<li>Carbon Ads - if using the Carbon Ads advertisement platform.</li>
|
||||
<li>AdButler - if using the AdButler advertisement platform.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@@ -73,20 +96,49 @@ There are 2 easy steps for configuring your Discourse settings to enable adverti
|
||||
|
||||
##### Adsense Advertisement Tag to Discourse's Site Settings
|
||||
|
||||

|
||||

|
||||
|
||||
##### DoubleClick for Publishers' Advertisement Tag to Discourse's Site Settings
|
||||
|
||||

|
||||

|
||||
|
||||
##### Amazon Affiliates' Advertisement Tag to Discourse's Site Settings
|
||||
Only for Product Link and Banner Ads.
|
||||
|
||||

|
||||

|
||||
|
||||
##### CodeFund Embed Tag to Discourse's Site Settings
|
||||
##### Carbon Ads Script Tag to Discourse's Site Settings
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### AdButler Ads Zone URL to Discourse's Site Settings
|
||||
|
||||
This plugin only support AdButler "Standard Zones". Text and VAST are not supported.
|
||||
|
||||
If you browse to a zone in the AdButler admin, then you can find the Publisher ID (PPPPPP) and the Zone ID (ZZZZZZ) in the URL of your browser's address bar:
|
||||
|
||||
`https://admin.adbutler.com/?ID=PPPPPP&p=textadzone.view&zoneID=ZZZZZZ`
|
||||
|
||||
Configure the ads in Admin > Settings > AdButler.
|
||||
Enter the publisher id in the "adbutler publisher id" setting, and enter the Zone IDs in the different
|
||||
zone id settings as desired.
|
||||
|
||||
By default, ads are assumed to be size 728 x 90, or 320 x 50 in mobile view.
|
||||
To use different size ads, customize using CSS in your site's theme. Override the following CSS:
|
||||
|
||||
```css
|
||||
.adbutler-ad {
|
||||
width: 728px;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.adbutler-mobile-ad {
|
||||
width: 320px;
|
||||
height: 50px;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3 - See Your Ad
|
||||
|
||||
@@ -97,9 +149,11 @@ Once you've configured your settings and your advertising platform has ads that
|
||||
|
||||
In this section, we go into more detail on:
|
||||
* Available Locations for Ad Display
|
||||
* Ad Sizes Supported
|
||||
* Trust Levels
|
||||
* Languages Supported
|
||||
* Personal messages
|
||||
* Groups
|
||||
* Categories
|
||||
* Tags
|
||||
|
||||
### Available Locations for Ad Display
|
||||
|
||||
@@ -112,26 +166,7 @@ The following are available locations along with a description and an image show
|
||||
| Topic Above Suggested | Ad will appear in the footer above suggested topics of all Discourse forum topics |
|
||||
| Post Bottom & Nth Post | Ad will appear on the stipulated nth post within a topic. So if you have 5 posts in a topic and you want the ad to display after on the 2nd post, put 2 in ```ad_platform_nth_post_code```. |
|
||||
|
||||
|
||||

|
||||
|
||||
### Advertisement Sizes Supported
|
||||
|
||||
This plugin supports the following ad sizes for the following locations.
|
||||
|
||||
All locations except post bottom | Post bottom location | Mobile
|
||||
--- | --- | ---
|
||||
728 x 90 | 728 x 90 | 320 x 50
|
||||
336 x 280 | 336 x 280 |
|
||||
300 x 250 | 300 x 250 |
|
||||
970 x 90 | 970 x 90 |
|
||||
468 x 60 | 468 x 60 |
|
||||
234 x 60 | 234 x 60 |
|
||||
125 x 125 | |
|
||||
180 x 150 | |
|
||||
200 x 200 | |
|
||||
250 x 250 | |
|
||||
|
||||

|
||||
|
||||
### Trust Levels
|
||||
|
||||
@@ -145,12 +180,21 @@ You can use the ```ad_platform_through_trust_level``` dropdown to disable ads fo
|
||||
|
||||
To find more about trust levels in Discourse, refer to [Discourse's posts on trust levels](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924)
|
||||
|
||||
### Languages Supported
|
||||
### Personal messages
|
||||
|
||||
* Chinese (Simplified)
|
||||
* English
|
||||
* French
|
||||
* Spanish
|
||||
By default, ads won't be shown in personal messages. To enable ads in personal messages, use the "no ads for personal messages" setting.
|
||||
|
||||
### Groups
|
||||
|
||||
To give some users an ad-free experience, put the users in groups and add those groups to the "no ads for groups" setting.
|
||||
|
||||
### Categories
|
||||
|
||||
To disable ads in certain categories, add them to the "no ads for categories" setting. Also consider using the "no ads for restricted categories" to disable ads in all categories that have read access restrictions.
|
||||
|
||||
### Tags
|
||||
|
||||
Individual topics can have ads disabled by using tags, and entering those tags in the "no ads for tags" setting. This is useful if some topics violate ad network policies.
|
||||
|
||||
## Other Installation
|
||||
|
||||
@@ -198,4 +242,4 @@ Open an Issue on this repository to start a chat.
|
||||
**Our Coaches**: Very special thank you to our coaches and honorary coach - [@georg](https://github.com/georg), [@betaass](https://github.com/betaass), [@adelsmee](https://github.com/adelsmee), [@davich](https://github.com/davich), [@link664](https://github.com/link664), [@tomjadams](https://github.com/tomjadams), [@compactcode](https://github.com/compactcode), [@joffotron](https://github.com/joffotron), [@jocranford](https://github.com/jocranford), [@saramic](https://github.com/saramic), [@madpilot](https://github.com/madpilot), [@catkins](https://github.com/catkins)
|
||||
|
||||
**Rails Girls**: Thanks [@sareg0](https://github.com/sareg0) and the Rails Girls Team for the opportunity to participate in Rails Girls Summer of Code 2015.
|
||||
<p>To create this plugin we referenced the <a href="https://github.com/discourse/discourse-google-dfp">original dfp plugin</a> (created by <a href="https://github.com/search?q=neil+lalonde&ref=opensearch&type=Users">nlalonde</a>) and the <a href="https://meta.discourse.org/t/google-adsense-plugin/11763/133">adsense plugin</a>.</p>
|
||||
<p>To create this plugin we referenced the <a href="https://github.com/discourse/discourse-google-dfp">original dfp plugin</a> (created by <a href="https://github.com/nlalonde">@nlalonde</a>) and the <a href="https://meta.discourse.org/t/google-adsense-plugin/11763/133">adsense plugin</a>.</p>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ::AdPlugin
|
||||
class HouseAdSettingsController < ::ApplicationController
|
||||
requires_plugin AdPlugin.plugin_name
|
||||
|
||||
def update
|
||||
HouseAdSetting.update(params[:id], params[:value])
|
||||
render json: success_json
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ::AdPlugin
|
||||
class HouseAdsController < ::ApplicationController
|
||||
requires_plugin AdPlugin.plugin_name
|
||||
|
||||
def index
|
||||
render_json_dump(house_ads: HouseAd.all.map(&:to_hash), settings: HouseAdSetting.all)
|
||||
end
|
||||
|
||||
def show
|
||||
render_json_dump(house_ad: HouseAd.find(params[:id])&.to_hash)
|
||||
end
|
||||
|
||||
def create
|
||||
ad = HouseAd.create(house_ad_params)
|
||||
ad.valid? ? render_json_dump(house_ad: ad.to_hash) : render_json_error(ad)
|
||||
end
|
||||
|
||||
def update
|
||||
if ad = HouseAd.find(house_ad_params[:id])
|
||||
ad.update(house_ad_params)
|
||||
else
|
||||
ad = HouseAd.create(house_ad_params.except(:id))
|
||||
end
|
||||
|
||||
ad.valid? ? render_json_dump(house_ad: ad.to_hash) : render_json_error(ad)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if ad = HouseAd.find(house_ad_params[:id])
|
||||
ad.destroy
|
||||
else
|
||||
render_json_error(I18n.t("not_found"), status: 404)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def house_ad_params
|
||||
params.permit(:id, :name, :html)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ::AdPlugin
|
||||
class HouseAd
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :id, :name, :html
|
||||
|
||||
NAME_REGEX = /\A[[:alnum:]\s\.,'!@#$%&\*\-\+\=:]*\z/i
|
||||
|
||||
validates :name, presence: true, format: { with: NAME_REGEX }
|
||||
validates :html, presence: true
|
||||
|
||||
validate do
|
||||
if self.class.all.any? { |ad| ad.id != self.id && ad.name.downcase == self.name.downcase }
|
||||
errors.add(:name, :taken) # unique name
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
@name = "New Ad"
|
||||
@html = "<div class='house-ad'>New Ad</div>"
|
||||
end
|
||||
|
||||
def self.from_hash(h)
|
||||
ad = self.new
|
||||
ad.name = h[:name]
|
||||
ad.html = h[:html]
|
||||
ad.id = h[:id].to_i if h[:id]
|
||||
ad
|
||||
end
|
||||
|
||||
def self.create(attrs)
|
||||
ad = from_hash(attrs)
|
||||
ad.save
|
||||
ad
|
||||
end
|
||||
|
||||
def self.alloc_id
|
||||
DistributedMutex.synchronize("adplugin-house-ad-id") do
|
||||
max_id = AdPlugin.pstore_get("ad:_id")
|
||||
max_id = 1 unless max_id
|
||||
AdPlugin.pstore_set("ad:_id", max_id + 1)
|
||||
max_id
|
||||
end
|
||||
end
|
||||
|
||||
def self.find(id)
|
||||
if r = AdPlugin.pstore_get("ad:#{id}")
|
||||
from_hash(r)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.all
|
||||
PluginStoreRow
|
||||
.where(plugin_name: AdPlugin.plugin_name)
|
||||
.where("key LIKE 'ad:%'")
|
||||
.where("key != 'ad:_id'")
|
||||
.map { |psr| from_hash(PluginStore.cast_value(psr.type_name, psr.value)) }
|
||||
.sort_by { |ad| ad.id }
|
||||
end
|
||||
|
||||
def save
|
||||
if self.valid?
|
||||
self.id = self.class.alloc_id if self.id.to_i <= 0
|
||||
AdPlugin.pstore_set("ad:#{id}", to_hash)
|
||||
self.class.publish_if_ads_enabled
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def update(attrs)
|
||||
self.name = attrs[:name]
|
||||
self.html = attrs[:html]
|
||||
self.save
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{ id: @id, name: @name, html: @html }
|
||||
end
|
||||
|
||||
def destroy
|
||||
AdPlugin.pstore_delete("ad:#{id}")
|
||||
self.class.publish_if_ads_enabled
|
||||
end
|
||||
|
||||
def self.publish_if_ads_enabled
|
||||
if AdPlugin::HouseAdSetting.all.any? { |_, adsToShow| !adsToShow.blank? }
|
||||
AdPlugin::HouseAdSetting.publish_settings
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ::AdPlugin
|
||||
class HouseAdSetting
|
||||
DEFAULTS = {
|
||||
topic_list_top: "",
|
||||
topic_above_post_stream: "",
|
||||
topic_above_suggested: "",
|
||||
post_bottom: "",
|
||||
topic_list_between: "",
|
||||
}
|
||||
|
||||
def self.all
|
||||
settings = DEFAULTS.dup
|
||||
|
||||
PluginStoreRow
|
||||
.where(plugin_name: AdPlugin.plugin_name)
|
||||
.where("key LIKE 'ad-setting:%'")
|
||||
.each { |psr| settings[psr.key[11..-1].to_sym] = psr.value }
|
||||
|
||||
settings
|
||||
end
|
||||
|
||||
def self.settings_and_ads
|
||||
settings = AdPlugin::HouseAdSetting.all
|
||||
ad_names = settings.values.map { |v| v.split("|") }.flatten.uniq
|
||||
ads = AdPlugin::HouseAd.all.select { |ad| ad_names.include?(ad.name) }
|
||||
{
|
||||
settings:
|
||||
settings.merge(
|
||||
after_nth_post: SiteSetting.house_ads_after_nth_post,
|
||||
after_nth_topic: SiteSetting.house_ads_after_nth_topic,
|
||||
house_ads_frequency: SiteSetting.house_ads_frequency,
|
||||
),
|
||||
creatives:
|
||||
ads.inject({}) do |h, ad|
|
||||
h[ad.name] = ad.html
|
||||
h
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
def self.update(setting_name, value)
|
||||
raise Discourse::NotFound unless DEFAULTS.keys.include?(setting_name.to_sym)
|
||||
|
||||
ad_names = value&.split("|") || []
|
||||
|
||||
raise Discourse::InvalidParameters if value && ad_names.any? { |v| v !~ HouseAd::NAME_REGEX }
|
||||
|
||||
ad_names = (HouseAd.all.map(&:name) & ad_names) unless ad_names.empty?
|
||||
|
||||
new_value = ad_names.join("|")
|
||||
|
||||
if value.nil? || new_value == DEFAULTS[setting_name.to_sym]
|
||||
AdPlugin.pstore_delete("ad-setting:#{setting_name}")
|
||||
else
|
||||
AdPlugin.pstore_set("ad-setting:#{setting_name}", new_value)
|
||||
end
|
||||
|
||||
publish_settings
|
||||
end
|
||||
|
||||
def self.publish_settings
|
||||
MessageBus.publish("/site/house-creatives", settings_and_ads)
|
||||
end
|
||||
end
|
||||
end
|
||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
export default {
|
||||
resource: "admin.adminPlugins",
|
||||
path: "/plugins",
|
||||
map() {
|
||||
this.route("houseAds", { path: "/pluginad/house_creatives" }, function () {
|
||||
this.route("index", { path: "/" });
|
||||
this.route("show", { path: "/:ad_id" });
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
import Component from "@ember/component";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { alias, or } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import {
|
||||
isNthPost,
|
||||
isNthTopicListItem,
|
||||
} from "discourse/plugins/discourse-adplugin/discourse/helpers/slot-position";
|
||||
|
||||
export default Component.extend({
|
||||
router: service(),
|
||||
|
||||
currentCategoryId: or(
|
||||
"router.currentRoute.attributes.category.id",
|
||||
"router.currentRoute.parent.attributes.category_id"
|
||||
),
|
||||
|
||||
currentCategorySlug: or(
|
||||
"router.currentRoute.attributes.category.slug",
|
||||
"router.currentRoute.parent.attributes.category.slug"
|
||||
),
|
||||
|
||||
// Server needs to compute this in case hidden tags are being used.
|
||||
topicTagsDisableAds: alias(
|
||||
"router.currentRoute.parent.attributes.tags_disable_ads"
|
||||
),
|
||||
|
||||
isRestrictedCategory: or(
|
||||
"router.currentRoute.attributes.category.read_restricted",
|
||||
"router.currentRoute.parent.attributes.category.read_restricted"
|
||||
),
|
||||
|
||||
@discourseComputed(
|
||||
"router.currentRoute.attributes.__type",
|
||||
"router.currentRoute.attributes.id"
|
||||
)
|
||||
topicListTag(type, tag) {
|
||||
if (type === "tag" && tag) {
|
||||
return tag;
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("router.currentRoute.parent.attributes.archetype")
|
||||
isPersonalMessage(topicType) {
|
||||
return topicType === "private_message";
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser.groups")
|
||||
showToGroups(groups) {
|
||||
const currentUser = this.currentUser;
|
||||
|
||||
if (
|
||||
!currentUser ||
|
||||
!groups ||
|
||||
!this.siteSettings.no_ads_for_groups ||
|
||||
this.siteSettings.no_ads_for_groups.length === 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let noAdsGroups = this.siteSettings.no_ads_for_groups
|
||||
.split("|")
|
||||
.filter(Boolean);
|
||||
let currentGroups = groups.map((g) => g.id.toString());
|
||||
|
||||
return !currentGroups.any((g) => noAdsGroups.includes(g));
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"currentCategoryId",
|
||||
"topicTagsDisableAds",
|
||||
"topicListTag",
|
||||
"isPersonalMessage",
|
||||
"isRestrictedCategory"
|
||||
)
|
||||
showOnCurrentPage(
|
||||
categoryId,
|
||||
topicTagsDisableAds,
|
||||
topicListTag,
|
||||
isPersonalMessage,
|
||||
isRestrictedCategory
|
||||
) {
|
||||
return (
|
||||
!topicTagsDisableAds &&
|
||||
(!categoryId ||
|
||||
!this.siteSettings.no_ads_for_categories ||
|
||||
!this.siteSettings.no_ads_for_categories
|
||||
.split("|")
|
||||
.includes(categoryId.toString())) &&
|
||||
(!topicListTag ||
|
||||
!this.siteSettings.no_ads_for_tags ||
|
||||
!this.siteSettings.no_ads_for_tags.split("|").includes(topicListTag)) &&
|
||||
(!isPersonalMessage || !this.siteSettings.no_ads_for_personal_messages) &&
|
||||
(!isRestrictedCategory ||
|
||||
!this.siteSettings.no_ads_for_restricted_categories)
|
||||
);
|
||||
},
|
||||
|
||||
isNthPost(n) {
|
||||
return isNthPost(n, this.get("postNumber"));
|
||||
},
|
||||
|
||||
isNthTopicListItem(n) {
|
||||
return isNthTopicListItem(n, this.get("indexNumber"));
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,254 @@
|
||||
import EmberObject from "@ember/object";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import {
|
||||
isNthPost,
|
||||
isNthTopicListItem,
|
||||
} from "discourse/plugins/discourse-adplugin/discourse/helpers/slot-position";
|
||||
|
||||
const adConfig = EmberObject.create({
|
||||
"google-adsense": {
|
||||
settingPrefix: "adsense", // settings follow naming convention
|
||||
enabledSetting: "adsense_publisher_code",
|
||||
nthPost: "adsense_nth_post_code",
|
||||
},
|
||||
"google-dfp-ad": {
|
||||
settingPrefix: "dfp", // settings follow naming convention
|
||||
enabledSetting: "dfp_publisher_id",
|
||||
nthPost: "dfp_nth_post_code",
|
||||
},
|
||||
"amazon-product-links": {
|
||||
settingPrefix: "amazon",
|
||||
enabledSetting: false,
|
||||
nthPost: "amazon_nth_post_code",
|
||||
desktop: {
|
||||
"topic-list-top": "amazon_topic_list_top_src_code",
|
||||
"post-bottom": "amazon_post_bottom_src_code",
|
||||
"topic-above-post-stream": "amazon_topic_above_post_stream_src_code",
|
||||
"topic-above-suggested": "amazon_topic_above_suggested_src_code",
|
||||
},
|
||||
mobile: {
|
||||
"topic-list-top": "amazon_mobile_topic_list_top_src_code",
|
||||
"post-bottom": "amazon_mobile_post_bottom_src_code",
|
||||
"topic-above-post-stream":
|
||||
"amazon_mobile_topic_above_post_stream_src_code",
|
||||
"topic-above-suggested": "amazon_mobile_topic_above_suggested_src_code",
|
||||
},
|
||||
},
|
||||
"carbonads-ad": {
|
||||
settingPrefix: "carbonads",
|
||||
enabledSetting: "carbonads_serve_id",
|
||||
desktop: {
|
||||
"topic-list-top": "carbonads_topic_list_top_enabled",
|
||||
"post-bottom": false,
|
||||
"topic-above-post-stream": "carbonads_above_post_stream_enabled",
|
||||
"topic-above-suggested": false,
|
||||
},
|
||||
},
|
||||
"adbutler-ad": {
|
||||
settingPrefix: "adbutler",
|
||||
enabledSetting: "adbutler_publisher_id",
|
||||
desktop: {
|
||||
"topic-list-top": "adbutler_topic_list_top_zone_id",
|
||||
"post-bottom": "adbutler_post_bottom_zone_id",
|
||||
"topic-above-post-stream": "adbutler_topic_above_post_stream_zone_id",
|
||||
"topic-above-suggested": "adbutler_topic_above_suggested_zone_id",
|
||||
},
|
||||
mobile: {
|
||||
"topic-list-top": "adbutler_mobile_topic_list_top_zone_id",
|
||||
"post-bottom": "adbutler_mobile_post_bottom_zone_id",
|
||||
"topic-above-post-stream":
|
||||
"adbutler_mobile_topic_above_post_stream_zone_id",
|
||||
"topic-above-suggested": "adbutler_mobile_topic_above_suggested_zone_id",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const displayCounts = {
|
||||
houseAds: 0,
|
||||
allAds: 0,
|
||||
};
|
||||
|
||||
function _isNetworkAvailable(siteSettings, 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(siteSettings[enabledNetworkSettingName])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function _shouldPlaceAdInSlot(
|
||||
siteSettings,
|
||||
currentPostNumber,
|
||||
positionToPlace
|
||||
) {
|
||||
return (
|
||||
!currentPostNumber ||
|
||||
!positionToPlace ||
|
||||
isNthPost(parseInt(siteSettings[positionToPlace], 10), currentPostNumber)
|
||||
);
|
||||
}
|
||||
|
||||
export function slotContenders(
|
||||
site,
|
||||
siteSettings,
|
||||
placement,
|
||||
indexNumber,
|
||||
postNumber
|
||||
) {
|
||||
let types = [];
|
||||
const houseAds = site.get("house_creatives"),
|
||||
placeUnderscored = placement.replace(/-/g, "_");
|
||||
|
||||
if (houseAds && houseAds.settings) {
|
||||
const adsForSlot = houseAds.settings[placeUnderscored];
|
||||
|
||||
const adAvailable =
|
||||
Object.keys(houseAds.creatives).length > 0 && !isBlank(adsForSlot);
|
||||
|
||||
// postNumber and indexNumber are both null for topic-list-top, topic-above-post-stream,
|
||||
// and topic-above-suggested placements. Assume we want to place an ad outside the topic list.
|
||||
const notPlacingBetweenTopics = !postNumber && !indexNumber;
|
||||
|
||||
const canBePlacedInBetweenTopics =
|
||||
placeUnderscored === "topic_list_between" &&
|
||||
isNthTopicListItem(
|
||||
parseInt(houseAds.settings.after_nth_topic, 10),
|
||||
indexNumber
|
||||
);
|
||||
|
||||
if (
|
||||
adAvailable &&
|
||||
(notPlacingBetweenTopics ||
|
||||
canBePlacedInBetweenTopics ||
|
||||
isNthPost(parseInt(houseAds.settings.after_nth_post, 10), postNumber))
|
||||
) {
|
||||
types.push("house-ad");
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(adConfig).forEach((adNetwork) => {
|
||||
const config = adConfig[adNetwork];
|
||||
let settingNames = null,
|
||||
name;
|
||||
|
||||
if (
|
||||
_isNetworkAvailable(siteSettings, config.enabledSetting) &&
|
||||
_shouldPlaceAdInSlot(siteSettings, postNumber, config.nthPost)
|
||||
) {
|
||||
if (site.mobileView) {
|
||||
settingNames = config.mobile || config.desktop;
|
||||
} else {
|
||||
settingNames = config.desktop;
|
||||
}
|
||||
|
||||
if (settingNames) {
|
||||
name = settingNames[placement];
|
||||
}
|
||||
|
||||
if (name === undefined) {
|
||||
// follows naming convention: prefix_(mobile_)_{placement}_code
|
||||
name = `${config.settingPrefix}_${
|
||||
site.mobileView ? "mobile_" : ""
|
||||
}${placeUnderscored}_code`;
|
||||
}
|
||||
|
||||
if (
|
||||
name !== false &&
|
||||
siteSettings[name] !== false &&
|
||||
!isBlank(siteSettings[name])
|
||||
) {
|
||||
types.push(adNetwork);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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,
|
||||
indexNumber,
|
||||
postNumber
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* When house ads are configured to alternate with other ad networks, we
|
||||
* need to trigger an update of which ad component is shown after
|
||||
* navigating between topic lists or topics.
|
||||
*/
|
||||
@observes("refreshOnChange")
|
||||
changed() {
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// force adComponents to be recomputed
|
||||
this.notifyPropertyChange("needsUpdate");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a list of the names of ad components that should be rendered
|
||||
* in the given ad placement. It handles alternating between house ads
|
||||
* and other ad networks.
|
||||
*/
|
||||
@discourseComputed("placement", "availableAdTypes", "needsUpdate")
|
||||
adComponents(placement, availableAdTypes) {
|
||||
if (
|
||||
!availableAdTypes.includes("house-ad") ||
|
||||
availableAdTypes.length === 1
|
||||
) {
|
||||
// Current behaviour is to allow multiple ads from different networks
|
||||
// to show in the same place. We could change this to choose one somehow.
|
||||
return availableAdTypes;
|
||||
}
|
||||
|
||||
const houseAds = this.site.get("house_creatives");
|
||||
let houseAdsSkipped = false;
|
||||
|
||||
if (houseAds.settings.house_ads_frequency === 100) {
|
||||
// house always wins
|
||||
return ["house-ad"];
|
||||
} else if (houseAds.settings.house_ads_frequency > 0) {
|
||||
// show house ads the given percent of the time
|
||||
if (
|
||||
displayCounts.allAds === 0 ||
|
||||
(100 * displayCounts.houseAds) / displayCounts.allAds <
|
||||
houseAds.settings.house_ads_frequency
|
||||
) {
|
||||
displayCounts.houseAds += 1;
|
||||
displayCounts.allAds += 1;
|
||||
return ["house-ad"];
|
||||
} else {
|
||||
houseAdsSkipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
const networkNames = availableAdTypes.filter((x) => x !== "house-ad");
|
||||
|
||||
if (houseAdsSkipped) {
|
||||
displayCounts.allAds += networkNames.length;
|
||||
}
|
||||
|
||||
return networkNames;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,161 @@
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import RSVP from "rsvp";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
|
||||
let _loaded = false,
|
||||
_promise = null,
|
||||
_c = 0;
|
||||
|
||||
function loadAdbutler(adserverHostname) {
|
||||
if (_loaded) {
|
||||
return RSVP.resolve();
|
||||
}
|
||||
|
||||
if (_promise) {
|
||||
return _promise;
|
||||
}
|
||||
|
||||
_promise = loadScript("https://" + adserverHostname + "/app.js", {
|
||||
scriptTag: true,
|
||||
}).then(function () {
|
||||
_loaded = true;
|
||||
});
|
||||
|
||||
return _promise;
|
||||
}
|
||||
|
||||
export default AdComponent.extend({
|
||||
divs: null,
|
||||
publisherId: null,
|
||||
|
||||
init() {
|
||||
let dimensions = [728, 90];
|
||||
let configKey = "adbutler_";
|
||||
let className = "adbutler-";
|
||||
let dimClassName = "adbutler-ad";
|
||||
|
||||
this.set("divs", []);
|
||||
|
||||
if (this.site.mobileView) {
|
||||
dimensions = [320, 50];
|
||||
configKey += "mobile_";
|
||||
className += "mobile-";
|
||||
dimClassName = "adbutler-mobile-ad";
|
||||
}
|
||||
|
||||
configKey += this.get("placement").replace(/-/g, "_") + "_zone_id";
|
||||
this.set("configKey", configKey);
|
||||
|
||||
className += this.get("placement");
|
||||
this.set("className", className + " " + dimClassName);
|
||||
|
||||
let zoneId = this.siteSettings[configKey];
|
||||
this.set("zoneId", zoneId);
|
||||
|
||||
let divId = "placement-" + zoneId + "-" + _c;
|
||||
this.set("divId", divId);
|
||||
|
||||
let publisherId = this.siteSettings.adbutler_publisher_id;
|
||||
this.set("publisherId", publisherId);
|
||||
|
||||
_c++;
|
||||
|
||||
this.divs.push({
|
||||
divId,
|
||||
publisherId,
|
||||
zoneId,
|
||||
dimensions,
|
||||
});
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
_triggerAds() {
|
||||
if (isTesting()) {
|
||||
return; // Don't load external JS during tests
|
||||
}
|
||||
|
||||
const adserverHostname = this.siteSettings.adbutler_adserver_hostname;
|
||||
|
||||
loadAdbutler(adserverHostname).then(
|
||||
function () {
|
||||
if (this.divs.length > 0) {
|
||||
let abkw = window.abkw || "";
|
||||
window.AdButler.ads.push({
|
||||
handler: function (opt) {
|
||||
window.AdButler.register(
|
||||
opt.place.publisherId,
|
||||
opt.place.zoneId,
|
||||
opt.place.dimensions,
|
||||
opt.place.divId,
|
||||
opt
|
||||
);
|
||||
},
|
||||
opt: {
|
||||
place: this.divs.pop(),
|
||||
keywords: abkw,
|
||||
domain: adserverHostname,
|
||||
click: "CLICK_MACRO_PLACEHOLDER",
|
||||
},
|
||||
});
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
scheduleOnce("afterRender", this, this._triggerAds);
|
||||
},
|
||||
|
||||
@observes("listLoading")
|
||||
waitForLoad() {
|
||||
if (this.get("adRequested")) {
|
||||
return;
|
||||
} // already requested that this ad unit be populated
|
||||
if (!this.get("listLoading")) {
|
||||
scheduleOnce("afterRender", this, this._triggerAds);
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser.trust_level")
|
||||
showToTrustLevel(trustLevel) {
|
||||
return !(
|
||||
trustLevel && trustLevel > this.siteSettings.adbutler_through_trust_level
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"publisherId",
|
||||
"showToTrustLevel",
|
||||
"showToGroups",
|
||||
"showAfterPost",
|
||||
"showOnCurrentPage"
|
||||
)
|
||||
showAd(
|
||||
publisherId,
|
||||
showToTrustLevel,
|
||||
showToGroups,
|
||||
showAfterPost,
|
||||
showOnCurrentPage
|
||||
) {
|
||||
return (
|
||||
publisherId &&
|
||||
showToTrustLevel &&
|
||||
showToGroups &&
|
||||
showAfterPost &&
|
||||
showOnCurrentPage
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("postNumber")
|
||||
showAfterPost(postNumber) {
|
||||
if (!postNumber) {
|
||||
return true;
|
||||
}
|
||||
return this.isNthPost(parseInt(this.siteSettings.adbutler_nth_post, 10));
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,191 @@
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { and } from "@ember/object/computed";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
|
||||
export default AdComponent.extend({
|
||||
classNames: ["amazon-product-links"],
|
||||
|
||||
showAd: and(
|
||||
"showToTrustLevel",
|
||||
"showToGroups",
|
||||
"showAfterPost",
|
||||
"showOnCurrentPage"
|
||||
),
|
||||
|
||||
init() {
|
||||
const data = {
|
||||
"topic-list-top": {},
|
||||
"topic-above-post-stream": {},
|
||||
"topic-above-suggested": {},
|
||||
"post-bottom": {},
|
||||
};
|
||||
const mobileView = this.site.get("mobileView");
|
||||
const placement = this.get("placement");
|
||||
|
||||
if (!mobileView && this.siteSettings.amazon_topic_list_top_src_code) {
|
||||
data["topic-list-top"]["user_input"] =
|
||||
this.siteSettings.amazon_topic_list_top_src_code;
|
||||
data["topic-list-top"]["amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_topic_list_top_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-list-top"]["amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_topic_list_top_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (mobileView && this.siteSettings.amazon_mobile_topic_list_top_src_code) {
|
||||
data["topic-list-top"]["user_input_mobile"] =
|
||||
this.siteSettings.amazon_mobile_topic_list_top_src_code;
|
||||
data["topic-list-top"]["mobile_amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_list_top_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-list-top"]["mobile_amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_list_top_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!mobileView &&
|
||||
this.siteSettings.amazon_topic_above_post_stream_src_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["user_input"] =
|
||||
this.siteSettings.amazon_topic_above_post_stream_src_code;
|
||||
data["topic-above-post-stream"]["amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_topic_above_post_stream_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-above-post-stream"]["amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_topic_above_post_stream_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
mobileView &&
|
||||
this.siteSettings.amazon_mobile_topic_above_post_stream_src_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["user_input_mobile"] =
|
||||
this.siteSettings.amazon_mobile_topic_above_post_stream_src_code;
|
||||
data["topic-above-post-stream"]["mobile_amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_above_post_stream_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-above-post-stream"]["mobile_amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_above_post_stream_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!mobileView &&
|
||||
this.siteSettings.amazon_topic_above_suggested_src_code
|
||||
) {
|
||||
data["topic-above-suggested"]["user_input"] =
|
||||
this.siteSettings.amazon_topic_above_suggested_src_code;
|
||||
data["topic-above-suggested"]["amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_topic_above_suggested_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-above-suggested"]["amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_topic_above_suggested_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
mobileView &&
|
||||
this.siteSettings.amazon_mobile_topic_above_suggested_src_code
|
||||
) {
|
||||
data["topic-above-suggested"]["user_input_mobile"] =
|
||||
this.siteSettings.amazon_mobile_topic_above_suggested_src_code;
|
||||
data["topic-above-suggested"]["mobile_amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_above_suggested_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["topic-above-suggested"]["mobile_amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_topic_above_suggested_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (!mobileView && this.siteSettings.amazon_post_bottom_src_code) {
|
||||
data["post-bottom"]["user_input"] =
|
||||
this.siteSettings.amazon_post_bottom_src_code;
|
||||
data["post-bottom"]["amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_post_bottom_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["post-bottom"]["amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_post_bottom_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
if (mobileView && this.siteSettings.amazon_mobile_post_bottom_src_code) {
|
||||
data["post-bottom"]["user_input_mobile"] =
|
||||
this.siteSettings.amazon_mobile_post_bottom_src_code;
|
||||
data["post-bottom"]["mobile_amazon_width"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_post_bottom_ad_width_code,
|
||||
10
|
||||
);
|
||||
data["post-bottom"]["mobile_amazon_height"] = parseInt(
|
||||
this.siteSettings.amazon_mobile_post_bottom_ad_height_code,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
this.set("user_input", data[placement]["user_input"]);
|
||||
this.set("amazon_width", data[placement]["amazon_width"]);
|
||||
this.set("amazon_height", data[placement]["amazon_height"]);
|
||||
this.set("user_input_mobile", data[placement]["user_input_mobile"]);
|
||||
this.set("mobile_amazon_height", data[placement]["mobile_amazon_height"]);
|
||||
this.set("mobile_amazon_width", data[placement]["mobile_amazon_width"]);
|
||||
this._super();
|
||||
},
|
||||
|
||||
@discourseComputed("amazon_width", "amazon_height")
|
||||
adWrapperStyle(w, h) {
|
||||
return htmlSafe(`width: ${w}px; height: ${h}px;`);
|
||||
},
|
||||
|
||||
@discourseComputed("mobile_amazon_width", "mobile_amazon_height")
|
||||
adWrapperStyleMobile(w, h) {
|
||||
return htmlSafe(`width: ${w}px; height: ${h}px;`);
|
||||
},
|
||||
|
||||
@discourseComputed("mobile_amazon_width")
|
||||
adTitleStyleMobile(w) {
|
||||
return htmlSafe(`width: ${w}px;`);
|
||||
},
|
||||
|
||||
@discourseComputed("user_input")
|
||||
userInput(userInput) {
|
||||
return htmlSafe(`${userInput}`);
|
||||
},
|
||||
|
||||
@discourseComputed("user_input_mobile")
|
||||
userInputMobile(userInput) {
|
||||
return htmlSafe(`${userInput}`);
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser.trust_level")
|
||||
showToTrustLevel(trustLevel) {
|
||||
return !(
|
||||
trustLevel && trustLevel > this.siteSettings.amazon_through_trust_level
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("postNumber")
|
||||
showAfterPost(postNumber) {
|
||||
if (!postNumber) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.isNthPost(parseInt(this.siteSettings.amazon_nth_post_code, 10));
|
||||
},
|
||||
});
|
||||
@@ -1,167 +0,0 @@
|
||||
var currentUser = Discourse.User.current();
|
||||
|
||||
var data = {
|
||||
"topic-list-top": {},
|
||||
"topic-above-post-stream": {},
|
||||
"topic-above-suggested": {},
|
||||
"post-bottom": {}
|
||||
};
|
||||
|
||||
if (
|
||||
!Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_topic_list_top_src_code
|
||||
) {
|
||||
data["topic-list-top"]["user_input"] =
|
||||
Discourse.SiteSettings.amazon_topic_list_top_src_code;
|
||||
data["topic-list-top"]["amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_list_top_ad_width_code
|
||||
);
|
||||
data["topic-list-top"]["amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_list_top_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_mobile_topic_list_top_src_code
|
||||
) {
|
||||
data["topic-list-top"]["user_input_mobile"] =
|
||||
Discourse.SiteSettings.amazon_mobile_topic_list_top_src_code;
|
||||
data["topic-list-top"]["mobile_amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_list_top_ad_width_code
|
||||
);
|
||||
data["topic-list-top"]["mobile_amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_list_top_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_topic_above_post_stream_src_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["user_input"] =
|
||||
Discourse.SiteSettings.amazon_topic_above_post_stream_src_code;
|
||||
data["topic-above-post-stream"]["amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_above_post_stream_ad_width_code
|
||||
);
|
||||
data["topic-above-post-stream"]["amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_above_post_stream_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_post_stream_src_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["user_input_mobile"] =
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_post_stream_src_code;
|
||||
data["topic-above-post-stream"]["mobile_amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_post_stream_ad_width_code
|
||||
);
|
||||
data["topic-above-post-stream"]["mobile_amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_post_stream_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_topic_above_suggested_src_code
|
||||
) {
|
||||
data["topic-above-suggested"]["user_input"] =
|
||||
Discourse.SiteSettings.amazon_topic_above_suggested_src_code;
|
||||
data["topic-above-suggested"]["amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_above_suggested_ad_width_code
|
||||
);
|
||||
data["topic-above-suggested"]["amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_topic_above_suggested_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_suggested_src_code
|
||||
) {
|
||||
data["topic-above-suggested"]["user_input_mobile"] =
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_suggested_src_code;
|
||||
data["topic-above-suggested"]["mobile_amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_suggested_ad_width_code
|
||||
);
|
||||
data["topic-above-suggested"]["mobile_amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_topic_above_suggested_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_post_bottom_src_code
|
||||
) {
|
||||
data["post-bottom"]["user_input"] =
|
||||
Discourse.SiteSettings.amazon_post_bottom_src_code;
|
||||
data["post-bottom"]["amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_post_bottom_ad_width_code
|
||||
);
|
||||
data["post-bottom"]["amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_post_bottom_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
Discourse.Mobile.mobileView &&
|
||||
Discourse.SiteSettings.amazon_mobile_post_bottom_src_code
|
||||
) {
|
||||
data["post-bottom"]["user_input_mobile"] =
|
||||
Discourse.SiteSettings.amazon_mobile_post_bottom_src_code;
|
||||
data["post-bottom"]["mobile_amazon_width"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_post_bottom_ad_width_code
|
||||
);
|
||||
data["post-bottom"]["mobile_amazon_height"] = parseInt(
|
||||
Discourse.SiteSettings.amazon_mobile_post_bottom_ad_height_code
|
||||
);
|
||||
}
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ["amazon-product-links"],
|
||||
|
||||
init: function() {
|
||||
let placement = this.get("placement");
|
||||
this.set("user_input", data[placement]["user_input"]);
|
||||
this.set("amazon_width", data[placement]["amazon_width"]);
|
||||
this.set("amazon_height", data[placement]["amazon_height"]);
|
||||
this.set("user_input_mobile", data[placement]["user_input_mobile"]);
|
||||
this.set("mobile_amazon_height", data[placement]["mobile_amazon_height"]);
|
||||
this.set("mobile_amazon_width", data[placement]["mobile_amazon_width"]);
|
||||
this._super();
|
||||
},
|
||||
|
||||
adWrapperStyle: function() {
|
||||
return `width: ${this.get("amazon_width")}px; height: ${this.get(
|
||||
"amazon_height"
|
||||
)}px;`.htmlSafe();
|
||||
}.property("amazon_width", "amazon_height"),
|
||||
|
||||
adWrapperStyleMobile: function() {
|
||||
return `width: ${this.get("mobile_amazon_width")}px; height: ${this.get(
|
||||
"mobile_amazon_height"
|
||||
)}px;`.htmlSafe();
|
||||
}.property("mobile_amazon_width", "mobile_amazon_height"),
|
||||
|
||||
adTitleStyleMobile: function() {
|
||||
return `width: ${this.get("mobile_amazon_width")}px;`.htmlSafe();
|
||||
}.property("mobile_amazon_width"),
|
||||
|
||||
userInput: function() {
|
||||
return `${this.get("user_input")}`.htmlSafe();
|
||||
}.property("user_input"),
|
||||
|
||||
userInputMobile: function() {
|
||||
return `${this.get("user_input_mobile")}`.htmlSafe();
|
||||
}.property("user_input_mobile"),
|
||||
|
||||
checkTrustLevels: function() {
|
||||
return !(
|
||||
currentUser &&
|
||||
currentUser.get("trust_level") >
|
||||
Discourse.SiteSettings.amazon_through_trust_level
|
||||
);
|
||||
}.property("trust_level")
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
|
||||
export default AdComponent.extend({
|
||||
serve_id: null,
|
||||
placement: null,
|
||||
|
||||
init() {
|
||||
this.set("serve_id", this.siteSettings.carbonads_serve_id);
|
||||
this.set("placement", this.siteSettings.carbonads_placement);
|
||||
this._super();
|
||||
},
|
||||
|
||||
@discourseComputed("serve_id", "placement")
|
||||
url(serveId, placement) {
|
||||
return htmlSafe(
|
||||
`//cdn.carbonads.com/carbon.js?serve=${serveId}&placement=${placement}`
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser.trust_level")
|
||||
showToTrustLevel(trustLevel) {
|
||||
return !(
|
||||
trustLevel && trustLevel > this.siteSettings.carbonads_through_trust_level
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"placement",
|
||||
"serve_id",
|
||||
"showToTrustLevel",
|
||||
"showToGroups",
|
||||
"showOnCurrentPage"
|
||||
)
|
||||
showAd(
|
||||
placement,
|
||||
serveId,
|
||||
showToTrustLevel,
|
||||
showToGroups,
|
||||
showOnCurrentPage
|
||||
) {
|
||||
return (
|
||||
placement &&
|
||||
serveId &&
|
||||
showToTrustLevel &&
|
||||
showToGroups &&
|
||||
showOnCurrentPage
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -1,131 +0,0 @@
|
||||
import {
|
||||
default as computed,
|
||||
observes
|
||||
} from "ember-addons/ember-computed-decorators";
|
||||
|
||||
var _loaded = false,
|
||||
_promise = null,
|
||||
currentUser = Discourse.User.current(),
|
||||
propertyId = Discourse.SiteSettings.codefund_property_id;
|
||||
|
||||
function loadCodeFund() {
|
||||
if (_loaded) {
|
||||
return Ember.RSVP.resolve();
|
||||
}
|
||||
|
||||
if (_promise) {
|
||||
return _promise;
|
||||
}
|
||||
|
||||
const url = "https://codefund.app/properties/" + propertyId + "/funder.json";
|
||||
|
||||
_promise = new Promise(function(resolve, reject) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open("GET", url);
|
||||
xhr.onreadystatechange = handler;
|
||||
xhr.responseType = "json";
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
xhr.send();
|
||||
|
||||
function handler() {
|
||||
if (this.readyState === this.DONE) {
|
||||
_loaded = true;
|
||||
|
||||
if (this.status === 200) {
|
||||
resolve(this.response);
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
"getJSON: `" + url + "` failed with status: [" + this.status + "]"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return _promise;
|
||||
}
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [
|
||||
":codefund-ad",
|
||||
"classForSlot",
|
||||
"isResponsive:codefund-responsive"
|
||||
],
|
||||
propertyId: propertyId,
|
||||
adRequested: false,
|
||||
adDetails: {},
|
||||
|
||||
_triggerAds() {
|
||||
if (!propertyId) return;
|
||||
|
||||
this.set("adRequested", true);
|
||||
loadCodeFund()
|
||||
.then(data => {
|
||||
_loaded = false;
|
||||
_promise = null;
|
||||
this.set("adDetails", data);
|
||||
this.set("adRequested", false);
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
if (!this.get("showAd")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
|
||||
},
|
||||
|
||||
@observes("listLoading")
|
||||
waitForLoad: function() {
|
||||
if (this.get("adRequested")) {
|
||||
return;
|
||||
} // already requested that this ad unit be populated
|
||||
if (!this.get("listLoading")) {
|
||||
Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
|
||||
}
|
||||
},
|
||||
|
||||
checkTrustLevels: function() {
|
||||
return !(
|
||||
currentUser &&
|
||||
currentUser.get("trust_level") >
|
||||
Discourse.SiteSettings.codefund_through_trust_level
|
||||
);
|
||||
}.property("trust_level"),
|
||||
|
||||
@computed("checkTrustLevels")
|
||||
showAd: function(checkTrustLevels) {
|
||||
return Discourse.SiteSettings.codefund_property_id && checkTrustLevels;
|
||||
},
|
||||
|
||||
@computed("placement")
|
||||
displayPostBottom: function(placement) {
|
||||
return placement === "post-bottom";
|
||||
},
|
||||
|
||||
@computed("placement")
|
||||
displayTopicAbovePostStream: function() {
|
||||
return this.get("placement") === "topic-above-post-stream";
|
||||
},
|
||||
|
||||
@computed("placement")
|
||||
displayTopicAboveSuggested: function() {
|
||||
return this.get("placement") === "topic-above-suggested";
|
||||
},
|
||||
|
||||
@computed("placement")
|
||||
displayTopicListTop: function() {
|
||||
return this.get("placement") === "topic-list-top";
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,255 @@
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import RSVP from "rsvp";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
|
||||
let _loaded = false,
|
||||
_promise = null,
|
||||
renderCounts = {};
|
||||
|
||||
function parseAdWidth(value) {
|
||||
if (value === "responsive") {
|
||||
return "auto";
|
||||
}
|
||||
if (value.startsWith("fluid")) {
|
||||
return "fluid";
|
||||
}
|
||||
const w = parseInt(value.substring(0, 3).trim(), 10);
|
||||
if (isNaN(w)) {
|
||||
return "auto";
|
||||
} else {
|
||||
return `${w}px`;
|
||||
}
|
||||
}
|
||||
|
||||
function parseAdHeight(value) {
|
||||
if (value === "responsive") {
|
||||
return "auto";
|
||||
}
|
||||
if (value.startsWith("fluid")) {
|
||||
return "fluid";
|
||||
}
|
||||
const h = parseInt(value.substring(4, 7).trim(), 10);
|
||||
if (isNaN(h)) {
|
||||
return "auto";
|
||||
} else {
|
||||
return `${h}px`;
|
||||
}
|
||||
}
|
||||
|
||||
function loadAdsense() {
|
||||
if (_loaded) {
|
||||
return RSVP.resolve();
|
||||
}
|
||||
|
||||
if (_promise) {
|
||||
return _promise;
|
||||
}
|
||||
|
||||
const adsenseSrc =
|
||||
("https:" === document.location.protocol ? "https:" : "http:") +
|
||||
"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
|
||||
_promise = loadScript(adsenseSrc, { scriptTag: true }).then(function () {
|
||||
_loaded = true;
|
||||
});
|
||||
|
||||
return _promise;
|
||||
}
|
||||
|
||||
const DESKTOP_SETTINGS = {
|
||||
"topic-list-top": {
|
||||
code: "adsense_topic_list_top_code",
|
||||
sizes: "adsense_topic_list_top_ad_sizes",
|
||||
},
|
||||
"topic-above-post-stream": {
|
||||
code: "adsense_topic_above_post_stream_code",
|
||||
sizes: "adsense_topic_above_post_stream_ad_sizes",
|
||||
},
|
||||
"topic-above-suggested": {
|
||||
code: "adsense_topic_above_suggested_code",
|
||||
sizes: "adsense_topic_above_suggested_ad_sizes",
|
||||
},
|
||||
"post-bottom": {
|
||||
code: "adsense_post_bottom_code",
|
||||
sizes: "adsense_post_bottom_ad_sizes",
|
||||
},
|
||||
};
|
||||
|
||||
const MOBILE_SETTINGS = {
|
||||
"topic-list-top": {
|
||||
code: "adsense_mobile_topic_list_top_code",
|
||||
sizes: "adsense_mobile_topic_list_top_ad_size",
|
||||
},
|
||||
"topic-above-post-stream": {
|
||||
code: "adsense_mobile_topic_above_post_stream_code",
|
||||
sizes: "adsense_mobile_topic_above_post_stream_ad_size",
|
||||
},
|
||||
"topic-above-suggested": {
|
||||
code: "adsense_mobile_topic_above_suggested_code",
|
||||
sizes: "adsense_mobile_topic_above_suggested_ad_size",
|
||||
},
|
||||
"post-bottom": {
|
||||
code: "adsense_mobile_post_bottom_code",
|
||||
sizes: "adsense_mobile_post_bottom_ad_size",
|
||||
},
|
||||
};
|
||||
|
||||
export default AdComponent.extend({
|
||||
classNameBindings: [
|
||||
":google-adsense",
|
||||
"classForSlot",
|
||||
"isResponsive:adsense-responsive",
|
||||
],
|
||||
loadedGoogletag: false,
|
||||
|
||||
publisher_id: null,
|
||||
ad_width: null,
|
||||
ad_height: null,
|
||||
|
||||
adRequested: false,
|
||||
|
||||
init() {
|
||||
let config, size;
|
||||
const placement = this.get("placement");
|
||||
|
||||
if (this.site.mobileView) {
|
||||
config = MOBILE_SETTINGS[placement];
|
||||
} else {
|
||||
config = DESKTOP_SETTINGS[placement];
|
||||
}
|
||||
|
||||
if (!renderCounts[placement]) {
|
||||
renderCounts[placement] = 0;
|
||||
}
|
||||
|
||||
const sizes = (this.siteSettings[config.sizes] || "").split("|");
|
||||
|
||||
if (sizes.length === 1) {
|
||||
size = sizes[0];
|
||||
} else {
|
||||
size = sizes[renderCounts[placement] % sizes.length];
|
||||
renderCounts[placement] += 1;
|
||||
}
|
||||
|
||||
this.set("ad_width", parseAdWidth(size));
|
||||
this.set("ad_height", parseAdHeight(size));
|
||||
this.set("ad_code", this.siteSettings[config.code]);
|
||||
this.set("publisher_id", this.siteSettings.adsense_publisher_code);
|
||||
this._super();
|
||||
},
|
||||
|
||||
_triggerAds() {
|
||||
if (isTesting()) {
|
||||
return; // Don't load external JS during tests
|
||||
}
|
||||
|
||||
this.set("adRequested", true);
|
||||
loadAdsense().then(function () {
|
||||
const adsbygoogle = window.adsbygoogle || [];
|
||||
|
||||
try {
|
||||
adsbygoogle.push({}); // ask AdSense to fill one ad unit
|
||||
} catch (ex) {}
|
||||
});
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
if (!this.get("showAd")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleOnce("afterRender", this, this._triggerAds);
|
||||
},
|
||||
|
||||
@observes("listLoading")
|
||||
waitForLoad() {
|
||||
if (this.get("adRequested")) {
|
||||
return;
|
||||
} // already requested that this ad unit be populated
|
||||
if (!this.get("listLoading")) {
|
||||
scheduleOnce("afterRender", this, this._triggerAds);
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("ad_width")
|
||||
isResponsive(adWidth) {
|
||||
return ["auto", "fluid"].includes(adWidth);
|
||||
},
|
||||
|
||||
@discourseComputed("ad_width")
|
||||
isFluid(adWidth) {
|
||||
return adWidth === "fluid";
|
||||
},
|
||||
|
||||
@discourseComputed("placement", "showAd")
|
||||
classForSlot(placement, showAd) {
|
||||
return showAd ? htmlSafe(`adsense-${placement}`) : "";
|
||||
},
|
||||
|
||||
@discourseComputed("isResponsive", "isFluid")
|
||||
autoAdFormat(isResponsive, isFluid) {
|
||||
return isResponsive ? htmlSafe(isFluid ? "fluid" : "auto") : false;
|
||||
},
|
||||
|
||||
@discourseComputed("ad_width", "ad_height", "isResponsive")
|
||||
adWrapperStyle(w, h, isResponsive) {
|
||||
return htmlSafe(isResponsive ? "" : `width: ${w}; height: ${h};`);
|
||||
},
|
||||
|
||||
@discourseComputed("adWrapperStyle", "isResponsive")
|
||||
adInsStyle(adWrapperStyle, isResponsive) {
|
||||
return htmlSafe(
|
||||
`display: ${isResponsive ? "block" : "inline-block"}; ${adWrapperStyle}`
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser.trust_level")
|
||||
showToTrustLevel(trustLevel) {
|
||||
return !(
|
||||
trustLevel && trustLevel > this.siteSettings.adsense_through_trust_level
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"publisher_id",
|
||||
"showToTrustLevel",
|
||||
"showToGroups",
|
||||
"showAfterPost",
|
||||
"showOnCurrentPage"
|
||||
)
|
||||
showAd(
|
||||
publisherId,
|
||||
showToTrustLevel,
|
||||
showToGroups,
|
||||
showAfterPost,
|
||||
showOnCurrentPage
|
||||
) {
|
||||
return (
|
||||
publisherId &&
|
||||
showToTrustLevel &&
|
||||
showToGroups &&
|
||||
showAfterPost &&
|
||||
showOnCurrentPage
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("postNumber")
|
||||
showAfterPost(postNumber) {
|
||||
if (!postNumber) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.isNthPost(
|
||||
parseInt(this.siteSettings.adsense_nth_post_code, 10)
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -1,239 +0,0 @@
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
|
||||
var _loaded = false,
|
||||
_promise = null,
|
||||
currentUser = Discourse.User.current(),
|
||||
publisher_id = Discourse.SiteSettings.adsense_publisher_code;
|
||||
|
||||
const mobileView = Discourse.Site.currentProp("mobileView");
|
||||
|
||||
function parseAdWidth(value) {
|
||||
if (value === "responsive") {
|
||||
return "auto";
|
||||
}
|
||||
return `${parseInt(value.substring(0, 3).trim())}px`;
|
||||
}
|
||||
|
||||
function parseAdHeight(value) {
|
||||
if (value === "responsive") {
|
||||
return "auto";
|
||||
}
|
||||
return `${parseInt(value.substring(4, 7).trim())}px`;
|
||||
}
|
||||
|
||||
function loadAdsense() {
|
||||
if (_loaded) {
|
||||
return Ember.RSVP.resolve();
|
||||
}
|
||||
|
||||
if (_promise) {
|
||||
return _promise;
|
||||
}
|
||||
|
||||
var adsenseSrc =
|
||||
("https:" === document.location.protocol ? "https:" : "http:") +
|
||||
"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
|
||||
_promise = loadScript(adsenseSrc, { scriptTag: true }).then(function() {
|
||||
_loaded = true;
|
||||
});
|
||||
|
||||
return _promise;
|
||||
}
|
||||
|
||||
var data = {
|
||||
"topic-list-top": {},
|
||||
"topic-above-post-stream": {},
|
||||
"topic-above-suggested": {},
|
||||
"post-bottom": {}
|
||||
};
|
||||
|
||||
if (Discourse.SiteSettings.adsense_publisher_code) {
|
||||
if (!mobileView && Discourse.SiteSettings.adsense_topic_list_top_code) {
|
||||
data["topic-list-top"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_topic_list_top_code;
|
||||
data["topic-list-top"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_topic_list_top_ad_sizes
|
||||
);
|
||||
data["topic-list-top"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_topic_list_top_ad_sizes
|
||||
);
|
||||
}
|
||||
if (mobileView && Discourse.SiteSettings.adsense_mobile_topic_list_top_code) {
|
||||
data["topic-list-top"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_mobile_topic_list_top_code;
|
||||
data["topic-list-top"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_list_top_ad_size
|
||||
);
|
||||
data["topic-list-top"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_list_top_ad_size
|
||||
);
|
||||
}
|
||||
if (
|
||||
!mobileView &&
|
||||
Discourse.SiteSettings.adsense_topic_above_post_stream_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_topic_above_post_stream_code;
|
||||
data["topic-above-post-stream"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_topic_above_post_stream_ad_sizes
|
||||
);
|
||||
data["topic-above-post-stream"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_topic_above_post_stream_ad_sizes
|
||||
);
|
||||
}
|
||||
if (
|
||||
mobileView &&
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_post_stream_code
|
||||
) {
|
||||
data["topic-above-post-stream"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_post_stream_code;
|
||||
data["topic-above-post-stream"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_post_stream_ad_size
|
||||
);
|
||||
data["topic-above-post-stream"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_post_stream_ad_size
|
||||
);
|
||||
}
|
||||
if (
|
||||
!mobileView &&
|
||||
Discourse.SiteSettings.adsense_topic_above_suggested_code
|
||||
) {
|
||||
data["topic-above-suggested"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_topic_above_suggested_code;
|
||||
data["topic-above-suggested"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_topic_above_suggested_ad_sizes
|
||||
);
|
||||
data["topic-above-suggested"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_topic_above_suggested_ad_sizes
|
||||
);
|
||||
}
|
||||
if (
|
||||
mobileView &&
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_suggested_code
|
||||
) {
|
||||
data["topic-above-suggested"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_suggested_code;
|
||||
data["topic-above-suggested"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_suggested_ad_size
|
||||
);
|
||||
data["topic-above-suggested"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_mobile_topic_above_suggested_ad_size
|
||||
);
|
||||
}
|
||||
if (!mobileView && Discourse.SiteSettings.adsense_post_bottom_code) {
|
||||
data["post-bottom"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_post_bottom_code;
|
||||
data["post-bottom"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_post_bottom_ad_sizes
|
||||
);
|
||||
data["post-bottom"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_post_bottom_ad_sizes
|
||||
);
|
||||
}
|
||||
if (mobileView && Discourse.SiteSettings.adsense_mobile_post_bottom_code) {
|
||||
data["post-bottom"]["ad_code"] =
|
||||
Discourse.SiteSettings.adsense_mobile_post_bottom_code;
|
||||
data["post-bottom"]["ad_width"] = parseAdWidth(
|
||||
Discourse.SiteSettings.adsense_mobile_post_bottom_ad_size
|
||||
);
|
||||
data["post-bottom"]["ad_height"] = parseAdHeight(
|
||||
Discourse.SiteSettings.adsense_mobile_post_bottom_ad_size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [
|
||||
":google-adsense",
|
||||
"classForSlot",
|
||||
"isResponsive:adsense-responsive"
|
||||
],
|
||||
loadedGoogletag: false,
|
||||
|
||||
publisher_id: publisher_id,
|
||||
ad_width: null,
|
||||
ad_height: null,
|
||||
|
||||
adRequested: false,
|
||||
|
||||
init() {
|
||||
this.set("ad_width", data[this.placement]["ad_width"]);
|
||||
this.set("ad_height", data[this.placement]["ad_height"]);
|
||||
this.set("ad_code", data[this.placement]["ad_code"]);
|
||||
this._super();
|
||||
},
|
||||
|
||||
_triggerAds() {
|
||||
this.set("adRequested", true);
|
||||
loadAdsense().then(function() {
|
||||
const adsbygoogle = window.adsbygoogle || [];
|
||||
|
||||
try {
|
||||
adsbygoogle.push({}); // ask AdSense to fill one ad unit
|
||||
} catch (ex) {}
|
||||
});
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
if (!this.get("showAd")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
|
||||
},
|
||||
|
||||
waitForLoad: function() {
|
||||
if (this.get("adRequested")) {
|
||||
return;
|
||||
} // already requested that this ad unit be populated
|
||||
if (!this.get("listLoading")) {
|
||||
Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
|
||||
}
|
||||
}.observes("listLoading"),
|
||||
|
||||
isResponsive: function() {
|
||||
return this.get("ad_width") === "auto";
|
||||
}.property("ad_width"),
|
||||
|
||||
classForSlot: function() {
|
||||
return `adsense-${this.get("placement")}`.htmlSafe();
|
||||
}.property("placement"),
|
||||
|
||||
autoAdFormat: function() {
|
||||
return this.get("isResponsive") ? "auto".htmlSafe() : false;
|
||||
}.property("isResponsive"),
|
||||
|
||||
adWrapperStyle: function() {
|
||||
return (this.get("isResponsive")
|
||||
? ""
|
||||
: `width: ${this.get("ad_width")}; height: ${this.get("ad_height")};`
|
||||
).htmlSafe();
|
||||
}.property("ad_width", "ad_height"),
|
||||
|
||||
adInsStyle: function() {
|
||||
return `display: ${
|
||||
this.get("isResponsive") ? "block" : "inline-block"
|
||||
}; ${this.get("adWrapperStyle")}`.htmlSafe();
|
||||
}.property("adWrapperStyle", "isResponsive"),
|
||||
|
||||
checkTrustLevels: function() {
|
||||
return !(
|
||||
currentUser &&
|
||||
currentUser.get("trust_level") >
|
||||
Discourse.SiteSettings.adsense_through_trust_level
|
||||
);
|
||||
}.property("trust_level"),
|
||||
|
||||
showAd: function() {
|
||||
return (
|
||||
Discourse.SiteSettings.adsense_publisher_code &&
|
||||
this.get("checkTrustLevels")
|
||||
);
|
||||
}.property("checkTrustLevels")
|
||||
});
|
||||
+423
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { isBlank } from "@ember/utils";
|
||||
|
||||
const adIndex = {
|
||||
topic_list_top: null,
|
||||
topic_above_post_stream: null,
|
||||
topic_above_suggested: null,
|
||||
post_bottom: null,
|
||||
topic_list_between: null,
|
||||
};
|
||||
|
||||
export default AdComponent.extend({
|
||||
classNames: ["house-creative"],
|
||||
classNameBindings: ["adUnitClass"],
|
||||
attributeBindings: ["colspanAttribute:colspan"],
|
||||
adHtml: "",
|
||||
|
||||
@discourseComputed
|
||||
colspanAttribute() {
|
||||
return this.tagName === "td" ? "5" : null;
|
||||
},
|
||||
|
||||
@discourseComputed("placement", "showAd")
|
||||
adUnitClass(placement, showAd) {
|
||||
return showAd ? `house-${placement}` : "";
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"showToGroups",
|
||||
"showAfterPost",
|
||||
"showAfterTopicListItem",
|
||||
"showOnCurrentPage"
|
||||
)
|
||||
showAd(
|
||||
showToGroups,
|
||||
showAfterPost,
|
||||
showAfterTopicListItem,
|
||||
showOnCurrentPage
|
||||
) {
|
||||
return (
|
||||
showToGroups &&
|
||||
(showAfterPost || showAfterTopicListItem) &&
|
||||
showOnCurrentPage
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("postNumber", "placement")
|
||||
showAfterPost(postNumber, placement) {
|
||||
if (!postNumber && placement !== "topic-list-between") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.isNthPost(
|
||||
parseInt(this.site.get("house_creatives.settings.after_nth_post"), 10)
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("placement")
|
||||
showAfterTopicListItem(placement) {
|
||||
if (placement !== "topic-list-between") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.isNthTopicListItem(
|
||||
parseInt(this.site.get("house_creatives.settings.after_nth_topic"), 10)
|
||||
);
|
||||
},
|
||||
|
||||
chooseAdHtml() {
|
||||
const houseAds = this.site.get("house_creatives"),
|
||||
placement = this.get("placement").replace(/-/g, "_"),
|
||||
adNames = this.adsNamesForSlot(placement);
|
||||
|
||||
if (adNames.length > 0) {
|
||||
if (!adIndex[placement]) {
|
||||
adIndex[placement] = 0;
|
||||
}
|
||||
let ad = houseAds.creatives[adNames[adIndex[placement]]] || "";
|
||||
adIndex[placement] = (adIndex[placement] + 1) % adNames.length;
|
||||
return ad;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
|
||||
adsNamesForSlot(placement) {
|
||||
const houseAds = this.site.get("house_creatives");
|
||||
|
||||
if (!houseAds || !houseAds.settings) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const adsForSlot = houseAds.settings[placement];
|
||||
|
||||
if (Object.keys(houseAds.creatives).length > 0 && !isBlank(adsForSlot)) {
|
||||
return adsForSlot.split("|");
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
@observes("refreshOnChange")
|
||||
refreshAd() {
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.set("adHtml", this.chooseAdHtml());
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
if (!this.get("showAd")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adIndex.topic_list_top === null) {
|
||||
// start at a random spot in the ad inventory
|
||||
Object.keys(adIndex).forEach((placement) => {
|
||||
const adNames = this.adsNamesForSlot(placement);
|
||||
adIndex[placement] = Math.floor(Math.random() * adNames.length);
|
||||
});
|
||||
}
|
||||
|
||||
this.refreshAd();
|
||||
},
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user