Backend: enrich message reply data (include created_at and media_files) and ensure chat owners are treated as members; tighten/extend permission checks and message query filters; fix hub routers so moderators/tags routes are resolved before hub detail; accept hub id from request.data in hub permission/tag views; add PostHub serializer and expose hub_detail on posts. Frontend: update generated API models (postHub, replyTo, members_detail, hub_detail); add hub-related pages/routes and components (HubCard, HubHeader, Tags) and a hub posts feed hook; rework message UI and composer to show richer reply previews (media thumbnails, timestamps), adjust video preload to metadata; add tag selection UI to PostComposer and wire hub tags fetching. Also: minor UI/UX improvements and generated model exports updated to match backend changes.
82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
from django.contrib.auth import get_user_model
|
|
from rest_framework import serializers
|
|
from .models import Post, PostContent, PostVote, PostSave
|
|
from social.hubs.serializers import TagsSerializer
|
|
from social.hubs.models import Hub
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class AuthorMinimalSerializer(serializers.ModelSerializer):
|
|
avatar = serializers.ImageField(read_only=True)
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = ['id', 'username', 'first_name', 'last_name', 'avatar']
|
|
|
|
|
|
class PostContentSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PostContent
|
|
fields = ['id', 'mime_type', 'file', 'alt_text']
|
|
read_only_fields = ['mime_type']
|
|
|
|
|
|
class PostHubSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Hub
|
|
fields = ['id', 'name', 'icon']
|
|
|
|
|
|
class PostSerializer(serializers.ModelSerializer):
|
|
contents = PostContentSerializer(many=True, read_only=True)
|
|
tags = TagsSerializer(many=True, read_only=True)
|
|
author_detail = AuthorMinimalSerializer(source='author', read_only=True)
|
|
hub_detail = PostHubSerializer(source='hub', read_only=True)
|
|
vote_score = serializers.SerializerMethodField()
|
|
user_vote = serializers.SerializerMethodField()
|
|
reply_count = serializers.IntegerField(read_only=True, default=0)
|
|
is_saved = serializers.SerializerMethodField()
|
|
save_count = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Post
|
|
fields = [
|
|
'id', 'content', 'created_at', 'updated_at',
|
|
'author', 'author_detail',
|
|
'hub', 'hub_detail', 'reply_to',
|
|
'tags', 'contents',
|
|
'vote_score', 'user_vote', 'reply_count', 'is_saved', 'save_count',
|
|
]
|
|
read_only_fields = ['author', 'created_at', 'updated_at']
|
|
|
|
def get_vote_score(self, obj):
|
|
return sum(v.vote for v in obj.votes.all())
|
|
|
|
def get_user_vote(self, obj):
|
|
request = self.context.get('request')
|
|
if not request or not request.user.is_authenticated:
|
|
return 0
|
|
vote = obj.votes.filter(user=request.user).first()
|
|
return vote.vote if vote else 0
|
|
|
|
def get_is_saved(self, obj):
|
|
request = self.context.get('request')
|
|
if not request or not request.user.is_authenticated:
|
|
return False
|
|
return obj.saves.filter(user=request.user).exists()
|
|
|
|
def get_save_count(self, obj):
|
|
return obj.saves.count()
|
|
|
|
|
|
class PostVoteSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PostVote
|
|
fields = ['id', 'post', 'user', 'vote', 'created_at']
|
|
read_only_fields = ['user', 'created_at']
|
|
|
|
|
|
class TagAttachSerializer(serializers.Serializer):
|
|
tag_id = serializers.IntegerField(help_text="PK of the hub tag to attach or detach.")
|