mirror of
https://github.com/discourse/discourse-adplugin.git
synced 2025-06-29 18:12:11 +00:00
DEV: Update linting config and run gjs-codemod
This commit is contained in:
parent
123dc9e6d8
commit
a98a223a35
@ -1,3 +1,4 @@
|
||||
< 3.5.0.beta5-dev: bd9af0b9a577bfd2c01cc8b81a782a4e8b81b9c5
|
||||
< 3.5.0.beta1-dev: 6ceba62e985223c269782c4bc9a1bdc4a5adba28
|
||||
< 3.4.0.beta2-dev: 7685ebf396c93e8accc5a76a81fcec4384a73fa3
|
||||
< 3.4.0.beta1-dev: da38a4c053b68d7076db4441cfe86b473979945d
|
||||
|
44
Gemfile.lock
44
Gemfile.lock
@ -14,30 +14,31 @@ GEM
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
uri (>= 0.13.1)
|
||||
ast (2.4.2)
|
||||
base64 (0.2.0)
|
||||
benchmark (0.4.0)
|
||||
bigdecimal (3.1.9)
|
||||
ast (2.4.3)
|
||||
base64 (0.3.0)
|
||||
benchmark (0.4.1)
|
||||
bigdecimal (3.2.0)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.0)
|
||||
drb (2.2.1)
|
||||
connection_pool (2.5.3)
|
||||
drb (2.2.3)
|
||||
i18n (1.14.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.10.2)
|
||||
language_server-protocol (3.17.0.4)
|
||||
json (2.12.2)
|
||||
language_server-protocol (3.17.0.5)
|
||||
lint_roller (1.1.0)
|
||||
logger (1.6.6)
|
||||
logger (1.7.0)
|
||||
minitest (5.25.5)
|
||||
parallel (1.26.3)
|
||||
parser (3.3.7.1)
|
||||
parallel (1.27.0)
|
||||
parser (3.3.8.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
prettier_print (1.2.1)
|
||||
prism (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (3.1.12)
|
||||
rack (3.1.15)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.10.0)
|
||||
rubocop (1.74.0)
|
||||
rubocop (1.75.8)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
@ -45,11 +46,12 @@ GEM
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.38.1)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-ast (1.44.1)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.4)
|
||||
rubocop-capybara (2.22.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
@ -65,13 +67,13 @@ GEM
|
||||
rubocop-factory_bot (2.27.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rails (2.30.3)
|
||||
rubocop-rails (2.32.0)
|
||||
activesupport (>= 4.2.0)
|
||||
lint_roller (~> 1.1)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.72.1, < 2.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-rspec (3.5.0)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
rubocop-rspec (3.6.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec_rails (2.31.0)
|
||||
@ -97,4 +99,4 @@ DEPENDENCIES
|
||||
syntax_tree
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.6
|
||||
2.6.9
|
||||
|
@ -0,0 +1,34 @@
|
||||
import { action } from "@ember/object";
|
||||
import { mapBy } from "@ember/object/computed";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import { makeArray } from "discourse/lib/helpers";
|
||||
import HouseAdsChooser from "./house-ads-chooser";
|
||||
import HouseAdsSetting from "./house-ads-setting";
|
||||
|
||||
@classNames("house-ads-setting house-ads-list-setting")
|
||||
export default class HouseAdsListSetting extends HouseAdsSetting {
|
||||
@mapBy("allAds", "name") adNames;
|
||||
|
||||
@action
|
||||
changeAdValue(value) {
|
||||
const settingValue = makeArray(value).join("|");
|
||||
this.set("adValue", settingValue);
|
||||
}
|
||||
|
||||
<template>
|
||||
<label for={{this.name}}>{{this.title}}</label>
|
||||
<HouseAdsChooser
|
||||
@settingValue={{this.adValue}}
|
||||
@choices={{this.adNames}}
|
||||
@onChange={{this.changeAdValue}}
|
||||
/>
|
||||
<div class="setting-controls">
|
||||
{{#if this.changed}}
|
||||
<DButton class="ok" @action={{action "save"}} @icon="check" />
|
||||
<DButton class="cancel" @action={{action "cancel"}} @icon="xmark" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="help">{{this.help}}</p>
|
||||
</template>
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
import Component from "@ember/component";
|
||||
import { action } from "@ember/object";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import TextField from "discourse/components/text-field";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { i18n as computedI18n, propertyNotEqual } from "discourse/lib/computed";
|
||||
@ -55,4 +57,16 @@ export default class HouseAdsSetting extends Component {
|
||||
cancel() {
|
||||
this.set("adValue", this.get("value"));
|
||||
}
|
||||
|
||||
<template>
|
||||
<label for={{this.name}}>{{this.title}}</label>
|
||||
<TextField @value={{this.adValue}} @classNames="house-ads-text-input" />
|
||||
<div class="setting-controls">
|
||||
{{#if this.changed}}
|
||||
<DButton class="ok" @action={{action "save"}} @icon="check" />
|
||||
<DButton class="cancel" @action={{action "cancel"}} @icon="xmark" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="help">{{this.help}}</p>
|
||||
</template>
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import routeAction from "discourse/helpers/route-action";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import HouseAdsListSetting from "../components/house-ads-list-setting";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
<section class="house-ads-settings content-body">
|
||||
<div>{{i18n "admin.adplugin.house_ads.description"}}</div>
|
||||
|
||||
{{#if @controller.houseAds.length}}
|
||||
<form class="form-horizontal">
|
||||
<HouseAdsListSetting
|
||||
@name="topic_list_top"
|
||||
@value={{@controller.adSettings.topic_list_top}}
|
||||
@allAds={{@controller.houseAds}}
|
||||
@adSettings={{@controller.adSettings}}
|
||||
/>
|
||||
<HouseAdsListSetting
|
||||
@name="topic_above_post_stream"
|
||||
@value={{@controller.adSettings.topic_above_post_stream}}
|
||||
@allAds={{@controller.houseAds}}
|
||||
@adSettings={{@controller.adSettings}}
|
||||
/>
|
||||
<HouseAdsListSetting
|
||||
@name="topic_above_suggested"
|
||||
@value={{@controller.adSettings.topic_above_suggested}}
|
||||
@allAds={{@controller.houseAds}}
|
||||
@adSettings={{@controller.adSettings}}
|
||||
/>
|
||||
<HouseAdsListSetting
|
||||
@name="post_bottom"
|
||||
@value={{@controller.adSettings.post_bottom}}
|
||||
@allAds={{@controller.houseAds}}
|
||||
@adSettings={{@controller.adSettings}}
|
||||
/>
|
||||
<HouseAdsListSetting
|
||||
@name="topic_list_between"
|
||||
@value={{@controller.adSettings.topic_list_between}}
|
||||
@allAds={{@controller.houseAds}}
|
||||
@adSettings={{@controller.adSettings}}
|
||||
/>
|
||||
|
||||
<DButton
|
||||
@label="admin.adplugin.house_ads.more_settings"
|
||||
@icon="gear"
|
||||
@action={{routeAction "moreSettings"}}
|
||||
class="btn-default"
|
||||
/>
|
||||
</form>
|
||||
{{else}}
|
||||
<p>
|
||||
{{#LinkTo route="adminPlugins.houseAds.show" model="new"}}
|
||||
{{i18n "admin.adplugin.house_ads.get_started"}}
|
||||
{{/LinkTo}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
</template>
|
||||
);
|
@ -0,0 +1,97 @@
|
||||
import { Input } from "@ember/component";
|
||||
import { fn, hash } from "@ember/helper";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import AceEditor from "discourse/components/ace-editor";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import TextField from "discourse/components/text-field";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import GroupChooser from "select-kit/components/group-chooser";
|
||||
import HouseAdsCategorySelector from "../components/house-ads-category-selector";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
<section class="edit-house-ad content-body">
|
||||
<h1><TextField
|
||||
@value={{@controller.buffered.name}}
|
||||
class="house-ad-name"
|
||||
/></h1>
|
||||
<div class="controls">
|
||||
<AceEditor
|
||||
@content={{@controller.buffered.html}}
|
||||
@onChange={{fn (mut @controller.buffered.html)}}
|
||||
@mode="html"
|
||||
/>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="visibility-settings">
|
||||
<div>
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{@controller.buffered.visible_to_logged_in_users}}
|
||||
class="visible-to-logged-in-checkbox"
|
||||
/>
|
||||
<span>{{i18n
|
||||
"admin.adplugin.house_ads.show_to_logged_in_users"
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Input
|
||||
class="visible-to-anonymous-checkbox"
|
||||
@type="checkbox"
|
||||
@checked={{@controller.buffered.visible_to_anons}}
|
||||
/>
|
||||
<span>{{i18n "admin.adplugin.house_ads.show_to_anons"}}</span>
|
||||
</div>
|
||||
|
||||
<HouseAdsCategorySelector
|
||||
@categories={{@controller.site.categories}}
|
||||
@selectedCategories={{@controller.selectedCategories}}
|
||||
@onChange={{@controller.setCategoryIds}}
|
||||
@options={{hash allowAny=true}}
|
||||
class="house-ads-categories"
|
||||
/>
|
||||
<div class="description">
|
||||
{{i18n "admin.adplugin.house_ads.category_chooser_description"}}
|
||||
</div>
|
||||
|
||||
<GroupChooser
|
||||
@content={{@controller.site.groups}}
|
||||
@onChange={{@controller.setGroupIds}}
|
||||
@value={{@controller.selectedGroups}}
|
||||
class="banner-groups"
|
||||
/>
|
||||
<div class="description">
|
||||
{{i18n "admin.adplugin.house_ads.group_chooser_description"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DButton
|
||||
@action={{@controller.save}}
|
||||
@disabled={{@controller.disabledSave}}
|
||||
@label="admin.adplugin.house_ads.save"
|
||||
class="btn-primary save-button"
|
||||
/>
|
||||
|
||||
{{#if @controller.saving}}
|
||||
{{@controller.savingStatus}}
|
||||
{{else}}
|
||||
{{#unless @controller.disabledSave}}
|
||||
<DButton @action={{@controller.cancel}} @label="cancel" />
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@action={{@controller.openPreview}}
|
||||
@label="admin.adplugin.house_ads.preview"
|
||||
/>
|
||||
|
||||
<DButton
|
||||
@action={{@controller.destroy}}
|
||||
@label="admin.adplugin.house_ads.delete"
|
||||
class="btn-danger delete-button"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
);
|
@ -0,0 +1,43 @@
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
<div class="adplugin-mgmt">
|
||||
<h1>{{i18n "admin.adplugin.house_ads.title"}}</h1>
|
||||
{{#if @controller.model.length}}
|
||||
<div class="content-list">
|
||||
<div class="house-ads-actions">
|
||||
<LinkTo
|
||||
@route="adminPlugins.houseAds.show"
|
||||
@model="new"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
{{icon "plus"}}
|
||||
<span>{{i18n "admin.adplugin.house_ads.new"}}</span>
|
||||
</LinkTo>
|
||||
<LinkTo
|
||||
@route="adminPlugins.houseAds.index"
|
||||
class="btn btn-default"
|
||||
>
|
||||
{{icon "gear"}}
|
||||
<span>{{i18n "admin.adplugin.house_ads.settings"}}</span>
|
||||
</LinkTo>
|
||||
</div>
|
||||
<ul class="house-ads-list">
|
||||
{{#each @controller.model as |ad|}}
|
||||
<li class="house-ads-list-item">
|
||||
{{#LinkTo route="adminPlugins.houseAds.show" model=ad.id}}
|
||||
{{ad.name}}
|
||||
{{/LinkTo}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{outlet}}
|
||||
</div>
|
||||
</template>
|
||||
);
|
@ -1,13 +0,0 @@
|
||||
<label for={{this.name}}>{{this.title}}</label>
|
||||
{{house-ads-chooser
|
||||
settingValue=this.adValue
|
||||
choices=this.adNames
|
||||
onChange=this.changeAdValue
|
||||
}}
|
||||
<div class="setting-controls">
|
||||
{{#if this.changed}}
|
||||
<DButton class="ok" @action={{action "save"}} @icon="check" />
|
||||
<DButton class="cancel" @action={{action "cancel"}} @icon="xmark" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="help">{{this.help}}</p>
|
@ -1,16 +0,0 @@
|
||||
import { action } from "@ember/object";
|
||||
import { mapBy } from "@ember/object/computed";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import { makeArray } from "discourse/lib/helpers";
|
||||
import HouseAdsSetting from "discourse/plugins/discourse-adplugin/discourse/components/house-ads-setting";
|
||||
|
||||
@classNames("house-ads-setting house-ads-list-setting")
|
||||
export default class HouseAdsListSetting extends HouseAdsSetting {
|
||||
@mapBy("allAds", "name") adNames;
|
||||
|
||||
@action
|
||||
changeAdValue(value) {
|
||||
const settingValue = makeArray(value).join("|");
|
||||
this.set("adValue", settingValue);
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
<label for={{this.name}}>{{this.title}}</label>
|
||||
<TextField @value={{this.adValue}} @classNames="house-ads-text-input" />
|
||||
<div class="setting-controls">
|
||||
{{#if this.changed}}
|
||||
<DButton class="ok" @action={{action "save"}} @icon="check" />
|
||||
<DButton class="cancel" @action={{action "cancel"}} @icon="xmark" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="help">{{this.help}}</p>
|
@ -1,51 +0,0 @@
|
||||
<section class="house-ads-settings content-body">
|
||||
<div>{{i18n "admin.adplugin.house_ads.description"}}</div>
|
||||
|
||||
{{#if this.houseAds.length}}
|
||||
<form class="form-horizontal">
|
||||
{{house-ads-list-setting
|
||||
name="topic_list_top"
|
||||
value=this.adSettings.topic_list_top
|
||||
allAds=this.houseAds
|
||||
adSettings=this.adSettings
|
||||
}}
|
||||
{{house-ads-list-setting
|
||||
name="topic_above_post_stream"
|
||||
value=this.adSettings.topic_above_post_stream
|
||||
allAds=this.houseAds
|
||||
adSettings=this.adSettings
|
||||
}}
|
||||
{{house-ads-list-setting
|
||||
name="topic_above_suggested"
|
||||
value=this.adSettings.topic_above_suggested
|
||||
allAds=this.houseAds
|
||||
adSettings=this.adSettings
|
||||
}}
|
||||
{{house-ads-list-setting
|
||||
name="post_bottom"
|
||||
value=this.adSettings.post_bottom
|
||||
allAds=this.houseAds
|
||||
adSettings=this.adSettings
|
||||
}}
|
||||
{{house-ads-list-setting
|
||||
name="topic_list_between"
|
||||
value=this.adSettings.topic_list_between
|
||||
allAds=this.houseAds
|
||||
adSettings=this.adSettings
|
||||
}}
|
||||
|
||||
<DButton
|
||||
@label="admin.adplugin.house_ads.more_settings"
|
||||
@icon="gear"
|
||||
@action={{route-action "moreSettings"}}
|
||||
class="btn-default"
|
||||
/>
|
||||
</form>
|
||||
{{else}}
|
||||
<p>
|
||||
{{#link-to route="adminPlugins.houseAds.show" model="new"}}
|
||||
{{i18n "admin.adplugin.house_ads.get_started"}}
|
||||
{{/link-to}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</section>
|
@ -1,78 +0,0 @@
|
||||
<section class="edit-house-ad content-body">
|
||||
<h1><TextField @value={{this.buffered.name}} class="house-ad-name" /></h1>
|
||||
<div class="controls">
|
||||
<AceEditor
|
||||
@content={{this.buffered.html}}
|
||||
@onChange={{fn (mut this.buffered.html)}}
|
||||
@mode="html"
|
||||
/>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="visibility-settings">
|
||||
<div>
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{this.buffered.visible_to_logged_in_users}}
|
||||
class="visible-to-logged-in-checkbox"
|
||||
/>
|
||||
<span>{{i18n "admin.adplugin.house_ads.show_to_logged_in_users"}}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Input
|
||||
class="visible-to-anonymous-checkbox"
|
||||
@type="checkbox"
|
||||
@checked={{this.buffered.visible_to_anons}}
|
||||
/>
|
||||
<span>{{i18n "admin.adplugin.house_ads.show_to_anons"}}</span>
|
||||
</div>
|
||||
|
||||
<HouseAdsCategorySelector
|
||||
@categories={{this.site.categories}}
|
||||
@selectedCategories={{this.selectedCategories}}
|
||||
@onChange={{this.setCategoryIds}}
|
||||
@options={{hash allowAny=true}}
|
||||
class="house-ads-categories"
|
||||
/>
|
||||
<div class="description">
|
||||
{{i18n "admin.adplugin.house_ads.category_chooser_description"}}
|
||||
</div>
|
||||
|
||||
<GroupChooser
|
||||
@content={{this.site.groups}}
|
||||
@onChange={{this.setGroupIds}}
|
||||
@value={{this.selectedGroups}}
|
||||
class="banner-groups"
|
||||
/>
|
||||
<div class="description">
|
||||
{{i18n "admin.adplugin.house_ads.group_chooser_description"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DButton
|
||||
@action={{this.save}}
|
||||
@disabled={{this.disabledSave}}
|
||||
@label="admin.adplugin.house_ads.save"
|
||||
class="btn-primary save-button"
|
||||
/>
|
||||
|
||||
{{#if this.saving}}
|
||||
{{this.savingStatus}}
|
||||
{{else}}
|
||||
{{#unless this.disabledSave}}
|
||||
<DButton @action={{this.cancel}} @label="cancel" />
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@action={{this.openPreview}}
|
||||
@label="admin.adplugin.house_ads.preview"
|
||||
/>
|
||||
|
||||
<DButton
|
||||
@action={{this.destroy}}
|
||||
@label="admin.adplugin.house_ads.delete"
|
||||
class="btn-danger delete-button"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
@ -1,31 +0,0 @@
|
||||
<div class="adplugin-mgmt">
|
||||
<h1>{{i18n "admin.adplugin.house_ads.title"}}</h1>
|
||||
{{#if this.model.length}}
|
||||
<div class="content-list">
|
||||
<div class="house-ads-actions">
|
||||
<LinkTo
|
||||
@route="adminPlugins.houseAds.show"
|
||||
@model="new"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
{{d-icon "plus"}}
|
||||
<span>{{i18n "admin.adplugin.house_ads.new"}}</span>
|
||||
</LinkTo>
|
||||
<LinkTo @route="adminPlugins.houseAds.index" class="btn btn-default">
|
||||
{{d-icon "gear"}}
|
||||
<span>{{i18n "admin.adplugin.house_ads.settings"}}</span>
|
||||
</LinkTo>
|
||||
</div>
|
||||
<ul class="house-ads-list">
|
||||
{{#each this.model as |ad|}}
|
||||
<li class="house-ads-list-item">
|
||||
{{#link-to route="adminPlugins.houseAds.show" model=ad.id}}
|
||||
{{ad.name}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{outlet}}
|
||||
</div>
|
@ -1,13 +1,26 @@
|
||||
import { array } from "@ember/helper";
|
||||
import EmberObject from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import { tagName } from "@ember-decorators/component";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import {
|
||||
isNthPost,
|
||||
isNthTopicListItem,
|
||||
} from "discourse/plugins/discourse-adplugin/discourse/helpers/slot-position";
|
||||
import { isNthPost, isNthTopicListItem } from "../helpers/slot-position";
|
||||
import AdComponent from "./ad-component";
|
||||
import AdbutlerAd from "./adbutler-ad";
|
||||
import AmazonProductLinks from "./amazon-product-links";
|
||||
import CarbonadsAd from "./carbonads-ad";
|
||||
import GoogleAdsense from "./google-adsense";
|
||||
import GoogleDfpAd from "./google-dfp-ad";
|
||||
import HouseAd from "./house-ad";
|
||||
|
||||
const AD_COMPONENTS = {
|
||||
"house-ad": HouseAd,
|
||||
"google-adsense": GoogleAdsense,
|
||||
"google-dfp-ad": GoogleDfpAd,
|
||||
"amazon-product-links": AmazonProductLinks,
|
||||
"carbonads-ad": CarbonadsAd,
|
||||
"adbutler-ad": AdbutlerAd,
|
||||
};
|
||||
|
||||
const adConfig = EmberObject.create({
|
||||
"google-adsense": {
|
||||
@ -201,7 +214,7 @@ export default class AdSlot extends AdComponent {
|
||||
* Depends on `router.currentRoute` so that we refresh ads when navigating around.
|
||||
*/
|
||||
@discourseComputed("placement", "availableAdTypes", "router.currentRoute")
|
||||
adComponents(placement, availableAdTypes) {
|
||||
adComponentNames(placement, availableAdTypes) {
|
||||
if (
|
||||
!availableAdTypes.includes("house-ad") ||
|
||||
availableAdTypes.length === 1
|
||||
@ -240,4 +253,23 @@ export default class AdSlot extends AdComponent {
|
||||
|
||||
return networkNames;
|
||||
}
|
||||
|
||||
get adComponents() {
|
||||
return this.adComponentNames.map((name) => AD_COMPONENTS[name]);
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#each this.adComponents as |Ad|}}
|
||||
{{! Trick to force full destroy/re-render of component when route changes }}
|
||||
{{#each (array this.router.currentRoute)}}
|
||||
<Ad
|
||||
@placement={{this.placement}}
|
||||
@category={{this.category}}
|
||||
@postNumber={{this.postNumber}}
|
||||
@indexNumber={{this.indexNumber}}
|
||||
@tagName={{this.childTagName}}
|
||||
/>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</template>
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{{#each this.adComponents as |adComponent|}}
|
||||
{{! Trick to force full destroy/re-render of component when route changes }}
|
||||
{{#each (array this.router.currentRoute)}}
|
||||
{{component
|
||||
adComponent
|
||||
placement=this.placement
|
||||
category=this.category
|
||||
postNumber=this.postNumber
|
||||
indexNumber=this.indexNumber
|
||||
tagName=this.childTagName
|
||||
}}
|
||||
{{/each}}
|
||||
{{/each}}
|
@ -3,7 +3,7 @@ import RSVP from "rsvp";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import { isTesting } from "discourse/lib/environment";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
let _loaded = false,
|
||||
_promise = null,
|
||||
@ -150,4 +150,10 @@ export default class AdbutlerAd extends AdComponent {
|
||||
}
|
||||
return this.isNthPost(parseInt(this.siteSettings.adbutler_nth_post, 10));
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
<div id={{this.divId}} class={{this.className}}></div>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
<div id={{this.divId}} class={{this.className}}></div>
|
||||
{{/if}}
|
@ -2,7 +2,8 @@ import { and } from "@ember/object/computed";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
@classNames("amazon-product-links")
|
||||
export default class AmazonProductLinks extends AdComponent {
|
||||
@ -186,4 +187,41 @@ export default class AmazonProductLinks extends AdComponent {
|
||||
|
||||
return this.isNthPost(parseInt(this.siteSettings.amazon_nth_post_code, 10));
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
{{#if this.site.mobileView}}
|
||||
<div
|
||||
class="amazon-product-links-label"
|
||||
style={{this.adTitleStyleMobile}}
|
||||
><h2>{{i18n "adplugin.advertisement_label"}}</h2></div>
|
||||
<iframe
|
||||
style={{this.adWrapperStyleMobile}}
|
||||
marginwidth="0"
|
||||
marginheight="0"
|
||||
scrolling="no"
|
||||
frameborder="0"
|
||||
src={{this.userInputMobile}}
|
||||
title={{i18n "adplugin.advertisement_label"}}
|
||||
>
|
||||
</iframe>
|
||||
{{else}}
|
||||
<div class="amazon-product-links-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div class="container" align="center">
|
||||
<iframe
|
||||
style={{this.adWrapperStyle}}
|
||||
marginwidth="0"
|
||||
marginheight="0"
|
||||
scrolling="no"
|
||||
frameborder="0"
|
||||
src={{this.userInput}}
|
||||
title={{i18n "adplugin.advertisement_label"}}
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
{{#if this.site.mobileView}}
|
||||
<div
|
||||
class="amazon-product-links-label"
|
||||
style={{this.adTitleStyleMobile}}
|
||||
><h2>{{i18n "adplugin.advertisement_label"}}</h2></div>
|
||||
<iframe
|
||||
style={{this.adWrapperStyleMobile}}
|
||||
marginwidth="0"
|
||||
marginheight="0"
|
||||
scrolling="no"
|
||||
frameborder="0"
|
||||
src={{this.userInputMobile}}
|
||||
title={{i18n "adplugin.advertisement_label"}}
|
||||
>
|
||||
</iframe>
|
||||
{{else}}
|
||||
<div class="amazon-product-links-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div class="container" align="center">
|
||||
<iframe
|
||||
style={{this.adWrapperStyle}}
|
||||
marginwidth="0"
|
||||
marginheight="0"
|
||||
scrolling="no"
|
||||
frameborder="0"
|
||||
src={{this.userInput}}
|
||||
title={{i18n "adplugin.advertisement_label"}}
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
@ -1,6 +1,6 @@
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
export default class CarbonadsAd extends AdComponent {
|
||||
serve_id = null;
|
||||
@ -40,4 +40,12 @@ export default class CarbonadsAd extends AdComponent {
|
||||
placement && serveId && showCarbonAds && showToGroups && showOnCurrentPage
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
{{! template-lint-disable no-forbidden-elements }}
|
||||
<script src={{this.url}} id="_carbonads_js" async type="text/javascript">
|
||||
</script>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
{{! template-lint-disable no-forbidden-elements }}
|
||||
<script src={{this.url}} id="_carbonads_js" async type="text/javascript">
|
||||
</script>
|
||||
{{/if}}
|
@ -5,7 +5,8 @@ import RSVP from "rsvp";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import { isTesting } from "discourse/lib/environment";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
let _loaded = false,
|
||||
_promise = null,
|
||||
@ -247,4 +248,26 @@ export default class GoogleAdsense extends AdComponent {
|
||||
parseInt(this.siteSettings.adsense_nth_post_code, 10)
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
<div class="google-adsense-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div
|
||||
class="google-adsense-content"
|
||||
id={{if this.isResponsive "google-adsense__responsive"}}
|
||||
style={{this.adWrapperStyle}}
|
||||
>
|
||||
<ins
|
||||
class="adsbygoogle"
|
||||
style={{this.adInsStyle}}
|
||||
data-ad-client="ca-pub-{{this.publisher_id}}"
|
||||
data-ad-slot={{this.ad_code}}
|
||||
data-ad-format={{this.autoAdFormat}}
|
||||
>
|
||||
</ins>
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
<div class="google-adsense-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div
|
||||
class="google-adsense-content"
|
||||
id={{if this.isResponsive "google-adsense__responsive"}}
|
||||
style={{this.adWrapperStyle}}
|
||||
>
|
||||
<ins
|
||||
class="adsbygoogle"
|
||||
style={{this.adInsStyle}}
|
||||
data-ad-client="ca-pub-{{this.publisher_id}}"
|
||||
data-ad-slot={{this.ad_code}}
|
||||
data-ad-format={{this.autoAdFormat}}
|
||||
>
|
||||
</ins>
|
||||
</div>
|
||||
{{/if}}
|
28
assets/javascripts/discourse/components/google-dfp-ad.js → assets/javascripts/discourse/components/google-dfp-ad.gjs
Executable file → Normal file
28
assets/javascripts/discourse/components/google-dfp-ad.js → assets/javascripts/discourse/components/google-dfp-ad.gjs
Executable file → Normal file
@ -5,7 +5,8 @@ import RSVP from "rsvp";
|
||||
import discourseComputed, { on } from "discourse/lib/decorators";
|
||||
import { isTesting } from "discourse/lib/environment";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
let _loaded = false,
|
||||
_promise = null,
|
||||
@ -427,4 +428,29 @@ export default class GoogleDfpAd extends AdComponent {
|
||||
cleanup() {
|
||||
destroySlot(this.get("divId"));
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
{{#if this.site.mobileView}}
|
||||
<div class="google-dfp-ad-label" style={{this.adTitleStyleMobile}}><h2
|
||||
>{{i18n "adplugin.advertisement_label"}}</h2></div>
|
||||
<div
|
||||
id={{this.divId}}
|
||||
style={{this.adWrapperStyle}}
|
||||
class="dfp-ad-unit"
|
||||
align="center"
|
||||
></div>
|
||||
{{else}}
|
||||
<div class="google-dfp-ad-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div
|
||||
id={{this.divId}}
|
||||
style={{this.adWrapperStyle}}
|
||||
class="dfp-ad-unit"
|
||||
align="center"
|
||||
></div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
{{#if this.site.mobileView}}
|
||||
<div class="google-dfp-ad-label" style={{this.adTitleStyleMobile}}><h2
|
||||
>{{i18n "adplugin.advertisement_label"}}</h2></div>
|
||||
<div
|
||||
id={{this.divId}}
|
||||
style={{this.adWrapperStyle}}
|
||||
class="dfp-ad-unit"
|
||||
align="center"
|
||||
></div>
|
||||
{{else}}
|
||||
<div class="google-dfp-ad-label"><h2>{{i18n
|
||||
"adplugin.advertisement_label"
|
||||
}}</h2></div>
|
||||
<div
|
||||
id={{this.divId}}
|
||||
style={{this.adWrapperStyle}}
|
||||
class="dfp-ad-unit"
|
||||
align="center"
|
||||
></div>
|
||||
{{/if}}
|
||||
{{/if}}
|
@ -4,8 +4,9 @@ import {
|
||||
classNameBindings,
|
||||
classNames,
|
||||
} from "@ember-decorators/component";
|
||||
import htmlSafe from "discourse/helpers/html-safe";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import AdComponent from "./ad-component";
|
||||
|
||||
const adIndex = {
|
||||
topic_list_top: null,
|
||||
@ -146,4 +147,10 @@ export default class HouseAd extends AdComponent {
|
||||
|
||||
this.refreshAd();
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.showAd}}
|
||||
{{htmlSafe this.adHtml}}
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{{#if this.showAd}}
|
||||
{{html-safe this.adHtml}}
|
||||
{{/if}}
|
11
assets/javascripts/discourse/components/post-bottom-ad.gjs
Normal file
11
assets/javascripts/discourse/components/post-bottom-ad.gjs
Normal file
@ -0,0 +1,11 @@
|
||||
import AdSlot from "./ad-slot";
|
||||
|
||||
const PostBottomAd = <template>
|
||||
<AdSlot
|
||||
@placement="post-bottom"
|
||||
@category={{@model.topic.category.slug}}
|
||||
@postNumber={{@model.post_number}}
|
||||
/>
|
||||
</template>;
|
||||
|
||||
export default PostBottomAd;
|
@ -1,5 +0,0 @@
|
||||
{{ad-slot
|
||||
placement="post-bottom"
|
||||
category=@model.topic.category.slug
|
||||
postNumber=@model.post_number
|
||||
}}
|
@ -0,0 +1,29 @@
|
||||
import Component from "@ember/component";
|
||||
import { classNames, tagName } from "@ember-decorators/component";
|
||||
import { slotContenders } from "discourse/plugins/discourse-adplugin/discourse/components/ad-slot";
|
||||
import AdSlot from "../../components/ad-slot";
|
||||
|
||||
@tagName("tr")
|
||||
@classNames("after-topic-list-item-outlet", "discourse-adplugin")
|
||||
export default class DiscourseAdplugin extends Component {
|
||||
static shouldRender(args, context) {
|
||||
return (
|
||||
args.index &&
|
||||
slotContenders(
|
||||
context.site,
|
||||
context.siteSettings,
|
||||
"topic-list-between",
|
||||
args.index
|
||||
).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
<AdSlot
|
||||
@placement="topic-list-between"
|
||||
@category={{this.category.slug}}
|
||||
@indexNumber={{this.index}}
|
||||
@childTagName="td"
|
||||
/>
|
||||
</template>
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
{{ad-slot
|
||||
placement="topic-list-between"
|
||||
category=this.category.slug
|
||||
indexNumber=this.index
|
||||
childTagName="td"
|
||||
}}
|
@ -1,15 +0,0 @@
|
||||
import { slotContenders } from "discourse/plugins/discourse-adplugin/discourse/components/ad-slot";
|
||||
|
||||
export default {
|
||||
shouldRender(args, component) {
|
||||
return (
|
||||
args.index &&
|
||||
slotContenders(
|
||||
component.site,
|
||||
component.siteSettings,
|
||||
"topic-list-between",
|
||||
args.index
|
||||
).length > 0
|
||||
);
|
||||
},
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
import Component from "@ember/component";
|
||||
import { classNames, tagName } from "@ember-decorators/component";
|
||||
import AdSlot from "../../components/ad-slot";
|
||||
|
||||
@tagName("span")
|
||||
@classNames("discovery-list-container-top-outlet", "discourse-adplugin")
|
||||
export default class DiscourseAdplugin extends Component {
|
||||
<template>
|
||||
<AdSlot @placement="topic-list-top" @category={{this.category.slug}} />
|
||||
</template>
|
||||
}
|
@ -1 +0,0 @@
|
||||
{{ad-slot placement="topic-list-top" category=this.category.slug}}
|
@ -0,0 +1,14 @@
|
||||
import Component from "@ember/component";
|
||||
import { classNames, tagName } from "@ember-decorators/component";
|
||||
import AdSlot from "../../components/ad-slot";
|
||||
|
||||
@tagName("div")
|
||||
@classNames("topic-above-post-stream-outlet", "discourse-adplugin")
|
||||
export default class DiscourseAdplugin extends Component {
|
||||
<template>
|
||||
<AdSlot
|
||||
@placement="topic-above-post-stream"
|
||||
@category={{this.model.category.slug}}
|
||||
/>
|
||||
</template>
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{{ad-slot
|
||||
placement="topic-above-post-stream"
|
||||
category=this.model.category.slug
|
||||
}}
|
@ -0,0 +1,14 @@
|
||||
import Component from "@ember/component";
|
||||
import { classNames, tagName } from "@ember-decorators/component";
|
||||
import AdSlot from "../../components/ad-slot";
|
||||
|
||||
@tagName("div")
|
||||
@classNames("topic-above-suggested-outlet", "discourse-adplugin")
|
||||
export default class DiscourseAdplugin extends Component {
|
||||
<template>
|
||||
<AdSlot
|
||||
@placement="topic-above-suggested"
|
||||
@category={{this.model.category.slug}}
|
||||
/>
|
||||
</template>
|
||||
}
|
@ -1 +0,0 @@
|
||||
{{ad-slot placement="topic-above-suggested" category=this.model.category.slug}}
|
@ -1,3 +1,5 @@
|
||||
@use "lib/viewport";
|
||||
|
||||
.google-dfp-ad {
|
||||
padding: 3px 0;
|
||||
margin-bottom: 10px;
|
||||
@ -57,7 +59,7 @@
|
||||
padding: 0 11px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 775px) {
|
||||
@media all and (width <= 775px) {
|
||||
.google-adsense.adsense-post-bottom {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
@ -100,7 +102,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(mobile-extra-large) {
|
||||
@include viewport.until(sm) {
|
||||
.google-dfp-ad .google-dfp-ad-label {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
@ -132,7 +134,7 @@
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@include breakpoint(mobile-extra-large) {
|
||||
@include viewport.until(sm) {
|
||||
.house-creative.house-post-bottom {
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
@ -208,7 +210,7 @@
|
||||
margin: 10px 0 10px 56px;
|
||||
}
|
||||
|
||||
@include breakpoint(mobile-extra-large) {
|
||||
@include viewport.until(sm) {
|
||||
.adbutler-post-bottom {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@discourse/lint-configs": "2.11.1",
|
||||
"ember-template-lint": "7.0.1",
|
||||
"eslint": "9.22.0",
|
||||
"@discourse/lint-configs": "2.23.0",
|
||||
"ember-template-lint": "7.7.0",
|
||||
"eslint": "9.28.0",
|
||||
"prettier": "3.5.3",
|
||||
"stylelint": "16.16.0"
|
||||
"stylelint": "16.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 22",
|
||||
|
881
pnpm-lock.yaml
generated
881
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe "Admin House Ad", type: :system, js: true do
|
||||
describe "Admin House Ad", type: :system do
|
||||
fab!(:admin)
|
||||
let(:house_ad) do
|
||||
AdPlugin::HouseAd.create(
|
||||
@ -14,7 +14,7 @@ describe "Admin House Ad", type: :system, js: true do
|
||||
before { sign_in(admin) }
|
||||
|
||||
describe "when visiting the page for creating new ads" do
|
||||
it "should have the visibility checkboxes on by default" do
|
||||
it "has the visibility checkboxes on by default" do
|
||||
visit("/admin/plugins/pluginad/house_creatives/new")
|
||||
|
||||
expect(find("input.visible-to-anonymous-checkbox").checked?).to eq(true)
|
||||
|
Loading…
x
Reference in New Issue
Block a user