add: store ad clicked state in cookies
This commit is contained in:
parent
83971b3d20
commit
befd9096b1
5 changed files with 119 additions and 65 deletions
|
@ -24,32 +24,18 @@
|
||||||
(text "{{ icon \"ellipsis\" }}"))
|
(text "{{ icon \"ellipsis\" }}"))
|
||||||
(div
|
(div
|
||||||
("class" "inner")
|
("class" "inner")
|
||||||
(text "{% if user.id == channel.owner -%} {% if selected_community == 0 %}")
|
|
||||||
(button
|
(button
|
||||||
("class" "lowered small")
|
("onclick" "trigger('atto::copy_text', ['{{ channel.id }}'])")
|
||||||
|
(icon (text "copy"))
|
||||||
|
(str (text "general:action.copy_id")))
|
||||||
|
(text "{% if user.id == channel.owner or can_manage_channels -%}")
|
||||||
|
; owner/manager controls
|
||||||
|
(button
|
||||||
("onclick" "add_member('{{ channel.id }}')")
|
("onclick" "add_member('{{ channel.id }}')")
|
||||||
(text "{{ icon \"user-plus\" }}")
|
(text "{{ icon \"user-plus\" }}")
|
||||||
(span
|
(span
|
||||||
(text "{{ text \"chats:action.add_someone\" }}")))
|
(text "{{ text \"chats:action.add_someone\" }}")))
|
||||||
; mute/unmute
|
|
||||||
(button
|
(button
|
||||||
("class" "lowered small {% if channel.id in user.channel_mutes -%} hidden {%- endif %}")
|
|
||||||
("ui_ident" "channel.mute:{{ channel.id }}")
|
|
||||||
("onclick" "mute_channel('{{ channel.id }}')")
|
|
||||||
(icon (text "bell-off"))
|
|
||||||
(span
|
|
||||||
(str (text "chats:action.mute"))))
|
|
||||||
(button
|
|
||||||
("class" "lowered small {% if not channel.id in user.channel_mutes -%} hidden {%- endif %}")
|
|
||||||
("ui_ident" "channel.unmute:{{ channel.id }}")
|
|
||||||
("onclick" "mute_channel('{{ channel.id }}', false)")
|
|
||||||
(icon (text "bell-ring"))
|
|
||||||
(span
|
|
||||||
(str (text "chats:action.unmute"))))
|
|
||||||
; ...
|
|
||||||
(text "{%- endif %}")
|
|
||||||
(button
|
|
||||||
("class" "lowered small")
|
|
||||||
("onclick" "update_channel_title('{{ channel.id }}')")
|
("onclick" "update_channel_title('{{ channel.id }}')")
|
||||||
(text "{{ icon \"pencil\" }}")
|
(text "{{ icon \"pencil\" }}")
|
||||||
(span
|
(span
|
||||||
|
@ -60,14 +46,32 @@
|
||||||
(text "{{ icon \"trash\" }}")
|
(text "{{ icon \"trash\" }}")
|
||||||
(span
|
(span
|
||||||
(text "{{ text \"general:action.delete\" }}")))
|
(text "{{ text \"general:action.delete\" }}")))
|
||||||
(text "{% elif selected_community == 0 %}")
|
(text "{%- endif %} {% if selected_community == 0 %}")
|
||||||
|
; mute/unmute
|
||||||
|
(button
|
||||||
|
("class" "{% if channel.id in user.channel_mutes -%} hidden {%- endif %}")
|
||||||
|
("ui_ident" "channel.mute:{{ channel.id }}")
|
||||||
|
("onclick" "mute_channel('{{ channel.id }}')")
|
||||||
|
(icon (text "bell-off"))
|
||||||
|
(span
|
||||||
|
(str (text "chats:action.mute"))))
|
||||||
|
(button
|
||||||
|
("class" "{% if not channel.id in user.channel_mutes -%} hidden {%- endif %}")
|
||||||
|
("ui_ident" "channel.unmute:{{ channel.id }}")
|
||||||
|
("onclick" "mute_channel('{{ channel.id }}', false)")
|
||||||
|
(icon (text "bell-ring"))
|
||||||
|
(span
|
||||||
|
(str (text "chats:action.unmute"))))
|
||||||
|
; ...
|
||||||
|
(text "{% if user.id != channel.owner -%}")
|
||||||
|
; group chat member controls
|
||||||
(button
|
(button
|
||||||
("onclick" "kick_member('{{ channel.id }}', '{{ user.id }}')")
|
("onclick" "kick_member('{{ channel.id }}', '{{ user.id }}')")
|
||||||
("class" "red")
|
("class" "red")
|
||||||
(text "{{ icon \"door-open\" }}")
|
(text "{{ icon \"door-open\" }}")
|
||||||
(span
|
(span
|
||||||
(text "{{ text \"chats:action.leave\" }}")))
|
(text "{{ text \"chats:action.leave\" }}")))
|
||||||
(text "{%- endif %}"))))
|
(text "{%- endif %} {%- endif %}"))))
|
||||||
(text "{% endfor %}"))
|
(text "{% endfor %}"))
|
||||||
(text "{% if selected_community == 0 and selected_channel -%}")
|
(text "{% if selected_community == 0 and selected_channel -%}")
|
||||||
(div
|
(div
|
||||||
|
|
|
@ -1210,6 +1210,8 @@
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
(div
|
(div
|
||||||
("class" "flex gap_2 hidden")
|
("class" "flex gap_2 hidden")
|
||||||
|
("onclick" "window.EMOJI_PICKER_REACTION_MESSAGE_ID = '{{ message.id }}'")
|
||||||
|
(text "{{ self::emoji_picker(element_id=\"react_emoji_picker_field\", render_dialog=false, render_button=true, small=true) }}")
|
||||||
(text "{{ self::message_actions(owner=user, message=message, can_manage_message=can_manage_message) }}")))
|
(text "{{ self::message_actions(owner=user, message=message, can_manage_message=can_manage_message) }}")))
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
(div
|
(div
|
||||||
|
@ -1232,14 +1234,12 @@
|
||||||
("ui_ident" "emoji_{{ emoji }}")
|
("ui_ident" "emoji_{{ emoji }}")
|
||||||
("onclick" "trigger('me::message_react', [event.target.parentElement.parentElement, '{{ message.id }}', '{{ emoji }}'])")
|
("onclick" "trigger('me::message_react', [event.target.parentElement.parentElement, '{{ message.id }}', '{{ emoji }}'])")
|
||||||
(span (text "{{ emoji|emojis|safe }} {{ num }}")))
|
(span (text "{{ emoji|emojis|safe }} {{ num }}")))
|
||||||
(text "{%- endfor %}")
|
(text "{%- endfor %}")))
|
||||||
|
|
||||||
(div
|
|
||||||
("class" "hidden")
|
|
||||||
(text "{{ self::emoji_picker(element_id=\"react_emoji_picker_field\", render_dialog=false, render_button=true, small=true) }}"))))
|
|
||||||
(text "{% if grouped -%}")
|
(text "{% if grouped -%}")
|
||||||
(div
|
(div
|
||||||
("class" "hidden")
|
("class" "hidden flex gap_2 items_center")
|
||||||
|
("onclick" "window.EMOJI_PICKER_REACTION_MESSAGE_ID = '{{ message.id }}'")
|
||||||
|
(text "{{ self::emoji_picker(element_id=\"react_emoji_picker_field\", render_dialog=false, render_button=true, small=true) }}")
|
||||||
(text "{{ self::message_actions(owner=user, message=message, can_manage_message=can_manage_message) }}"))
|
(text "{{ self::message_actions(owner=user, message=message, can_manage_message=can_manage_message) }}"))
|
||||||
(text "{%- endif %}"))))
|
(text "{%- endif %}"))))
|
||||||
|
|
||||||
|
@ -2740,7 +2740,7 @@
|
||||||
(text "{%- endmacro %}")
|
(text "{%- endmacro %}")
|
||||||
|
|
||||||
(text "{% macro advertisement(size=\"Leaderboard\") -%}")
|
(text "{% macro advertisement(size=\"Leaderboard\") -%}")
|
||||||
(text "{% if not is_supporter and config.enable_user_ads -%}")
|
(text "{% if user and not is_supporter and config.enable_user_ads -%}")
|
||||||
(object ("class" "tetratto_ad") ("data-ad-size" "{{ size }}"))
|
(object ("class" "tetratto_ad") ("data-ad-size" "{{ size }}"))
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
(text "{%- endmacro %}")
|
(text "{%- endmacro %}")
|
||||||
|
|
|
@ -6,8 +6,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::Path,
|
extract::Path,
|
||||||
response::{IntoResponse, Redirect},
|
response::{Html, IntoResponse},
|
||||||
Extension, Json,
|
Extension, Json,
|
||||||
|
http::StatusCode,
|
||||||
};
|
};
|
||||||
use tetratto_core::model::{
|
use tetratto_core::model::{
|
||||||
economy::UserAd,
|
economy::UserAd,
|
||||||
|
@ -139,8 +140,56 @@ pub async fn click_request(
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
let user = get_user_from_token!(jar, data);
|
let user = get_user_from_token!(jar, data);
|
||||||
|
|
||||||
|
let bad_return = (
|
||||||
|
StatusCode::FOUND,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"Set-Cookie".to_string(),
|
||||||
|
format!(
|
||||||
|
"Atto-Clicked=true; Path=/api/v1/ads/host/{host}/{id}/click; Max-Age=86400"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("Location".to_string(), data.0.0.host.clone()),
|
||||||
|
],
|
||||||
|
Html(""),
|
||||||
|
);
|
||||||
|
|
||||||
|
if jar.get("Atto-Clicked").is_some() {
|
||||||
|
// we've already clicked this ad, don't charge
|
||||||
|
match data.get_ad_by_id(id).await {
|
||||||
|
Ok(x) => {
|
||||||
|
return (
|
||||||
|
StatusCode::FOUND,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"Set-Cookie".to_string(),
|
||||||
|
format!(
|
||||||
|
"Atto-Clicked=true; Path=/api/v1/ads/host/{host}/{id}/click; Max-Age=86400"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("Location".to_string(), x.target),
|
||||||
|
],
|
||||||
|
Html(""),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(_) => return bad_return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match data.ad_click(host, id, user).await {
|
match data.ad_click(host, id, user).await {
|
||||||
Ok(t) => Redirect::to(&t),
|
Ok(t) => (
|
||||||
Err(_) => Redirect::to(&data.0.0.host),
|
StatusCode::FOUND,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"Set-Cookie".to_string(),
|
||||||
|
format!(
|
||||||
|
"Atto-Clicked=true; Path=/api/v1/ads/host/{host}/{id}/click; Max-Age=86400"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("Location".to_string(), t),
|
||||||
|
],
|
||||||
|
Html(""),
|
||||||
|
),
|
||||||
|
Err(_) => bad_return,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,12 +348,25 @@ pub async fn channels_request(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let membership = match data
|
||||||
|
.0
|
||||||
|
.get_membership_by_owner_community(user.id, community)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let can_manage_channels = membership.role.check(CommunityPermission::MANAGE_CHANNELS)
|
||||||
|
| user.permissions.check(FinePermission::MANAGE_CHANNELS);
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||||
|
|
||||||
context.insert("channels", &channels);
|
context.insert("channels", &channels);
|
||||||
context.insert("page", &props.page);
|
context.insert("page", &props.page);
|
||||||
|
|
||||||
|
context.insert("can_manage_channels", &can_manage_channels);
|
||||||
context.insert("members", &members);
|
context.insert("members", &members);
|
||||||
context.insert("channel", &channel);
|
context.insert("channel", &channel);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use axum::{
|
||||||
};
|
};
|
||||||
use crate::cookie::CookieJar;
|
use crate::cookie::CookieJar;
|
||||||
use tetratto_core::model::{
|
use tetratto_core::model::{
|
||||||
economy::{CoinTransferMethod, UserAd, UserAdSize},
|
economy::{CoinTransferMethod, UserAdSize},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use crate::{assets::initial_context, get_lang, get_user_from_token, State};
|
use crate::{assets::initial_context, get_lang, get_user_from_token, State};
|
||||||
|
@ -254,18 +254,17 @@ pub async fn random_ad_request(
|
||||||
Query(props): Query<RandomAdQuery>,
|
Query(props): Query<RandomAdQuery>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = data.read().await;
|
let data = data.read().await;
|
||||||
|
let headers = [(
|
||||||
|
"content-security-policy",
|
||||||
|
"default-src 'self' *.spotify.com musicbrainz.org; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' *; script-src 'self' 'unsafe-inline' *; worker-src * blob:; object-src 'self' *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: *; frame-ancestors *",
|
||||||
|
)];
|
||||||
|
|
||||||
let ad = match data.0.random_ad_charged(props.size.clone()).await {
|
let ad = match data.0.random_ad_charged(props.size.clone()).await {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(_) => UserAd {
|
Err(_) => {
|
||||||
id: 0,
|
// no ad found, show nothing
|
||||||
created: 0,
|
return (headers, Html(String::new()));
|
||||||
upload_id: 0,
|
}
|
||||||
owner: data.0.0.0.system_user,
|
|
||||||
target: data.0.0.0.host.clone(),
|
|
||||||
last_charge_time: 0,
|
|
||||||
is_running: true,
|
|
||||||
size: props.size,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
|
@ -276,10 +275,7 @@ pub async fn random_ad_request(
|
||||||
|
|
||||||
// return
|
// return
|
||||||
(
|
(
|
||||||
[(
|
headers,
|
||||||
"content-security-policy",
|
|
||||||
"default-src 'self' *.spotify.com musicbrainz.org; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' *; script-src 'self' 'unsafe-inline' *; worker-src * blob:; object-src 'self' *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: *; frame-ancestors *",
|
|
||||||
)],
|
|
||||||
Html(data.1.render("economy/ad.html", &context).unwrap()),
|
Html(data.1.render("economy/ad.html", &context).unwrap()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -291,19 +287,17 @@ pub async fn known_ad_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = data.read().await;
|
let data = data.read().await;
|
||||||
|
let headers = [
|
||||||
|
(
|
||||||
|
"content-security-policy",
|
||||||
|
"default-src 'self' *.spotify.com musicbrainz.org; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' *; script-src 'self' 'unsafe-inline' *; worker-src * blob:; object-src 'self' *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: *; frame-ancestors *",
|
||||||
|
),
|
||||||
|
("Cache-Control", "no-cache"),
|
||||||
|
];
|
||||||
|
|
||||||
let ad = match data.0.get_ad_by_id(id).await {
|
let ad = match data.0.get_ad_by_id(id).await {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(_) => UserAd {
|
Err(_) => return (headers, Html(String::new())),
|
||||||
// polyfill ad
|
|
||||||
id: 0,
|
|
||||||
created: 0,
|
|
||||||
upload_id: 0,
|
|
||||||
owner: data.0.0.0.system_user,
|
|
||||||
target: data.0.0.0.host.clone(),
|
|
||||||
last_charge_time: 0,
|
|
||||||
is_running: true,
|
|
||||||
size: props.size,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
|
@ -314,13 +308,7 @@ pub async fn known_ad_request(
|
||||||
|
|
||||||
// return
|
// return
|
||||||
(
|
(
|
||||||
[
|
headers,
|
||||||
(
|
|
||||||
"content-security-policy",
|
|
||||||
"default-src 'self' *.spotify.com musicbrainz.org; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' *; script-src 'self' 'unsafe-inline' *; worker-src * blob:; object-src 'self' *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: *; frame-ancestors *",
|
|
||||||
),
|
|
||||||
("Cache-Control", "no-cache"),
|
|
||||||
],
|
|
||||||
Html(data.1.render("economy/ad.html", &context).unwrap()),
|
Html(data.1.render("economy/ad.html", &context).unwrap()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue