diff --git a/Gulpfile.js b/Gulpfile.js index 8835e1aa1a..9e0611dcc7 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -153,6 +153,7 @@ function jsPackages() { require.resolve('chartjs-adapter-moment/dist/chartjs-adapter-moment.min.js'), require.resolve('chart.js/dist/chart.min.js'), require.resolve('easymde/dist/easymde.min.js'), + require.resolve('jdenticon/standalone'), path.resolve('node_modules/mathjax/unpacked/**') ], { sourcemaps: true }) .pipe(gulp.dest('dist/js/', { sourcemaps: '.' })) diff --git a/package.json b/package.json index 955289a191..8cb192a20f 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "gulp-postcss": "10.0.0", "gulp-terser-js": "5.2.2", "gulp.spritesmith": "6.13.0", + "jdenticon": "3.3.0", "jquery": "3.7.1", "mathjax": "2.7.1", "moment": "2.30.1", diff --git a/templates/base.html b/templates/base.html index a7f19bf9b6..21e57c686f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -241,6 +241,10 @@

{{ headlin {# Javascript stuff start #} + + {% block extra_js %} {% endblock %} diff --git a/templates/forum/base.html b/templates/forum/base.html index dbc9149bb6..b3f13cbe6f 100644 --- a/templates/forum/base.html +++ b/templates/forum/base.html @@ -140,7 +140,7 @@

{{ period|humane_delta }}

{% with answer=topic.get_last_answer %} {% if answer %} {% with profile=answer.author|profile %} - + {% avatar profile %} {% endwith %} {% trans "Dernière réponse" %} diff --git a/templates/header.html b/templates/header.html index 493f6b8815..f81103d9bc 100644 --- a/templates/header.html +++ b/templates/header.html @@ -236,7 +236,7 @@

{% trans "Messagerie privée" %}

  • - + {% avatar notification.author.profile %} {{ notification.author.username }} {{ notification.pubdate|format_date:True|capfirst }}
    @@ -274,7 +274,7 @@

    {% trans "Notifications" %}

  • - + {% avatar first_unread.author.profile %} {{ first_unread.author.username }} {{ first_unread.pubdate|format_date:True|capfirst }}
    @@ -344,7 +344,7 @@

    {% trans "Alertes de modération" %}

    data-active="open-my-account" {% endif %} > - Mon compte + {% avatar profile %} {{ user.username }}
    {% endwith %} diff --git a/templates/member/profile.html b/templates/member/profile.html index 4f3b0b6443..f88ba71e98 100644 --- a/templates/member/profile.html +++ b/templates/member/profile.html @@ -78,7 +78,7 @@
    - {% trans + {% avatar profile size=200 %}
    diff --git a/templates/misc/avatar.part.html b/templates/misc/avatar.part.html new file mode 100644 index 0000000000..b653d14fb3 --- /dev/null +++ b/templates/misc/avatar.part.html @@ -0,0 +1,11 @@ +{% load captureas %} + +{# Template used by the templatetag "avatar" defined in zds/utils/templatetags/profile.py #} + +{% captureas alt_text %}Avatar de {{ username }}{% endcaptureas %} + +{% if avatar_url %} + +{% else %} + {{ alt_text }} +{% endif %} diff --git a/templates/misc/member_item.part.html b/templates/misc/member_item.part.html index 4c3ca23da7..e6e3fcc12e 100644 --- a/templates/misc/member_item.part.html +++ b/templates/misc/member_item.part.html @@ -16,7 +16,7 @@ {% endif %}> {% if avatar %} - + {% avatar profile %} {% endif %} {{ username }} diff --git a/templates/misc/message_user.html b/templates/misc/message_user.html index adf8ac626d..37401bfe50 100644 --- a/templates/misc/message_user.html +++ b/templates/misc/message_user.html @@ -5,7 +5,7 @@
    {% with profile=member|profile %} - + {% avatar profile %} {% include 'misc/badge.part.html' %} diff --git a/yarn.lock b/yarn.lock index d90bcf6070..ef1df2fa67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1049,6 +1049,13 @@ caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz#da06b79c3d9c3d9958eb307aa832ac68ead79bee" integrity sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ== +canvas-renderer@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/canvas-renderer/-/canvas-renderer-2.2.1.tgz#c1d131f78a9799aca8af9679ad0a005052b65550" + integrity sha512-RrBgVL5qCEDIXpJ6NrzyRNoTnXxYarqm/cS/W6ERhUJts5UQtt/XPEosGN3rqUkZ4fjBArlnCbsISJ+KCFnIAg== + dependencies: + "@types/node" "*" + capture-stack-trace@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz#1c43f6b059d4249e7f3f8724f15f048b927d3a8a" @@ -4809,6 +4816,13 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" +jdenticon@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-3.3.0.tgz#64bae9f9b3cf5c2a210e183648117afe3a89b367" + integrity sha512-DhuBRNRIybGPeAjMjdHbkIfiwZCCmf8ggu7C49jhp6aJ7DYsZfudnvnTY5/1vgUhrGA7JaDAx1WevnpjCPvaGg== + dependencies: + canvas-renderer "~2.2.0" + jpeg-js@0.0.4: version "0.0.4" resolved "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.0.4.tgz" diff --git a/zds/member/models.py b/zds/member/models.py index 856e844404..78d76fa2b8 100644 --- a/zds/member/models.py +++ b/zds/member/models.py @@ -118,9 +118,7 @@ def get_avatar_url(self, size=80): else: return self.avatar_url else: - return "https://secure.gravatar.com/avatar/{}?d=identicon&s={}".format( - md5(self.user.email.lower().encode("utf-8")).hexdigest(), size - ) + return "" def get_post_count(self): """ diff --git a/zds/member/tests/tests_models.py b/zds/member/tests/tests_models.py index c21c30b114..de6ef2eb91 100644 --- a/zds/member/tests/tests_models.py +++ b/zds/member/tests/tests_models.py @@ -30,8 +30,8 @@ def test_get_absolute_url_for_details_of_member(self): self.assertEqual(self.user1.get_absolute_url(), f"/@{self.user1.user.username}") def test_get_avatar_url(self): - # if no url was specified -> gravatar ! - self.assertIn("gravatar.com", self.user1.get_avatar_url()) + # if no url was specified -> nothing ! + self.assertEqual("", self.user1.get_avatar_url()) # if an url is specified -> take it ! user2 = ProfileFactory() diff --git a/zds/utils/templatetags/profile.py b/zds/utils/templatetags/profile.py index bf234cc1b6..31c6c21ef2 100644 --- a/zds/utils/templatetags/profile.py +++ b/zds/utils/templatetags/profile.py @@ -73,13 +73,10 @@ def state(current_user): return user_state -@register.simple_tag -def avatar_url(profile: Profile, size=80) -> str: - """ - Return the URL of the avatar of a profile. - If the profile is None, return an empty string. - """ - if profile is not None: - url = profile.get_avatar_url(size) - return remove_url_scheme(url) - return "" +@register.inclusion_tag("misc/avatar.part.html") +def avatar(profile: Profile, size=80) -> dict: + return { + "avatar_url": remove_url_scheme(profile.get_avatar_url(size)), + "avatar_size": size, + "username": profile.user.username, + }