-
-
Notifications
You must be signed in to change notification settings - Fork 775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Following section #6301
Following section #6301
Changes from all commits
0ca2ca3
13e854f
6c2780e
e22d9f6
c0dcaee
39f5a34
8648841
cb8bafc
edda50d
7517420
a0efb30
398f1f6
fa26429
bc5ae0c
14ca76b
0a98720
ab54f3d
1dccfb9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ | |
from django.contrib.postgres.fields import ArrayField, JSONField | ||
from django.core.validators import MaxValueValidator, MinValueValidator | ||
from django.db import connection, models | ||
from django.db.models import Count, F, Q, Sum | ||
from django.db.models import Count, F, Q, Sum, Subquery | ||
from django.db.models.signals import m2m_changed, post_delete, post_save, pre_save | ||
from django.dispatch import receiver | ||
from django.forms.models import model_to_dict | ||
|
@@ -4852,3 +4852,17 @@ class TribeMember(SuperModel): | |
max_length=20, | ||
blank=True | ||
) | ||
|
||
@property | ||
def mutual_follow(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tribesmembers is used for users following but also for orgs tribes seems this will show tribes orgs as following There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a handy method for Tribe Members, this method will be used as predicate to know if the current pair (org, profile) follow mutually. |
||
return TribeMember.objects.filter(profile=self.org, org=self.profile).exists() | ||
|
||
@property | ||
def mutual_follower(self): | ||
tribe_following = Subquery(TribeMember.objects.filter(profile=self.profile).values_list('org', flat=True)) | ||
return TribeMember.objects.filter(org=self.org, profile__in=tribe_following).exclude(profile=self.profile) | ||
|
||
@property | ||
def mutual_following(self): | ||
tribe_following = Subquery(TribeMember.objects.filter(org=self.profile).values_list('profile', flat=True)) | ||
return TribeMember.objects.filter(org__in=tribe_following, profile=self.org).exclude(org=self.org) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
{% load i18n static %} | ||
|
||
{% if not hidden %} | ||
<div id="profile-tabs" class="tab-container font-body mt-3 mb-4"> | ||
<button type="button" id="nav-description" href="{{profile.url}}/follow?sub=followers" class="text-center section-tab {% if foltab == "followers" %} active {% endif %}"> | ||
{% trans "FOLLOWERS" %} <span class="nav-badge">({{followers.count}})</span> | ||
</button> | ||
<button type="button" id="nav-description" href="{{profile.url}}/follow?sub=following" class="text-center section-tab {% if foltab == "following" %} active {% endif %}"> | ||
{% trans "FOLLOWING" %} <span class="nav-badge">({{following.count}})</span> | ||
</button> | ||
</div> | ||
{% endif %} | ||
|
||
<div class="tab-projects d-flex flex-column"> | ||
{% if foltab == 'followers' %} | ||
<!-- Show This users followers--> | ||
{% for user in followers %} | ||
<div class="tab-projects__item d-flex mb-0 pt-1 pb-1 bounty_row"> | ||
<div class="avatar-container col-1 justify-content-center hide_min_viewport"> | ||
<img class="profile-header__avatar mr-3" src="/dynamic/avatar/{{ user.profile.handle }}" alt=""> | ||
</div> | ||
<div class="tab-projects__item-details col-3 d-flex flex-column bounty-detail"> | ||
<div class="d-flex flex-column"> | ||
<div class="font-weight-semibold font-header">{{user.profile.name}}</div> | ||
<div class="text-highlight-gc-blue font-smaller-1">{{user.profile.handle}}</div> | ||
</div> | ||
</div> | ||
<div class="mb-0 mt-1 col-5 d-flex flex-row align-items-center"> | ||
<div class="mr-5" style="height: fit-content"> | ||
<button class="btn btn-outline-gc-blue btn-sm flex-grow-1 font-smaller-5 position-relative quick-link" data-openchat="{{user.profile}}" | ||
data-placement="bottom" data-toggle="tooltip" data-html="true" title="Chat @{{ user.profile.handle }}"> | ||
<i class="fas fa-comment-dots"></i> | ||
</button> | ||
</div> | ||
<div style="height: fit-content"> | ||
<a class="btn btn-outline-gc-blue btn-sm flex-grow-1 mr-5 font-smaller-5 position-relative quick-link btn-outline-gc-blue" href="https://gitcoin.co/users?invite={{user.profile.handle}}" data-placement="bottom" data-toggle="tooltip" data-html="true" title="Invite {{ user.profile.handle }} to Bounty"> | ||
<i class="fas fa-envelope-open-text"></i> | ||
</a> | ||
</div> | ||
<div class="d-flex align-items-center" style="height: fit-content"> | ||
{% with followers=user.mutual_following %} | ||
<div style="width: 60px" class="{% if followers|length > 1 %}d-flex flex-row align-items-center{% endif %}"> | ||
{% for follower in followers %} | ||
{% if forloop.last %} | ||
<img class="rounded-circle" style="height: 25px; width: 25px;" src="/dynamic/avatar/{{ follower.org.handle }}" alt=""> | ||
{% else %} | ||
<img class="rounded-circle" style="height: 25px; width: 25px; margin-right: -12px " src="/dynamic/avatar/{{ follower.org.handle }}" alt=""> | ||
{% endif %} | ||
{% endfor %} | ||
</div> | ||
{% if followers|length >= 1 %} | ||
<p class="text-muted font-smaller-4 my-0">Followed by {% for follower in followers %} | ||
{{ follower.org.handle }}{% if not forloop.last %}, {% endif %} | ||
{% endfor %}</p> | ||
{% endif %} | ||
{% endwith %} | ||
</div> | ||
</div> | ||
<div class="col-12 col-md-4 col-lg-3 font-caption my-auto text-right"> | ||
{% if user.mutual_follow %} | ||
<button class="btn btn-sm m-2 px-4 font-caption py-1 font-weight-bold btn-outline-gc-green" style="border-width: 2px !important;" data-tribe="{{user.profile.handle}}">Following</button> | ||
{% else %} | ||
<button class="btn btn-gc-blue btn-sm m-2 px-2 font-caption" data-jointribe="{{user.profile.handle}}">Follow<i class="fas fa-user-plus font-smaller-4 ml-2"></i></button> | ||
{% endif %} | ||
</div> | ||
</div> | ||
{% endfor %} | ||
|
||
{% elif foltab == 'following' %} | ||
<!-- Show which users this one is following--> | ||
{% for user in following %} | ||
<div class="tab-projects__item d-flex mb-0 pt-1 pb-1 bounty_row"> | ||
<div class="avatar-container col-1 justify-content-center hide_min_viewport"> | ||
<img class="profile-header__avatar mr-3" src="/dynamic/avatar/{{ user.org.handle }}" alt=""> | ||
</div> | ||
<div class="tab-projects__item-details col-3 d-flex flex-column bounty-detail"> | ||
<div class="d-flex flex-column"> | ||
<div class="font-weight-semibold font-header">{{user.org.name}}</div> | ||
<div class="text-highlight-gc-blue font-smaller-1">{{user.org.handle}}</div> | ||
</div> | ||
</div> | ||
<div class="mb-0 mt-1 col-5 d-flex flex-row align-items-center"> | ||
<div class="mr-5" style="height: fit-content"> | ||
<button class="btn btn-outline-gc-blue btn-sm flex-grow-1 font-smaller-5 position-relative quick-link" data-openchat="{{user.org}}"> | ||
<i class="fas fa-comment-dots" data-p lacement="bottom" data-toggle="tooltip" data-html="true" | ||
title="Chat @{{ user.org.handle }}"> | ||
</i> | ||
</button> | ||
</div> | ||
<div style="height: fit-content"> | ||
<a class="btn btn-sm flex-grow-1 mr-5 font-smaller-5 position-relative quick-link btn-outline-gc-blue" {% if not user.org.email %} hidden {% endif %} href="mailto:{{user.org.email}}" data-placement="bottom" data-toggle="tooltip" data-html="true" title="@{{ user.org.handle }}'s Email"> | ||
<i class="far fa-envelope"></i> | ||
</a> | ||
</div> | ||
<div class="d-flex align-items-center" style="height: fit-content"> | ||
{% with followers=user.mutual_follower %} | ||
<div style="width: 60px" class="{% if followers|length > 1 %} d-flex flex-row align-items-center{% endif %}"> | ||
{% for follower in followers %} | ||
{% if forloop.last %} | ||
<img class="rounded-circle" style="height: 25px; width: 25px;" src="/dynamic/avatar/{{ follower.profile.handle }}" alt=""> | ||
{% else %} | ||
<img class="rounded-circle" style="height: 25px; width: 25px; margin-right: -12px " src="/dynamic/avatar/{{ follower.profile.handle }}" alt=""> | ||
{% endif %} | ||
{% endfor %} | ||
</div> | ||
{% if followers|length >= 1 %} | ||
<p class="text-muted font-smaller-4 my-0">Followed by {% for follower in followers %} | ||
{{ follower.profile.handle }}{% if not forloop.last %}, {% endif %} | ||
{% endfor %}</p> | ||
{% endif %} | ||
{% endwith %} | ||
</div> | ||
|
||
</div> | ||
<div class="col-12 col-md-3 col-lg-3 font-caption my-auto text-right"> | ||
<button class="btn btn-sm m-4 px-4 font-caption py-1 font-weight-bold btn-outline-gc-green" style="border-width: 2px !important;" data-tribe="{{user.org.handle}}">Following</button> | ||
</div> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
{% endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is loaded in many pleases probably is better to move it to his own file or even loaded on that page only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we omit this at this moment? i'll move this in another PR due i'll be working this weeks on tribes functionality.