add: user settings following page
add: comments to be seen by owner of the post they're on (even if the owner is private)
This commit is contained in:
parent
fa1a609bf5
commit
b8b0ef7f21
4 changed files with 154 additions and 7 deletions
|
@ -44,12 +44,23 @@
|
||||||
<span>{{ text "settings:tab.security" }}</span>
|
<span>{{ text "settings:tab.security" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
data-tab-button="account/following"
|
||||||
|
href="#/account/following"
|
||||||
|
>
|
||||||
|
{{ icon "rss" }}
|
||||||
|
<span>{{ text "auth:label.following" }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a data-tab-button="account/blocks" href="#/account/blocks">
|
<a data-tab-button="account/blocks" href="#/account/blocks">
|
||||||
{{ icon "shield" }}
|
{{ icon "shield" }}
|
||||||
<span>{{ text "settings:tab.blocks" }}</span>
|
<span>{{ text "settings:tab.blocks" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a data-tab-button="account/uploads" href="#/account/uploads">
|
<a
|
||||||
|
data-tab-button="account/uploads"
|
||||||
|
href="?page=0#/account/uploads"
|
||||||
|
>
|
||||||
{{ icon "image-up" }}
|
{{ icon "image-up" }}
|
||||||
<span>{{ text "settings:tab.uploads" }}</span>
|
<span>{{ text "settings:tab.uploads" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -357,6 +368,74 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full flex flex-col gap-2 hidden" data-tab="account/following">
|
||||||
|
<div class="card tertiary flex flex-col gap-2">
|
||||||
|
<a href="#/account" class="button secondary">
|
||||||
|
{{ icon "arrow-left" }}
|
||||||
|
<span>{{ text "general:action.back" }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="card-nest">
|
||||||
|
<div class="card flex items-center gap-2 small">
|
||||||
|
{{ icon "rss" }}
|
||||||
|
<span>{{ text "auth:label.following" }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card flex flex-col gap-2">
|
||||||
|
{% for userfollow in following %} {% set user =
|
||||||
|
userfollow[1] %}
|
||||||
|
<div
|
||||||
|
class="card secondary flex flex-wrap gap-2 items-center justify-between"
|
||||||
|
>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
{{ components::avatar(username=user.username) }} {{
|
||||||
|
components::full_username(user=user) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button
|
||||||
|
class="quaternary red small"
|
||||||
|
onclick="toggle_follow_user('{{ user.id }}')"
|
||||||
|
>
|
||||||
|
{{ icon "user-minus" }}
|
||||||
|
<span>{{ text "auth:action.unfollow" }}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="/@{{ user.username }}"
|
||||||
|
class="button quaternary small"
|
||||||
|
>
|
||||||
|
{{ icon "external-link" }}
|
||||||
|
<span
|
||||||
|
>{{ text "requests:action.view_profile"
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
globalThis.toggle_follow_user = async (uid) => {
|
||||||
|
await trigger("atto::debounce", ["users::follow"]);
|
||||||
|
|
||||||
|
fetch(`/api/v1/auth/user/${uid}/follow`, {
|
||||||
|
method: "POST",
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
trigger("atto::toast", [
|
||||||
|
res.ok ? "success" : "error",
|
||||||
|
res.message,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="w-full flex flex-col gap-2 hidden" data-tab="account/blocks">
|
<div class="w-full flex flex-col gap-2 hidden" data-tab="account/blocks">
|
||||||
<div class="card tertiary flex flex-col gap-2">
|
<div class="card tertiary flex flex-col gap-2">
|
||||||
<a href="#/account" class="button secondary">
|
<a href="#/account" class="button secondary">
|
||||||
|
|
|
@ -666,8 +666,6 @@ pub async fn post_request(
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
};
|
};
|
||||||
|
|
||||||
check_user_blocked_or_private!(user, owner, data, jar);
|
|
||||||
|
|
||||||
if owner.permissions.check_banned() {
|
if owner.permissions.check_banned() {
|
||||||
if let Some(ref ua) = user {
|
if let Some(ref ua) = user {
|
||||||
if !ua.permissions.check(FinePermission::MANAGE_POSTS) {
|
if !ua.permissions.check(FinePermission::MANAGE_POSTS) {
|
||||||
|
@ -682,6 +680,27 @@ pub async fn post_request(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the user has a private account OR if we're blocked...
|
||||||
|
// don't do this check if we're the owner of the post this post is replying to
|
||||||
|
if let Some(ref ua) = user {
|
||||||
|
if let Some(replying) = post.replying_to {
|
||||||
|
if replying != 0 {
|
||||||
|
let replying_to = match data.0.get_post_by_id(replying).await {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
|
};
|
||||||
|
|
||||||
|
if replying_to.owner != ua.id {
|
||||||
|
check_user_blocked_or_private!(user, owner, data, jar);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
check_user_blocked_or_private!(user, owner, data, jar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
check_user_blocked_or_private!(user, owner, data, jar);
|
||||||
|
}
|
||||||
|
|
||||||
// check repost
|
// check repost
|
||||||
let reposting = data.0.get_post_reposting(&post, &ignore_users, &user).await;
|
let reposting = data.0.get_post_reposting(&post, &ignore_users, &user).await;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,20 @@ pub async fn settings_request(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let following = match data
|
||||||
|
.0
|
||||||
|
.fill_userfollows_with_receiver(
|
||||||
|
data.0
|
||||||
|
.get_userfollows_by_initiator_all(profile.id)
|
||||||
|
.await
|
||||||
|
.unwrap_or(Vec::new()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &None).await)),
|
||||||
|
};
|
||||||
|
|
||||||
let blocks = match data
|
let blocks = match data
|
||||||
.0
|
.0
|
||||||
.fill_userblocks_receivers(data.0.get_userblocks_by_initiator(profile.id).await)
|
.fill_userblocks_receivers(data.0.get_userblocks_by_initiator(profile.id).await)
|
||||||
|
@ -82,6 +96,7 @@ pub async fn settings_request(
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
context.insert("uploads", &uploads);
|
context.insert("uploads", &uploads);
|
||||||
context.insert("stacks", &stacks);
|
context.insert("stacks", &stacks);
|
||||||
|
context.insert("following", &following);
|
||||||
context.insert("blocks", &blocks);
|
context.insert("blocks", &blocks);
|
||||||
context.insert(
|
context.insert(
|
||||||
"user_tokens_serde",
|
"user_tokens_serde",
|
||||||
|
|
|
@ -21,6 +21,39 @@ use rusqlite::Row;
|
||||||
#[cfg(feature = "postgres")]
|
#[cfg(feature = "postgres")]
|
||||||
use tokio_postgres::Row;
|
use tokio_postgres::Row;
|
||||||
|
|
||||||
|
macro_rules! private_post_replying {
|
||||||
|
($post:ident, $replying_posts:ident, $ua1:ident, $data:ident) => {
|
||||||
|
// post owner is not following us
|
||||||
|
// check if we're the owner of the post the post is replying to
|
||||||
|
// all routes but 1 must lead to continue
|
||||||
|
if let Some(replying) = $post.replying_to {
|
||||||
|
if replying != 0 {
|
||||||
|
if let Some(post) = $replying_posts.get(&replying) {
|
||||||
|
// we've seen this post before
|
||||||
|
if post.owner != $ua1.id {
|
||||||
|
// we aren't the owner of this post,
|
||||||
|
// so we can't see their comment
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we haven't seen this post before
|
||||||
|
let post = $data.get_post_by_id(replying).await?;
|
||||||
|
|
||||||
|
if post.owner != $ua1.id {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$replying_posts.insert(post.id, post);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl DataManager {
|
impl DataManager {
|
||||||
/// Get a [`Post`] from an SQL row.
|
/// Get a [`Post`] from an SQL row.
|
||||||
pub(crate) fn get_post_from_row(
|
pub(crate) fn get_post_from_row(
|
||||||
|
@ -176,6 +209,7 @@ impl DataManager {
|
||||||
|
|
||||||
let mut users: HashMap<usize, User> = HashMap::new();
|
let mut users: HashMap<usize, User> = HashMap::new();
|
||||||
let mut seen_user_follow_statuses: HashMap<(usize, usize), bool> = HashMap::new();
|
let mut seen_user_follow_statuses: HashMap<(usize, usize), bool> = HashMap::new();
|
||||||
|
let mut replying_posts: HashMap<usize, Post> = HashMap::new();
|
||||||
|
|
||||||
for post in posts {
|
for post in posts {
|
||||||
if post.is_deleted {
|
if post.is_deleted {
|
||||||
|
@ -216,11 +250,10 @@ impl DataManager {
|
||||||
seen_user_follow_statuses.get(&(ua.id, ua1.id))
|
seen_user_follow_statuses.get(&(ua.id, ua1.id))
|
||||||
{
|
{
|
||||||
if !is_following
|
if !is_following
|
||||||
&& (ua.id != ua1.id)
|
&& ua.id != ua1.id
|
||||||
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
||||||
{
|
{
|
||||||
// post owner is not following us
|
private_post_replying!(post, replying_posts, ua1, self);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if self
|
if self
|
||||||
|
@ -228,10 +261,11 @@ impl DataManager {
|
||||||
.await
|
.await
|
||||||
.is_err()
|
.is_err()
|
||||||
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
||||||
|
&& ua.id != ua1.id
|
||||||
{
|
{
|
||||||
// post owner is not following us
|
// post owner is not following us
|
||||||
seen_user_follow_statuses.insert((ua.id, ua1.id), false);
|
seen_user_follow_statuses.insert((ua.id, ua1.id), false);
|
||||||
continue;
|
private_post_replying!(post, replying_posts, ua1, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
seen_user_follow_statuses.insert((ua.id, ua1.id), true);
|
seen_user_follow_statuses.insert((ua.id, ua1.id), true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue