Commit a2adc3e7 authored by Christophe Henry's avatar Christophe Henry

Merge branch 'fix-contacts-following' into 'master'

Multiple fixes on contacts pages

Closes #545 and #548

See merge request socialhome/socialhome!536
parents 849ded51 b04baf8b
Pipeline #2154 failed with stages
in 19 minutes and 25 seconds
...@@ -63,10 +63,10 @@ export default { ...@@ -63,10 +63,10 @@ export default {
return this.$store.state.application.isUserAuthenticated return this.$store.state.application.isUserAuthenticated
}, },
showFollowBtn() { showFollowBtn() {
return this.$store.state.application.isUserAuthenticated && !this.following return this.isUserAuthenticated && !this.following
}, },
showUnfollowBtn() { showUnfollowBtn() {
return this.$store.state.application.isUserAuthenticated && this.following return this.isUserAuthenticated && this.following
}, },
translations() { translations() {
return { return {
......
...@@ -5,15 +5,20 @@ ...@@ -5,15 +5,20 @@
<b-card <b-card
v-for="item in chunk" v-for="item in chunk"
:key="item.fid" :key="item.fid"
:title="item.name" :title="contactDesignation(item)"
:img-src="item.image_url_large" :img-src="item.image_url_large"
:img-alt="contactAvatarAlt(item.name)" :img-alt="contactAvatarAlt(item)"
img-top img-top
class="socialhome-contact-card mb-3" class="socialhome-contact-card mb-3"
> >
<b-card-text>{{ item.handle }}</b-card-text> <b-card-text>{{ item.handle }}</b-card-text>
<profile-reaction-buttons slot="footer" class="pull-right" :profile="item" :user-following="true" /> <profile-reaction-buttons
slot="footer"
class="pull-right"
:profile="item"
:user-following="item.user_following"
/>
</b-card> </b-card>
</b-card-group> </b-card-group>
<infinite-loading @infinite="loadMore" /> <infinite-loading @infinite="loadMore" />
...@@ -63,8 +68,11 @@ export default { ...@@ -63,8 +68,11 @@ export default {
}, },
}, },
methods: { methods: {
contactAvatarAlt(contactName) { contactAvatarAlt(contact) {
return `${gettext("Avatar of")} ${contactName}` return `${gettext("Avatar of")} ${this.contactDesignation(contact)}`
},
contactDesignation(contact) {
return contact.name || contact.handle || contact.fid
}, },
fetch() { /* Override */ fetch() { /* Override */
}, },
......
...@@ -124,6 +124,7 @@ describe("ProfileReactionButtons", () => { ...@@ -124,6 +124,7 @@ describe("ProfileReactionButtons", () => {
}) })
it("should show an error to the user if not logged in", () => { it("should show an error to the user if not logged in", () => {
store.state.application.isUserAuthenticated = false
const target = mount(ProfileReactionButtons, { const target = mount(ProfileReactionButtons, {
propsData: { propsData: {
profile: store.content.author, profile: store.content.author,
...@@ -132,8 +133,6 @@ describe("ProfileReactionButtons", () => { ...@@ -132,8 +133,6 @@ describe("ProfileReactionButtons", () => {
store, store,
}) })
target.instance().$store.state.application.isUserAuthenticated = false
Sinon.spy(target.instance().$snotify, "error") Sinon.spy(target.instance().$snotify, "error")
target.instance().following.should.be.false target.instance().following.should.be.false
target.instance().follow() target.instance().follow()
...@@ -200,6 +199,7 @@ describe("ProfileReactionButtons", () => { ...@@ -200,6 +199,7 @@ describe("ProfileReactionButtons", () => {
}) })
it("should show an error to the user if not logged in", () => { it("should show an error to the user if not logged in", () => {
store.state.application.isUserAuthenticated = false
const target = mount(ProfileReactionButtons, { const target = mount(ProfileReactionButtons, {
propsData: { propsData: {
profile: store.content.author, profile: store.content.author,
...@@ -208,8 +208,6 @@ describe("ProfileReactionButtons", () => { ...@@ -208,8 +208,6 @@ describe("ProfileReactionButtons", () => {
store, store,
}) })
target.instance().$store.state.application.isUserAuthenticated = false
Sinon.spy(target.instance().$snotify, "error") Sinon.spy(target.instance().$snotify, "error")
target.instance().following.should.be.true target.instance().following.should.be.true
target.instance().unfollow() target.instance().unfollow()
......
...@@ -65,4 +65,5 @@ class TestObtainSocialhomeAuthToken(SocialhomeAPITestCase): ...@@ -65,4 +65,5 @@ class TestObtainSocialhomeAuthToken(SocialhomeAPITestCase):
"is_local": self.user.profile.is_local, "is_local": self.user.profile.is_local,
"name": self.user.profile.name, "name": self.user.profile.name,
"url": self.user.profile.url, "url": self.user.profile.url,
"user_following": False,
"token": Token.objects.get(user=self.user).key}) "token": Token.objects.get(user=self.user).key})
...@@ -14,6 +14,8 @@ class LimitedProfileSerializer(ModelSerializer): ...@@ -14,6 +14,8 @@ class LimitedProfileSerializer(ModelSerializer):
For example for adding to serialized Content. For example for adding to serialized Content.
""" """
user_following = SerializerMethodField()
class Meta: class Meta:
model = Profile model = Profile
fields = ( fields = (
...@@ -28,6 +30,7 @@ class LimitedProfileSerializer(ModelSerializer): ...@@ -28,6 +30,7 @@ class LimitedProfileSerializer(ModelSerializer):
"is_local", "is_local",
"name", "name",
"url", "url",
"user_following",
) )
read_only_fields = ( read_only_fields = (
"fid", "fid",
...@@ -41,8 +44,15 @@ class LimitedProfileSerializer(ModelSerializer): ...@@ -41,8 +44,15 @@ class LimitedProfileSerializer(ModelSerializer):
"is_local", "is_local",
"name", "name",
"url", "url",
"user_following",
) )
def get_user_following(self, obj: Profile) -> bool:
request = self.context.get("request")
if not request:
return False
return bool(request.user.is_authenticated and obj.id in request.user.profile.following_ids)
class ProfileSerializer(ModelSerializer): class ProfileSerializer(ModelSerializer):
followed_tags = SerializerMethodField() followed_tags = SerializerMethodField()
......
...@@ -64,13 +64,13 @@ class ProfileViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, Generic ...@@ -64,13 +64,13 @@ class ProfileViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, Generic
@action(methods=["get"], detail=False, permission_classes=(IsAuthenticated,)) @action(methods=["get"], detail=False, permission_classes=(IsAuthenticated,))
def following(self, request): def following(self, request):
query_set = self.paginate_queryset(request.user.profile.following.all()) query_set = self.paginate_queryset(request.user.profile.following.all())
values = [LimitedProfileSerializer(x).data for x in query_set] values = [LimitedProfileSerializer(x, context={'request': request}).data for x in query_set]
return self.get_paginated_response(values) return self.get_paginated_response(values)
@action(methods=["get"], detail=False, permission_classes=(IsAuthenticated,)) @action(methods=["get"], detail=False, permission_classes=(IsAuthenticated,))
def followers(self, request): def followers(self, request):
query_set = self.paginate_queryset(request.user.profile.followers.all()) query_set = self.paginate_queryset(request.user.profile.followers.all())
values = [LimitedProfileSerializer(x).data for x in query_set] values = [LimitedProfileSerializer(x, context={'request': request}).data for x in query_set]
return self.get_paginated_response(values) return self.get_paginated_response(values)
@list_route(methods=["post"], permission_classes=(IsAuthenticated,)) @list_route(methods=["post"], permission_classes=(IsAuthenticated,))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment