add: user ads
This commit is contained in:
parent
46b3e66cd4
commit
2cb7d08ddc
41 changed files with 1095 additions and 29 deletions
|
@ -1,5 +1,10 @@
|
|||
@import url("root.css");
|
||||
|
||||
/* ads */
|
||||
.tetratto_ad iframe {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
/* media gallery */
|
||||
.media_gallery {
|
||||
display: grid;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
(div ("id" "toast_zone"))
|
||||
|
||||
; ads
|
||||
(script ("src" "/js/ads.js?v=tetratto-{{ random_cache_breaker }}"))
|
||||
(script
|
||||
(text "TetrattoAds.init();"))
|
||||
|
||||
; large text
|
||||
(text "{% if user and user.settings.large_text -%}")
|
||||
(style
|
||||
|
@ -76,6 +81,8 @@
|
|||
return;
|
||||
}
|
||||
|
||||
TetrattoAds.render_ads(\"{{ config.system_user }}\", \"\");
|
||||
|
||||
atto.disconnect_observers();
|
||||
atto.remove_false_options();
|
||||
atto.clean_date_codes();
|
||||
|
|
|
@ -182,7 +182,7 @@
|
|||
(text "{%- endif %} {%- endif %}")
|
||||
(button
|
||||
("class" "primary")
|
||||
(text "{{ text \"communities:action.create\" }}"))))))
|
||||
(str (text "communities:action.create")))))))
|
||||
(text "{% if not quoting -%}")
|
||||
(script
|
||||
(text "async function create_post_from_form(e) {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
(span
|
||||
(text "Make this a forum community")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{% if list|length >= 4 -%} {{ components::supporter_ad(body=\"Become a supporter to create up to 10 communities!\") }} {%- endif %} {%- endif %}")
|
||||
(div
|
||||
("class" "card_nest w_full")
|
||||
|
|
|
@ -302,7 +302,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "32")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{% for channel in channels %}")
|
||||
(div
|
||||
("class" "card_nest")
|
||||
|
@ -472,7 +472,7 @@
|
|||
("accept" "image/png,image/jpeg,image/avif,image/webp")
|
||||
("class" "w_full")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))
|
||||
(str (text "communities:action.create")))
|
||||
(span
|
||||
("class" "fade")
|
||||
(text "Emojis can be a maximum of 256 KiB."))))
|
||||
|
@ -646,7 +646,7 @@
|
|||
("min" "0")
|
||||
("max" "256")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{% for id, topic in community.topics %}")
|
||||
(div
|
||||
("class" "card_nest")
|
||||
|
|
|
@ -894,7 +894,7 @@
|
|||
(div
|
||||
("class" "flex gap_2")
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))
|
||||
(str (text "communities:action.create")))
|
||||
|
||||
(text "{% if drawing_enabled -%}")
|
||||
(button
|
||||
|
@ -2494,6 +2494,11 @@
|
|||
(li
|
||||
(text "Create and sell CSS snippet products"))
|
||||
|
||||
(text "{% if config.enable_user_ads -%}")
|
||||
(li
|
||||
(text "No ads"))
|
||||
(text "{%- endif %}")
|
||||
|
||||
(text "{% if config.security.enable_invite_codes -%}")
|
||||
(li
|
||||
(text "Create up to 48 invite codes")
|
||||
|
@ -2709,3 +2714,33 @@
|
|||
(icon (text "badge-cent"))
|
||||
(text "{{ product.price }}")))
|
||||
(text "{%- endmacro %}")
|
||||
|
||||
(text "{% macro ad_listing_card(ad) -%}")
|
||||
(a
|
||||
("class" "card button lowered w_full flex flex_col gap_2")
|
||||
("href" "/product/ad/{{ ad.id }}/edit")
|
||||
(b
|
||||
("class" "flex gap_2 items_center")
|
||||
("style" "height: 24px; text-decoration: {% if not ad.is_running -%} line-through {%- else -%} none {%- endif %}")
|
||||
(icon (text "link"))
|
||||
(text "{{ ad.target }}"))
|
||||
(b
|
||||
("style" "height: 18px")
|
||||
(text "{% if ad.is_running -%}")
|
||||
(span
|
||||
("class" "green flex gap_2 items_center")
|
||||
(icon (text "circle-check"))
|
||||
(text "Running"))
|
||||
(text "{% else %}")
|
||||
(span
|
||||
("class" "red flex gap_2 items_center")
|
||||
(icon (text "circle-x"))
|
||||
(text "Not running"))
|
||||
(text "{%- endif %}")))
|
||||
(text "{%- endmacro %}")
|
||||
|
||||
(text "{% macro advertisement(size=\"Leaderboard\") -%}")
|
||||
(text "{% if not is_supporter and config.enable_user_ads -%}")
|
||||
(object ("class" "tetratto_ad") ("data-ad-size" "{{ size }}"))
|
||||
(text "{%- endif %}")
|
||||
(text "{%- endmacro %}")
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
("placeholder" "redirect URL")
|
||||
("minlength" "2")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
|
||||
; app listing
|
||||
(div
|
||||
|
|
62
crates/app/src/public/html/economy/ad.lisp
Normal file
62
crates/app/src/public/html/economy/ad.lisp
Normal file
|
@ -0,0 +1,62 @@
|
|||
(text "<!doctype html>")
|
||||
(html
|
||||
("lang" "en")
|
||||
(head
|
||||
(meta ("charset" "UTF-8"))
|
||||
(meta ("name" "viewport") ("content" "width=device-width, initial-scale=1.0"))
|
||||
(meta ("http-equiv" "X-UA-Compatible") ("content" "ie=edge")))
|
||||
(body
|
||||
(a
|
||||
("href" "{% if not disable_click -%} {{ config.host }}/api/v1/ads/host/{{ host }}/{{ ad.id }}/click {%- endif %}")
|
||||
("title" "Advertisement")
|
||||
("target" "_blank")
|
||||
("class" "ad"))
|
||||
|
||||
(span ("class" "display_tag") (text "Ad"))
|
||||
|
||||
(style
|
||||
(text "* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.15px;
|
||||
font-family:
|
||||
\"Inter\", \"Poppins\", \"Roboto\", ui-sans-serif, system-ui, sans-serif,
|
||||
\"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",
|
||||
\"Noto Color Emoji\";
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
a.ad {
|
||||
display: inline;
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
background-image: url(\"{{ config.host|safe }}/api/v1/uploads/{{ ad.upload_id }}\");
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.display_tag {
|
||||
position: absolute;
|
||||
bottom: 0.5rem;
|
||||
left: 0.5rem;
|
||||
padding: 0.15rem 0.5rem;
|
||||
background: hsla(0, 0%, 0%, 50%);
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
font-size: 10px;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
border-radius: 0.4rem;
|
||||
box-shadow: 0 0 2px hsla(0, 0%, 0%, 25%);
|
||||
}"))))
|
97
crates/app/src/public/html/economy/edit_ad.lisp
Normal file
97
crates/app/src/public/html/economy/edit_ad.lisp
Normal file
|
@ -0,0 +1,97 @@
|
|||
(text "{% extends \"root.html\" %} {% block head %}")
|
||||
(title
|
||||
(text "Manage advertisement - {{ config.name }}"))
|
||||
(text "{% endblock %} {% block body %} {{ macros::nav(selected=\"\") }}")
|
||||
(main
|
||||
("class" "flex flex_col gap_2")
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
("class" "card small flex gap_2 items_center")
|
||||
(icon (text "link"))
|
||||
(b
|
||||
(text "{{ ad.target }}")))
|
||||
(form
|
||||
("class" "card flex flex_col gap_2")
|
||||
("onsubmit" "event.preventDefault(); update_is_running_from_form(event.target.is_running.checked)")
|
||||
(object ("class" "tetratto_ad") ("data-ad-size" "{{ ad.size }}") ("data-noclick" "true") ("data-ad-id" "{{ ad.id }}"))
|
||||
(ul
|
||||
(li
|
||||
(text "{% if ad.last_charge_time != 0 -%}")
|
||||
(text "Last charge: ") (span ("class" "date") (text "{{ ad.last_charge_time }}"))
|
||||
(text "{% else %}")
|
||||
(text "No previous charges")
|
||||
(text "{%- endif %}")))
|
||||
(div ("class" "squig"))
|
||||
(p (text "Each day your ad is viewed, you'll be charged 25 coins. This charge only applies to the very first view of the day."))
|
||||
(p (text "Additionally, you'll be charged 2 coins per click on your ad. This fee will be paid to the user which hosts the site your ad was shown on."))
|
||||
(p (text "Each of these transfers will be shown in your wallet's transfer table as either \"AdClick\" or \"AdCharge\"."))
|
||||
(label
|
||||
("for" "is_running")
|
||||
("class" "flex items_center gap_2")
|
||||
(input
|
||||
("type" "checkbox")
|
||||
("id" "is_running")
|
||||
("name" "is_running")
|
||||
("class" "w_content")
|
||||
("checked" "{{ ad.is_running }}"))
|
||||
(span
|
||||
(str (text "economy:label.running"))))
|
||||
(button (str (text "general:action.save")))))
|
||||
|
||||
(div
|
||||
("class" "flex gap_2")
|
||||
(a
|
||||
("class" "button secondary")
|
||||
("href" "/products")
|
||||
(icon (text "arrow-left"))
|
||||
(str (text "general:action.back")))
|
||||
|
||||
(button
|
||||
("class" "lowered red")
|
||||
("onclick" "delete_ad()")
|
||||
(icon (text "trash"))
|
||||
(str (text "general:action.delete")))))
|
||||
|
||||
(script
|
||||
(text "async function update_is_running_from_form(is_running) {
|
||||
await trigger(\"atto::debounce\", [\"products::update\"]);
|
||||
fetch(\"/api/v1/ads/{{ ad.id }}/running\", {
|
||||
method: \"POST\",
|
||||
headers: {
|
||||
\"Content-Type\": \"application/json\",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
is_running,
|
||||
}),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
trigger(\"atto::toast\", [
|
||||
res.ok ? \"success\" : \"error\",
|
||||
res.message,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
async function delete_ad() {
|
||||
if (
|
||||
!(await trigger(\"atto::confirm\", [
|
||||
\"Are you sure you would like to do this?\",
|
||||
]))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(\"/api/v1/ads/{{ ad.id }}\", {
|
||||
method: \"DELETE\",
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
trigger(\"atto::toast\", [
|
||||
res.ok ? \"success\" : \"error\",
|
||||
res.message,
|
||||
]);
|
||||
});
|
||||
};"))
|
||||
(text "{% endblock %}")
|
|
@ -43,7 +43,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "1024")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
|
||||
; product listing
|
||||
(div
|
||||
|
@ -56,7 +56,105 @@
|
|||
(div
|
||||
("class" "card flex flex_col gap_2")
|
||||
(text "{% for item in list %} {{ components::product_listing_card(product=item, edit=true) }} {% endfor %}")
|
||||
(text "{{ components::pagination(page=page, items=list|length) }}"))))
|
||||
; selective pagination
|
||||
(text "{% if page_set_id == 0 -%}")
|
||||
(text "{{ components::pagination(page=page, items=list|length) }}")
|
||||
(text "{% else %}")
|
||||
(text "{{ components::pagination(page=0, items=list|length) }}")
|
||||
(text "{%- endif %}")))
|
||||
|
||||
(text "{% if config.enable_user_ads -%}")
|
||||
(div ("class" "squig") ("style" "--background: var(--color-surface)"))
|
||||
|
||||
; create new ad
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
("class" "card small")
|
||||
(b
|
||||
(str (text "economy:label.create_new_ad"))))
|
||||
(form
|
||||
("class" "card flex flex_col gap_2")
|
||||
("onsubmit" "create_ad_from_form(event)")
|
||||
(div
|
||||
("class" "flex flex_col gap_1")
|
||||
(label
|
||||
("for" "target")
|
||||
(str (text "economy:label.target")))
|
||||
(input
|
||||
("type" "url")
|
||||
("name" "target")
|
||||
("id" "target")
|
||||
("placeholder" "target url")
|
||||
("required" "")
|
||||
("minlength" "2")
|
||||
("maxlength" "128")))
|
||||
(div
|
||||
("class" "flex flex_col gap_1")
|
||||
(label
|
||||
("for" "file")
|
||||
(str (text "economy:label.image")))
|
||||
(input
|
||||
("id" "file")
|
||||
("name" "file")
|
||||
("type" "file")
|
||||
("accept" "image/png,image/jpeg,image/avif,image/webp,image/gif")
|
||||
("required" "")
|
||||
("class" "w_content")))
|
||||
(div
|
||||
("class" "flex flex_col gap_1")
|
||||
(label
|
||||
("for" "size_base")
|
||||
(str (text "economy:label.size_base")))
|
||||
(select
|
||||
("id" "size_base")
|
||||
("name" "size_base")
|
||||
(option ("value" "Leaderboard") (text "Leaderboard (720x90)"))
|
||||
(option ("value" "Billboard") (text "Billboard (970x250)"))
|
||||
(option ("value" "Skyscraper") (text "Skyscraper (160x600)"))
|
||||
(option ("value" "MediumRectangle") (text "Medium rectangle (300x250)"))
|
||||
(option ("value" "MobileLeaderboard") (text "Mobile leaderboard (320x50, mobile only)"))))
|
||||
(button
|
||||
(str (text "communities:action.create")))))
|
||||
|
||||
; ad listing
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
("class" "card small flex items_center gap_2")
|
||||
(icon (text "images"))
|
||||
(str (text "economy:label.my_ads")))
|
||||
|
||||
(div
|
||||
("class" "card flex flex_col gap_2")
|
||||
(text "{% for item in ads_list %} {{ components::ad_listing_card(ad=item) }} {% endfor %}")
|
||||
; selective pagination
|
||||
(text "{% if page_set_id == 1 -%}")
|
||||
(text "{{ components::pagination(page=page, items=ads_list|length, key=\"&page_set_id=1\") }}")
|
||||
(text "{% else %}")
|
||||
(text "{{ components::pagination(page=0, items=ads_list|length, key=\"&page_set_id=1\") }}")
|
||||
(text "{%- endif %}")))
|
||||
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
("class" "card small flex items_center gap_2")
|
||||
(icon (text "code"))
|
||||
(str (text "economy:label.embed_ads_on_my_site")))
|
||||
|
||||
(div
|
||||
("class" "card flex flex_col gap_2")
|
||||
(p (text "You can embed the advertising network into your site to earn a (coin) commission from clicks."))
|
||||
(p (text "Place the following into your site's HTML:"))
|
||||
(pre (code (text "<script src=\"{{ config.host }}\"/js/ads.js\"></script>
|
||||
<script>TetrattoAds.init(); TetrattoAds.render_ads(\"{{ user.id }}\", \"{{ config.host }}\")</script>")))
|
||||
(p (text "After you've done that, you can place your ads like so:"))
|
||||
(pre (code (text "<object class=\"tetratto_ad\" data-ad-size=\"$size$\"></object>")))
|
||||
(p
|
||||
(text "In the above example, replace \"$size$\" with a size from ")
|
||||
(a ("href" "https://tetratto.com/reference/tetratto/model/economy/enum.UserAdSize.html") (text "here"))
|
||||
(text " keep in mind that the name of a size must be in title case. That means it's \"Leaderboard\", not \"leaderboard\"."))))
|
||||
(text "{%- endif %}"))
|
||||
|
||||
(script
|
||||
(text "async function create_product_from_form(e) {
|
||||
|
@ -87,5 +185,43 @@
|
|||
}, 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function create_ad_from_form(e) {
|
||||
e.preventDefault();
|
||||
await trigger(\"atto::debounce\", [\"products::create\"]);
|
||||
|
||||
// create body
|
||||
const body = new FormData();
|
||||
|
||||
for (const file of e.target.file.files) {
|
||||
body.append(file.name, file);
|
||||
}
|
||||
|
||||
body.append(
|
||||
\"body\",
|
||||
JSON.stringify({
|
||||
target: e.target.target.value,
|
||||
size: e.target.size_base.selectedOptions[0].value,
|
||||
}),
|
||||
);
|
||||
|
||||
// ...
|
||||
fetch(\"/api/v1/ads\", {
|
||||
method: \"POST\",
|
||||
body,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
trigger(\"atto::toast\", [
|
||||
res.ok ? \"success\" : \"error\",
|
||||
res.message,
|
||||
]);
|
||||
|
||||
if (res.ok) {
|
||||
e.target.reset();
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}"))
|
||||
(text "{% endblock %}")
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
(text "{%- endif %}"))
|
||||
(td (text "{{ transfer[3].source }}"))
|
||||
(td
|
||||
(text "{% if user.id == transfer[1].id -%}")
|
||||
(text "{% if user.id == transfer[1].id and transfer[3].source == '\"Sale\"' -%}")
|
||||
; we're the receiver
|
||||
(button
|
||||
("class" "small tiny square raised camo big_icon")
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "32")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{% else %}")
|
||||
(text "{{ components::developer_pass_ad(body=\"Get a developer pass to create forges!\") }}")
|
||||
(text "{%- endif %}")
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
(option ("value" "{{ tld }}") (text ".{{ tld|lower }}"))
|
||||
(text "{%- endfor %}")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))
|
||||
(str (text "communities:action.create")))
|
||||
|
||||
(details
|
||||
(summary
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "32")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{%- endif %}")
|
||||
(div
|
||||
("class" "card_nest w_full")
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
("required" "")
|
||||
("minlength" "16")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}")))))
|
||||
(str (text "communities:action.create"))))))
|
||||
|
||||
(script
|
||||
(text "function create_report_from_form(e) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
("class" "lowered small")
|
||||
(text "{{ icon \"plus\" }}")
|
||||
(span
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(div
|
||||
("class" "card flex flex_col gap_2")
|
||||
(text "{% for item in items %}")
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "4096")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
("class" "flex gap_2")
|
||||
(text "{{ components::emoji_picker(element_id=\"content\", render_dialog=true) }} {% if is_supporter -%} {{ components::file_picker(files_list_id=\"files_list\") }} {% endif %}")
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}")))))
|
||||
(str (text "communities:action.create"))))))
|
||||
(text "{%- endif %}")
|
||||
(div
|
||||
("class" "pillmenu")
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
("minlength" "2")
|
||||
("maxlength" "32")))
|
||||
(button
|
||||
(text "{{ text \"communities:action.create\" }}"))))
|
||||
(str (text "communities:action.create")))))
|
||||
(text "{%- endif %}")
|
||||
(div
|
||||
("class" "card_nest w_full")
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
(text "{% endblock %} {% block body %} {{ macros::nav() }}")
|
||||
(main
|
||||
("class" "flex flex_col gap_2")
|
||||
(text "{{ macros::timelines_nav(selected=\"all\", posts=\"/all\", questions=\"/all/questions\", forum_posts=\"/all/forum_posts\") }} {% if not user -%}")
|
||||
(text "{{ macros::timelines_nav(selected=\"all\", posts=\"/all\", questions=\"/all/questions\", forum_posts=\"/all/forum_posts\") }}")
|
||||
(text "{{ components::advertisement(size=\"Leaderboard\") }}")
|
||||
(text "{% if not user -%}")
|
||||
(div
|
||||
("class" "card_nest")
|
||||
(div
|
||||
|
|
65
crates/app/src/public/js/ads.js
Normal file
65
crates/app/src/public/js/ads.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
globalThis.TetrattoAds = {
|
||||
AD_SIZES: {
|
||||
Billboard: [970, 250],
|
||||
Leaderboard: [720, 90],
|
||||
Skyscraper: [160, 600],
|
||||
MediumRectangle: [300, 250],
|
||||
MobileLeaderboard: [320, 50],
|
||||
},
|
||||
IS_MOBILE: window.innerWidth <= 900 && window.innerHeight <= 900,
|
||||
};
|
||||
|
||||
globalThis.TetrattoAds.init = () => {
|
||||
const styles = document.createElement("style");
|
||||
styles.id = "tetratto_ads_css";
|
||||
styles.setAttribute("data-turbo-permanent", "true");
|
||||
|
||||
styles.innerHTML = `.tetratto_ad {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.tetratto_ad,
|
||||
.tetratto_ad iframe {
|
||||
max-width: 100%;
|
||||
background: transparent;
|
||||
}`;
|
||||
|
||||
document.head.appendChild(styles);
|
||||
};
|
||||
|
||||
globalThis.TetrattoAds.render_ads = (
|
||||
host_id = 0,
|
||||
tetratto = "https://tetratto.com",
|
||||
) => {
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll(".tetratto_ad"),
|
||||
)) {
|
||||
if (element.children.length > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
let size = element.getAttribute("data-ad-size") || "MediumRectangle";
|
||||
|
||||
if (size === "Leaderboard" && TetrattoAds.IS_MOBILE) {
|
||||
size = "MobileLeaderboard";
|
||||
}
|
||||
|
||||
const size_px = TetrattoAds.AD_SIZES[size];
|
||||
|
||||
const noclick =
|
||||
element.getAttribute("data-noclick") === "true" || false;
|
||||
const ad_id = element.getAttribute("data-ad-id");
|
||||
|
||||
iframe.src = `${tetratto}/adn/${ad_id ? ad_id : "random"}?size=${size}&host=${host_id}&noclick=${noclick}`;
|
||||
iframe.setAttribute("frameborder", "0");
|
||||
iframe.loading = "lazy";
|
||||
|
||||
iframe.style.width = `${size_px[0]}px`;
|
||||
iframe.style.height = `${size_px[1]}px`;
|
||||
|
||||
element.appendChild(iframe);
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue