Skip to content
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

Kevins vision for building up a huge social graph on Gitcoin via tribes #5916

Merged
merged 7 commits into from
Feb 15, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/assets/v2/css/profile.css
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@
transform: scale(1.1);
}

#follow_header,
#kudos_header {
position: absolute;
top: -95px;
Expand All @@ -457,6 +458,14 @@
border-radius: 5px;
padding: 5px;
}
#follow_header{
top: -165px;
color: white;
font-size: 12px;
}
#follow_header.lower{
top: -75px;
}
#kudos_header img{
box-shadow: none;
background: none;
Expand Down
17 changes: 14 additions & 3 deletions app/assets/v2/js/pages/join_tribe.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
const joinTribe = () => {
$('[data-jointribe]').each(function(index, elem) {

$(elem).on('click', function() {
$(elem).on('click', function(e) {
if (!document.contxt.github_handle) {
e.preventDefault();
_alert('Please login first.', 'error');
return;
}
$(elem).attr('disabled', true);

const tribe = $(elem).data('jointribe');
Expand All @@ -10,8 +15,14 @@ const joinTribe = () => {

$.when(sendJoin).then(function(response) {
$(elem).attr('disabled', false);
response.is_member ? $(elem).text('Leave Tribe') : $(elem).text('Join Tribe');

response.is_member ? $(elem).html('Unfollow <i class="fas fa-minus"></i>') : $(elem).html('Follow <i class="fas fa-plus"></i>');
let old_count = parseInt($('#follower_count span').text());
var new_count = response.is_member ? old_count + 1 : old_count - 1;

$('#follower_count span').fadeOut();
setTimeout(function() {
$('#follower_count span').text(new_count).fadeIn();
}, 500);
}).fail(function(error) {
$(elem).attr('disabled', false);
});
Expand Down
31 changes: 31 additions & 0 deletions app/dashboard/management/commands/create_auto_follows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'''
Copyright (C) 2020 Gitcoin Core

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

'''

from django.core.management.base import BaseCommand

from dashboard.models import Earning


class Command(BaseCommand):

help = 'auto follows everyone who user has done economic relationship with'

def handle(self, *args, **options):
for obj in Earning.objects.all():
success = obj.create_auto_follow()
print(obj.pk, success)
23 changes: 23 additions & 0 deletions app/dashboard/migrations/0079_auto_20200131_2036.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.2.4 on 2020-01-31 20:36

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dashboard', '0078_profile_as_representation'),
]

operations = [
migrations.AddField(
model_name='profile',
name='dont_autofollow_earnings',
field=models.BooleanField(default=False, help_text='If this option is chosen, Gitcoin will not auto-follow users you do business with'),
),
migrations.AddField(
model_name='tribemember',
name='why',
field=models.CharField(blank=True, max_length=20),
),
]
31 changes: 31 additions & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2498,6 +2498,11 @@ class Profile(SuperModel):
default=False,
help_text='If this option is chosen, the user is able to submit a faucet/ens domain registration even if they are new to github',
)
dont_autofollow_earnings = models.BooleanField(
default=False,
help_text='If this option is chosen, Gitcoin will not auto-follow users you do business with',
)

keywords = ArrayField(models.CharField(max_length=200), blank=True, default=list)
organizations = ArrayField(models.CharField(max_length=200), blank=True, default=list)
profile_organizations = models.ManyToManyField(Organization, blank=True)
Expand Down Expand Up @@ -4549,6 +4554,28 @@ class Earning(SuperModel):
def __str__(self):
return f"{self.from_profile} => {self.to_profile} of ${self.value_usd} on {self.created_on} for {self.source}"

def create_auto_follow(self):
profiles = [self.to_profile, self.from_profile, self.org_profile]
count = 0
for p1 in profiles:
for p2 in profiles:
if not p1 or not p2:
continue
if p1.pk == p2.pk:
continue
if not p1.dont_autofollow_earnings:
TribeMember.objects.update_or_create(
profile=p1,
org=p2,
defaults={'why':'auto'}
)
count += 1
return count

@receiver(post_save, sender=Earning, dispatch_uid="post_save_tip")
def postsave_tip(sender, instance, created, **kwargs):
if created:
instance.create_auto_follow()

def get_my_earnings_counter_profiles(profile_pk):
# returns profiles that a user has done business with
Expand Down Expand Up @@ -4611,3 +4638,7 @@ class TribeMember(SuperModel):
choices=MEMBER_STATUS,
blank=True
)
why = models.CharField(
max_length=20,
blank=True
)
24 changes: 24 additions & 0 deletions app/dashboard/templates/profiles/follow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{% comment %}
Copyright (C) 2020 Gitcoin Core

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
{% endcomment %}
{% load i18n static avatar_tags %}

<span id=follower_count>(<span>{{profile.org.count}}</span> Follower{{profile.org.count|pluralize}})</span>
{% if is_on_tribe %}
<button class="btn btn-gc-blue btn-sm m-2" data-jointribe="{{profile.handle}}">Unfollow <i class="fas fa-minus"></i></button>
{% else %}
<button class="btn btn-gc-blue btn-sm m-2" data-jointribe="{{profile.handle}}">Follow <i class="fas fa-plus"></i></button>
{% endif %}
11 changes: 4 additions & 7 deletions app/dashboard/templates/profiles/header_details.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% load i18n static avatar_tags add_url_schema email_obfuscator %}

<h1 class="profile-header__handle">
{{ profile.name }}
@{{ profile.name }}
{% if verification %}
<button class="btn btn-sm animate-verify" data-container="body" data-toggle="popover" data-html="true" data-placement="bottom" data-trigger="hover click" data-content='
<p class="h6 my-2 text-left">Gitcoin Verified <img width="18" src="{% static "v2/images/badge-verify.svg" %}"></p>
Expand Down Expand Up @@ -32,11 +32,14 @@ <h1 class="profile-header__handle">
<a class="btn btn-outline-gc-blue btn-sm flex-grow-1 font-smaller-5 position-relative quick-link" href="/users?invite={{ profile.handle }}"
data-placement="bottom" data-toggle="tooltip" data-html="true" title="Invite @{{ profile.handle }} to Bounty"
>

<i class="fas fa-envelope-open-text"></i>

</a>
{% if profile.custom_tagline %}
<span style="font-size: 14px; font-color: #000;">- {{ profile.custom_tagline }}</span>
{% endif %}

</p>
<p class="profile-header__links clearfix mt-1">
<a href="{{ profile.data.html_url }}?tab=repositories" target="_blank" rel="noopener noreferrer" data-placement="bottom" data-toggle="tooltip" data-html="true" title="@{{ profile.handle }} on Github">
Expand Down Expand Up @@ -70,12 +73,6 @@ <h1 class="profile-header__handle">
</div>
{% endif %}

{% if user.is_authenticated and is_on_tribe and profile.is_org %}
<button class="btn btn-gc-blue btn-sm" data-jointribe="{{profile.handle}}">Leave Tribe</button>
{% elif user.is_authenticated and profile.is_org %}
<button class="btn btn-gc-blue btn-sm" data-jointribe="{{profile.handle}}">Join Tribe</button>
{% endif %}

{% if not profile.hide_wallet_address %}
{% if profile.preferred_payout_address %}
<div class="my-2">
Expand Down
6 changes: 4 additions & 2 deletions app/dashboard/templates/profiles/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
<div class="container-fluid bg-light">
<div class="container profile-card mh-150">
<div class="row">
<div id="follow_header" class="d-md-block d-none {% if not my_kudos|length %}lower{% endif %}">
{% include 'profiles/follow.html' %}
</div>
{% if total_kudos_count %}
<div id="kudos_header" class="d-md-block d-none">
{% for kudos_group in my_kudos %}
Expand All @@ -66,12 +69,11 @@
{% endcomment %}
{% include 'profiles/header_details.html' %}
</div>

{% if profile.is_org %}
{% include 'profiles/organization.html' %}

{% elif profile.cascaded_persona == 'funder' %}
{% include 'profiles/scorecard_funder.html' %}

{% else %}
{% include 'profiles/scorecard_hunter.html' %}
{% endif %}
Expand Down
3 changes: 2 additions & 1 deletion app/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4395,7 +4395,8 @@ def join_tribe(request, handle):
except TribeMember.DoesNotExist:
kwargs = {
'org': Profile.objects.filter(handle=handle).first(),
'profile': profile
'profile': profile,
'why': 'api',
}
tribemember = TribeMember.objects.create(**kwargs)
tribemember.save()
Expand Down
1 change: 1 addition & 0 deletions app/marketing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def privacy_settings(request):
msg = ''
if request.POST and request.POST.get('submit'):
if profile:
profile.dont_autofollow_earnings = bool(request.POST.get('dont_autofollow_earnings', False))
profile.suppress_leaderboard = bool(request.POST.get('suppress_leaderboard', False))
profile.hide_profile = bool(request.POST.get('hide_profile', False))
profile.hide_wallet_address = bool(request.POST.get('hide_wallet_address', False))
Expand Down
8 changes: 8 additions & 0 deletions app/retail/templates/settings/privacy.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ <h5>{% trans "Privacy Preferences" %}</h5>
{% trans "If this option is chosen, Gitcoin will hide your wallet address in it's UI." %}
</small>
</div>
<div>
<input type="checkbox" name="dont_autofollow_earnings" id=dont_autofollow_earnings {% if profile.dont_autofollow_earnings %} checked="checked" {% endif %} {% if not is_logged_in %} disabled {% endif %} >
<label class="form__label" for="dont_autofollow_earnings">{% trans "Don't auto-follow users you do business with" %}</label>
<br>
<small id="dont_autofollow_earnings_help" class="form__input-help">
{% trans "If this option is chosen, Gitcoin will not auto-follow users you do business with." %}
</small>
</div>
{% if profile.alumni.exists %}
<div>
<input type="checkbox" name="hide_alumni" id=hide_alumni value="1" {% if not profile.alumni.first.public %} checked="checked" {% endif %} {% if not is_logged_in %} disabled {% endif %} >
Expand Down