Skip to content

Commit

Permalink
feat: profile publicity levels
Browse files Browse the repository at this point in the history
  • Loading branch information
vas3k committed Jul 29, 2024
1 parent 6ed3a39 commit 6c40c04
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 36 deletions.
4 changes: 3 additions & 1 deletion frontend/html/comments/list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{% load comments %}
{% for tree in comments|comment_tree %}
{% if tree.comment.author_id in muted_user_ids %}
{% if not request.me and tree.comment.author.profile_publicity_level == "private" %}
{% include "comments/types/private.html" with comment=tree.comment replies=tree.replies %}
{% elif tree.comment.author_id in muted_user_ids %}
{% include "comments/types/muted.html" with comment=tree.comment replies=tree.replies %}
{% elif tree.comment.is_pinned %}
{% include "comments/types/bold.html" with comment=tree.comment replies=tree.replies %}
Expand Down
5 changes: 5 additions & 0 deletions frontend/html/comments/types/private.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="comment" id="comment-{{ comment.id }}">
<div class="comment-body-muted">
🕵️ Юзер скрыл свои комментарии от публичного просмотра...
</div>
</div>
4 changes: 3 additions & 1 deletion frontend/html/comments/types/reply.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
{% load posts %}
{% load comments %}

{% if comment.author_id in muted_user_ids %}
{% if not request.me and comment.author.profile_publicity_level == "private" %}
{% include "comments/types/private.html" with comment=comment replies=replies %}
{% elif comment.author_id in muted_user_ids %}
{% include "comments/types/muted.html" with comment=comment replies=replies %}
{% else %}
<div class="reply {% if comment.created_at > post_last_view_at %}comment-is-new{% endif %} {% if comment.metadata.badges %}comment-is-badged{% endif %}" id="comment-{{ comment.id }}">
Expand Down
4 changes: 3 additions & 1 deletion frontend/html/posts/show/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ <h1 class="post-title">
{% endif %}

<footer class="post-footer p-author">
{% include "users/widgets/card.html" with user=post.author %}
{% if request.me or post.author.profile_publicity_level != "private" %}
{% include "users/widgets/card.html" with user=post.author %}
{% endif %}

{% if post.coauthors %}
{% for coauthor in post.coauthors_with_details %}
Expand Down
75 changes: 52 additions & 23 deletions frontend/html/users/edit/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,42 +85,71 @@
</span>
</div>

<button type="submit" class="button button-big" {% if user.is_profile_public %}name="is_profile_public" value="1"{% endif %}>Сохранить изменения</button>
<button type="submit" class="button button-big" name="profile_publicity_level" value="{{ user.profile_publicity_level }}">Сохранить изменения</button>

<div class="clearfix50"></div>
</div>

<div class="block">
<div class="block-header">🥷 Публичность профиля</div>

<div class="block-description block-description-center">
{% if form.is_profile_public.errors %}
<span class="form-row-errors">{{ form.is_profile_public.errors }}</span>
{% endif %}
<div class="block-description">
<p>
Эта настройка влияет только на то, как видят вас люди, не зарегистрированные в Клубе. Для членов Клуба ваш профиль, интро и контакты всегда доступны.
</p>

{% if user.is_profile_public %}
<p>
<p>
{% if user.profile_publicity_level == 'public' %}
Сейчас ваш профиль <strong>ОТКРЫТ</strong> для большого интернета по ссылке: <a href="{{ settings.APP_HOST }}{% url "profile" user.slug %}" target="_blank">{{ settings.APP_HOST }}{% url "profile" user.slug %}</a>
</p>
<p>
Его могут индексировать поисковики и видеть люди без регистрации в Клубе. Можете посмотреть как он выглядит со стороны через инкогнито-мод в вашем браузере.
</p>
{% else %}
<p>
Сейчас ваш профиль <strong>ЗАКРЫТ</strong> для большого интернета. Его могут просматривать только члены Клуба.
</p>
<p>
Вы можете сделать его видимым наружу. Комментарии при этом останутся скрытыми, но ваши контакты, интро, посты и награды будут видны всем.
</p>
{% endif %}
{% else %}
Сейчас ваш профиль <strong>СКРЫТ</strong> от большого интернета.
{% endif %}

Ваши комментарии в публичных постах {% if user.profile_publicity_level == 'private' %}<strong>НЕ ВИДНЫ</strong>{% else %}<strong>ВИДНЫ</strong>{% endif %}.
</p>
</div>

{% if user.is_profile_public %}
<button type="submit" class="button">Нет, скройте меня от большого интернета!</button>
{% else %}
<button type="submit" class="button button-red" name="is_profile_public" value="1">Да, я хочу публичности!</button>
<div class="block-description block-description-center">
{% if form.profile_publicity_level.errors %}
<span class="form-row-errors">{{ form.profile_publicity_level.errors }}</span>
{% endif %}

<div class="form-row">
<div class="big-radio">
<div class="big-radio-item">
{{ form.profile_publicity_level.0.tag }}
<label for="{{ form.profile_publicity_level.0.id_for_label }}" class="big-radio-label">
<i class="fas fa-ambulance"></i>
<span class="big-radio-title">{{ form.profile_publicity_level.0.choice_label }}</span>
<span class="big-radio-description">Скрывает ваши комментарии и био в публичных постах</span>
</label>
</div>
<div class="big-radio-item">
{{ form.profile_publicity_level.1.tag }}
<label for="{{ form.profile_publicity_level.1.id_for_label }}" class="big-radio-label">
<i class="fas fa-smile"></i>
<span class="big-radio-title">{{ form.profile_publicity_level.1.choice_label }}</span>
<span class="big-radio-description">Профиль скрыт от интернета, но комментарии в публичных постах видны</span>
</label>
</div>
<div class="big-radio-item">
{{ form.profile_publicity_level.2.tag }}
<label for="{{ form.profile_publicity_level.2.id_for_label }}" class="big-radio-label">
<i class="fas fa-star"></i>
<span class="big-radio-title">{{ form.profile_publicity_level.2.choice_label }}</span>
<span class="big-radio-description">Профиль и интро видны даже из большого интернета</span>
</label>
</div>
</div>
</div>

<p>
⚠️ Приватность профиля не означает, что ваши данные не смогут украсть злые люди. Эта опция лишь усложняет жизнь ботам, но вас всё так же могут спалить в комментариях другие.
</p>
</div>

<button type="submit" class="button button-big">Сохранить настройки публичности</button>

<div class="clearfix50"></div>
</div>
</form>
Expand Down
2 changes: 1 addition & 1 deletion frontend/static/css/components/comments.css
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@
}

.comment-body-muted {
font-size: 120%;
font-size: 110%;
opacity: 0.5;
padding-bottom: 20px;
}
Expand Down
20 changes: 13 additions & 7 deletions users/forms/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ class ProfileEditForm(ModelForm):
required=True,
max_length=128
)
is_profile_public = forms.BooleanField(
label="Сделать мой профиль публичным",
profile_publicity_level = forms.ChoiceField(
label="Уровень публичности профиля",
choices=User.PUBLICITY_LEVELS,
initial=User.PUBLICITY_LEVEL_NORMAL,
widget=forms.RadioSelect(),
required=False,
)

Expand All @@ -54,16 +57,19 @@ class Meta:
"city",
"country",
"bio",
"is_profile_public",
"profile_publicity_level",
]

def clean_is_profile_public(self):
new_value = self.cleaned_data["is_profile_public"]
old_value = self.instance.is_profile_public
def clean_profile_publicity_level(self):
new_value = self.cleaned_data["profile_publicity_level"]
old_value = self.instance.profile_publicity_level

# update intro post visibility settings
if new_value != old_value:
Post.objects.filter(author=self.instance, type=Post.TYPE_INTRO).update(is_public=new_value)
if new_value == User.PUBLICITY_LEVEL_PUBLIC:
Post.objects.filter(author=self.instance, type=Post.TYPE_INTRO).update(is_public=True)
else:
Post.objects.filter(author=self.instance, type=Post.TYPE_INTRO).update(is_public=False)

return new_value

Expand Down
25 changes: 25 additions & 0 deletions users/migrations/0030_auto_20240729_1343.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 3.2.13 on 2024-07-29 13:43

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('users', '0029_auto_20240613_1242'),
]

operations = [
migrations.AddField(
model_name='user',
name='profile_publicity_level',
field=models.CharField(choices=[('private', 'Параноик'), ('normal', 'Обычный'), ('public', 'Публичный')], default='normal', max_length=16),
),
migrations.RunSQL(
"update users set profile_publicity_level = 'public' where is_profile_public = true;"
),
migrations.RemoveField(
model_name='user',
name='is_profile_public',
),
]
17 changes: 15 additions & 2 deletions users/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ class User(models.Model, ModelDiffMixin):
(ROLE_GOD, "Бог"),
]

PUBLICITY_LEVEL_PRIVATE = "private"
PUBLICITY_LEVEL_NORMAL = "normal"
PUBLICITY_LEVEL_PUBLIC = "public"
PUBLICITY_LEVELS = [
(PUBLICITY_LEVEL_PRIVATE, "Параноик"),
(PUBLICITY_LEVEL_NORMAL, "Обычный"),
(PUBLICITY_LEVEL_PUBLIC, "Публичный"),
]

MODERATION_STATUS_INTRO = "intro"
MODERATION_STATUS_ON_REVIEW = "on_review"
MODERATION_STATUS_REJECTED = "rejected"
Expand Down Expand Up @@ -99,7 +108,6 @@ class User(models.Model, ModelDiffMixin):

stripe_id = models.CharField(max_length=128, null=True)

is_profile_public = models.BooleanField(default=False)
is_email_verified = models.BooleanField(default=False)
is_email_unsubscribed = models.BooleanField(default=False)
is_banned_until = models.DateTimeField(null=True)
Expand All @@ -110,6 +118,11 @@ class User(models.Model, ModelDiffMixin):
db_index=True
)

profile_publicity_level = models.CharField(
max_length=16, choices=PUBLICITY_LEVELS,
default=PUBLICITY_LEVEL_NORMAL, null=False
)

roles = ArrayField(models.CharField(max_length=32, choices=ROLES), default=list, null=False)

deleted_at = models.DateTimeField(null=True)
Expand Down Expand Up @@ -176,7 +189,7 @@ def get_avatar(self):
return self.avatar or settings.DEFAULT_AVATAR

def can_view(self, user):
return user or self.is_profile_public
return user or self.profile_publicity_level == self.PUBLICITY_LEVEL_PUBLIC

@property
def is_banned(self):
Expand Down

0 comments on commit 6c40c04

Please sign in to comment.