From 94d793b33c2721f1c4b3829c4467ba4aa7aff3cf Mon Sep 17 00:00:00 2001 From: moonlitgrace Date: Fri, 13 Dec 2024 16:31:20 +0530 Subject: [PATCH] refactor: crate comment app and integrate django_ltree_2 --- backend/apps/comment/__init__.py | 0 backend/apps/comment/admin.py | 11 ++ backend/apps/comment/api/__init__.py | 0 backend/apps/comment/api/v1/__init__.py | 0 backend/apps/comment/api/v1/serializers.py | 0 backend/apps/comment/api/v1/urls.py | 0 backend/apps/comment/api/v1/viewsets.py | 0 backend/apps/comment/apps.py | 6 + .../apps/comment/migrations/0001_initial.py | 73 ++++++++++ backend/apps/comment/migrations/__init__.py | 0 backend/apps/comment/models.py | 34 +++++ backend/apps/quiblet/api/v1/serializers.py | 16 +++ backend/apps/quiblet/api/v1/viewsets.py | 8 +- .../quiblet/migrations/0003_quib_cover.py | 26 ++++ ...emove_quib_likes_quib_comments_and_more.py | 53 +++++++ backend/apps/quiblet/models.py | 24 +++- backend/config/settings.py | 3 + backend/poetry.lock | 42 +++++- backend/pyproject.toml | 1 + frontend/src/lib/clients/v1.ts | 136 +++++++++++------- .../pages/home/{post.svelte => quib.svelte} | 31 ++-- ...osts_header.svelte => quibs_header.svelte} | 0 ...ecent_posts.svelte => recent_quibs.svelte} | 2 +- frontend/src/routes/+page.svelte | 12 +- 24 files changed, 386 insertions(+), 92 deletions(-) create mode 100644 backend/apps/comment/__init__.py create mode 100644 backend/apps/comment/admin.py create mode 100644 backend/apps/comment/api/__init__.py create mode 100644 backend/apps/comment/api/v1/__init__.py create mode 100644 backend/apps/comment/api/v1/serializers.py create mode 100644 backend/apps/comment/api/v1/urls.py create mode 100644 backend/apps/comment/api/v1/viewsets.py create mode 100644 backend/apps/comment/apps.py create mode 100644 backend/apps/comment/migrations/0001_initial.py create mode 100644 backend/apps/comment/migrations/__init__.py create mode 100644 backend/apps/comment/models.py create mode 100644 backend/apps/quiblet/migrations/0003_quib_cover.py create mode 100644 backend/apps/quiblet/migrations/0004_remove_quib_dislikes_remove_quib_likes_quib_comments_and_more.py rename frontend/src/lib/components/pages/home/{post.svelte => quib.svelte} (70%) rename frontend/src/lib/components/pages/home/{posts_header.svelte => quibs_header.svelte} (100%) rename frontend/src/lib/components/pages/home/{recent_posts.svelte => recent_quibs.svelte} (97%) diff --git a/backend/apps/comment/__init__.py b/backend/apps/comment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/admin.py b/backend/apps/comment/admin.py new file mode 100644 index 00000000..e3c9d31c --- /dev/null +++ b/backend/apps/comment/admin.py @@ -0,0 +1,11 @@ +from django.contrib import admin + +from .models import Comment + +# Register your models here. + + +@admin.register(Comment) +class CommentAdmin(admin.ModelAdmin): + list_display = ('quibbler', 'content', 'created_at') + search_fields = ('quibbler__username', 'content') diff --git a/backend/apps/comment/api/__init__.py b/backend/apps/comment/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/api/v1/__init__.py b/backend/apps/comment/api/v1/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/api/v1/serializers.py b/backend/apps/comment/api/v1/serializers.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/api/v1/urls.py b/backend/apps/comment/api/v1/urls.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/api/v1/viewsets.py b/backend/apps/comment/api/v1/viewsets.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/apps.py b/backend/apps/comment/apps.py new file mode 100644 index 00000000..1b4ed7f0 --- /dev/null +++ b/backend/apps/comment/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CommentConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.comment' diff --git a/backend/apps/comment/migrations/0001_initial.py b/backend/apps/comment/migrations/0001_initial.py new file mode 100644 index 00000000..3abee925 --- /dev/null +++ b/backend/apps/comment/migrations/0001_initial.py @@ -0,0 +1,73 @@ +# Generated by Django 5.1.4 on 2024-12-13 10:36 + +import django.contrib.postgres.indexes +import django.db.models.deletion +import django_ltree.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('user', '0003_alter_profile_username'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), + ( + 'created_at', + models.DateTimeField(auto_now_add=True, verbose_name='create at'), + ), + ('path', django_ltree.fields.PathField(unique=True)), + ('content', models.TextField(verbose_name='content')), + ( + 'downvotes', + models.ManyToManyField( + blank=True, + related_name='downvotes', + to='user.profile', + verbose_name='downvotes', + ), + ), + ( + 'quibbler', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='user.profile', + verbose_name='quibbler', + ), + ), + ( + 'upvotes', + models.ManyToManyField( + blank=True, + related_name='upvotes', + to='user.profile', + verbose_name='upvotes', + ), + ), + ], + options={ + 'verbose_name': 'Comment', + 'verbose_name_plural': 'Comments', + 'indexes': [ + django.contrib.postgres.indexes.GistIndex( + fields=['path'], name='comment_com_path_d1388c_gist' + ) + ], + }, + ), + ] diff --git a/backend/apps/comment/migrations/__init__.py b/backend/apps/comment/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/comment/models.py b/backend/apps/comment/models.py new file mode 100644 index 00000000..46cba3d7 --- /dev/null +++ b/backend/apps/comment/models.py @@ -0,0 +1,34 @@ +from django.contrib.postgres import indexes as idx +from django.db import models +from django.utils.translation import gettext_lazy as _ +from django_ltree.models import TreeModel + +from apps.user.models import Profile +from common.mixins.model_mixins import CreatedAtMixin + +# Create your models here. + + +class Comment(CreatedAtMixin, TreeModel): + quibbler = models.ForeignKey( + Profile, on_delete=models.CASCADE, verbose_name=_('quibbler') + ) + content = models.TextField(_('content')) + upvotes = models.ManyToManyField( + Profile, related_name='upvotes', blank=True, verbose_name=_('upvotes') + ) + downvotes = models.ManyToManyField( + Profile, related_name='downvotes', blank=True, verbose_name=_('downvotes') + ) + + @property + def children_count(self): + return self.children().count() + + def __str__(self) -> str: + return f"Comment by {self.quibbler.username}" + + class Meta: # pyright: ignore + indexes = [idx.GistIndex(fields=['path'])] + verbose_name = 'Comment' + verbose_name_plural = 'Comments' diff --git a/backend/apps/quiblet/api/v1/serializers.py b/backend/apps/quiblet/api/v1/serializers.py index 6011cdb6..0edfd11b 100644 --- a/backend/apps/quiblet/api/v1/serializers.py +++ b/backend/apps/quiblet/api/v1/serializers.py @@ -18,7 +18,23 @@ def validate_name(self, name): return name +class QuibletSlimSerializer(ModelSerializer): + class Meta: + model = Quiblet + fields = ('name', 'avatar') + + class QuibSerializer(ModelSerializer): + quiblet = QuibletSerializer(read_only=True) + class Meta: model = Quib fields = '__all__' + + +class QuibSlimSerializer(ModelSerializer): + quiblet = QuibletSlimSerializer(read_only=True) + + class Meta: + model = Quib + exclude = ('quibber',) diff --git a/backend/apps/quiblet/api/v1/viewsets.py b/backend/apps/quiblet/api/v1/viewsets.py index 002e4eb1..d928070b 100644 --- a/backend/apps/quiblet/api/v1/viewsets.py +++ b/backend/apps/quiblet/api/v1/viewsets.py @@ -6,7 +6,7 @@ from common.patches.request import PatchedHttpRequest from ...models import Quib, Quiblet -from .serializers import QuibletSerializer, QuibSerializer +from .serializers import QuibletSerializer, QuibSerializer, QuibSlimSerializer @extend_schema(tags=['quibs & quiblets']) @@ -28,4 +28,8 @@ def perform_create(self, serializer): @extend_schema(tags=['quibs & quiblets']) class QuibViewSet(ModelViewSet): queryset = Quib.objects.all() - serializer_class = QuibSerializer + + def get_serializer_class(self): # pyright: ignore + if self.action == 'list': + return QuibSlimSerializer + return QuibSerializer diff --git a/backend/apps/quiblet/migrations/0003_quib_cover.py b/backend/apps/quiblet/migrations/0003_quib_cover.py new file mode 100644 index 00000000..90a52be4 --- /dev/null +++ b/backend/apps/quiblet/migrations/0003_quib_cover.py @@ -0,0 +1,26 @@ +# Generated by Django 5.1.4 on 2024-12-13 02:45 + +import dynamic_filenames +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('quiblet', '0002_initial'), + ] + + operations = [ + migrations.AddField( + model_name='quib', + name='cover', + field=models.ImageField( + blank=True, + null=True, + upload_to=dynamic_filenames.FilePattern( + filename_pattern='cover/{uuid:s}{ext}' + ), + verbose_name='cover', + ), + ), + ] diff --git a/backend/apps/quiblet/migrations/0004_remove_quib_dislikes_remove_quib_likes_quib_comments_and_more.py b/backend/apps/quiblet/migrations/0004_remove_quib_dislikes_remove_quib_likes_quib_comments_and_more.py new file mode 100644 index 00000000..57c15c02 --- /dev/null +++ b/backend/apps/quiblet/migrations/0004_remove_quib_dislikes_remove_quib_likes_quib_comments_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 5.1.4 on 2024-12-13 10:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('comment', '0001_initial'), + ('quiblet', '0003_quib_cover'), + ('user', '0003_alter_profile_username'), + ] + + operations = [ + migrations.RemoveField( + model_name='quib', + name='dislikes', + ), + migrations.RemoveField( + model_name='quib', + name='likes', + ), + migrations.AddField( + model_name='quib', + name='comments', + field=models.ManyToManyField( + blank=True, + related_name='comments', + to='comment.comment', + verbose_name='comments', + ), + ), + migrations.AddField( + model_name='quib', + name='downvotes', + field=models.ManyToManyField( + blank=True, + related_name='downvoted_quibs', + to='user.profile', + verbose_name='downvotes', + ), + ), + migrations.AddField( + model_name='quib', + name='upvotes', + field=models.ManyToManyField( + blank=True, + related_name='upvoted_quibs', + to='user.profile', + verbose_name='upvotes', + ), + ), + ] diff --git a/backend/apps/quiblet/models.py b/backend/apps/quiblet/models.py index 0ed343ac..ca8e535f 100644 --- a/backend/apps/quiblet/models.py +++ b/backend/apps/quiblet/models.py @@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _ from dynamic_filenames import FilePattern +from apps.comment.models import Comment from apps.user.models import Profile from common.mixins.model_mixins import ( AvatarMixin, @@ -13,13 +14,17 @@ ShortUUIDMixin, ) +cover_file_pattern = FilePattern(filename_pattern="cover/{uuid:s}{ext}") + +# models + class Quiblet(AvatarMixin, CreatedAtMixin, IsPublicMixin): name = models.CharField(_('name'), unique=True, max_length=25) description = models.TextField(_('description')) cover = models.ImageField( _('cover'), - upload_to=FilePattern(filename_pattern="cover/{uuid:s}{ext}"), + upload_to=cover_file_pattern, blank=True, null=True, ) @@ -58,11 +63,20 @@ class Quib(CreatedAtMixin, IsPublicMixin, ShortUUIDMixin): title = models.CharField(_('title'), max_length=255) slug = models.SlugField(_('slug'), editable=False, max_length=25, blank=True) content = models.TextField(_('content')) - likes = models.ManyToManyField( - Profile, related_name='liked_quibs', blank=True, verbose_name=_('likes') + cover = models.ImageField( + _('cover'), + upload_to=cover_file_pattern, + blank=True, + null=True, + ) + upvotes = models.ManyToManyField( + Profile, related_name='upvoted_quibs', blank=True, verbose_name=_('upvotes') + ) + downvotes = models.ManyToManyField( + Profile, related_name='downvoted_quibs', blank=True, verbose_name=_('downvotes') ) - dislikes = models.ManyToManyField( - Profile, related_name='disliked_quibs', blank=True, verbose_name=_('dislikes') + comments = models.ManyToManyField( + Comment, related_name='comments', blank=True, verbose_name=_('comments') ) def save(self, *args, **kwargs): diff --git a/backend/config/settings.py b/backend/config/settings.py index 64fd9d74..053a536a 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -53,11 +53,14 @@ 'drf_standardized_errors', # file middleware 'django_cleanup', + # postgres ltree + 'django_ltree', ] SELF_APPS = [ 'apps.user', 'apps.quiblet', + 'apps.comment', ] INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + SELF_APPS diff --git a/backend/poetry.lock b/backend/poetry.lock index ae429d77..7e8f5ff4 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "asgiref" @@ -283,6 +283,21 @@ files = [ [package.dependencies] Django = ">=4.2" +[[package]] +name = "django-ltree-2" +version = "0.1.10" +description = "Continual of django-ltree" +optional = false +python-versions = ">=3.9" +files = [ + {file = "django_ltree_2-0.1.10-py3-none-any.whl", hash = "sha256:1b3b51c5b97beda5254cdf0dcef83a5c4258c791e3b2b6c331d1e52a8b1dd6a2"}, + {file = "django_ltree_2-0.1.10.tar.gz", hash = "sha256:1540aced6564429865b6330dfe7bbacbb3cedfdff3823b546859265117c9f048"}, +] + +[package.dependencies] +django = ">=3.2" +psycopg = ">=3" + [[package]] name = "django-rest-knox" version = "5.0.2" @@ -701,6 +716,29 @@ pyyaml = ">=6.0.2,<7.0.0" [package.extras] poetry-plugin = ["poetry (>=1.0,<2.0)"] +[[package]] +name = "psycopg" +version = "3.2.3" +description = "PostgreSQL database adapter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907"}, + {file = "psycopg-3.2.3.tar.gz", hash = "sha256:a5764f67c27bec8bfac85764d23c534af2c27b893550377e37ce59c12aac47a2"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""} +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +binary = ["psycopg-binary (==3.2.3)"] +c = ["psycopg-c (==3.2.3)"] +dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.11)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] +docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"] +pool = ["psycopg-pool"] +test = ["anyio (>=4.0)", "mypy (>=1.11)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"] + [[package]] name = "psycopg2-binary" version = "2.9.10" @@ -1166,4 +1204,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "4c73b102a188bd740568beb8009f232e6bd7dc9dfc700de4649ba2cc0fc04a92" +content-hash = "54ccfc824f80b2d5789b1639f0de254d0a1d0c49737d837e220755155d8b6671" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c4917e05..42f582ef 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -33,6 +33,7 @@ drf-spectacular = {extras = ["sidecar"], version = "^0.28.0"} shortuuid = "^1.0.13" # 3rd party exception handler drf-standardized-errors = {extras = ["openapi"], version = "^0.14.1"} +django-ltree-2 = "^0.1.10" [tool.poetry.group.dev.dependencies] # task runner diff --git a/frontend/src/lib/clients/v1.ts b/frontend/src/lib/clients/v1.ts index 28707574..494686c3 100644 --- a/frontend/src/lib/clients/v1.ts +++ b/frontend/src/lib/clients/v1.ts @@ -320,6 +320,7 @@ export interface components { color?: components['schemas']['ColorEnum']; /** Format: uri */ avatar?: string | null; + /** @description Required. 25 characters or fewer. Letters, digits and ./_ only. */ username?: string; first_name?: string | null; last_name?: string | null; @@ -327,13 +328,15 @@ export interface components { }; PatchedQuib: { readonly id?: string; + readonly quiblet?: components['schemas']['Quiblet']; /** Format: date-time */ readonly created_at?: string; is_public?: boolean; title?: string; readonly slug?: string; content?: string; - quiblet?: number; + /** Format: uri */ + cover?: string | null; /** Quibbler */ quibber?: number; likes?: number[]; @@ -361,6 +364,7 @@ export interface components { color?: components['schemas']['ColorEnum']; /** Format: uri */ avatar?: string | null; + /** @description Required. 25 characters or fewer. Letters, digits and ./_ only. */ username: string; first_name?: string | null; last_name?: string | null; @@ -867,6 +871,23 @@ export interface components { | 'surrogate_characters_not_allowed'; detail: string; }; + QQuibsCreateCoverErrorComponent: { + /** + * @description * `cover` - cover (enum property replaced by openapi-typescript) + * @enum {string} + */ + attr: 'cover'; + /** + * @description * `empty` - empty + * * `invalid` - invalid + * * `invalid_image` - invalid_image + * * `max_length` - max_length + * * `no_name` - no_name + * @enum {string} + */ + code: 'empty' | 'invalid' | 'invalid_image' | 'max_length' | 'no_name'; + detail: string; + }; QQuibsCreateDislikesErrorComponent: { /** * @description * `dislikes` - dislikes (enum property replaced by openapi-typescript) @@ -888,7 +909,7 @@ export interface components { | components['schemas']['QQuibsCreateIsPublicErrorComponent'] | components['schemas']['QQuibsCreateTitleErrorComponent'] | components['schemas']['QQuibsCreateContentErrorComponent'] - | components['schemas']['QQuibsCreateQuibletErrorComponent'] + | components['schemas']['QQuibsCreateCoverErrorComponent'] | components['schemas']['QQuibsCreateQuibberErrorComponent'] | components['schemas']['QQuibsCreateLikesErrorComponent'] | components['schemas']['QQuibsCreateDislikesErrorComponent']; @@ -952,22 +973,6 @@ export interface components { code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; detail: string; }; - QQuibsCreateQuibletErrorComponent: { - /** - * @description * `quiblet` - quiblet (enum property replaced by openapi-typescript) - * @enum {string} - */ - attr: 'quiblet'; - /** - * @description * `does_not_exist` - does_not_exist - * * `incorrect_type` - incorrect_type - * * `null` - null - * * `required` - required - * @enum {string} - */ - code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; - detail: string; - }; QQuibsCreateTitleErrorComponent: { /** * @description * `title` - title (enum property replaced by openapi-typescript) @@ -1022,6 +1027,23 @@ export interface components { | 'surrogate_characters_not_allowed'; detail: string; }; + QQuibsPartialUpdateCoverErrorComponent: { + /** + * @description * `cover` - cover (enum property replaced by openapi-typescript) + * @enum {string} + */ + attr: 'cover'; + /** + * @description * `empty` - empty + * * `invalid` - invalid + * * `invalid_image` - invalid_image + * * `max_length` - max_length + * * `no_name` - no_name + * @enum {string} + */ + code: 'empty' | 'invalid' | 'invalid_image' | 'max_length' | 'no_name'; + detail: string; + }; QQuibsPartialUpdateDislikesErrorComponent: { /** * @description * `dislikes` - dislikes (enum property replaced by openapi-typescript) @@ -1043,7 +1065,7 @@ export interface components { | components['schemas']['QQuibsPartialUpdateIsPublicErrorComponent'] | components['schemas']['QQuibsPartialUpdateTitleErrorComponent'] | components['schemas']['QQuibsPartialUpdateContentErrorComponent'] - | components['schemas']['QQuibsPartialUpdateQuibletErrorComponent'] + | components['schemas']['QQuibsPartialUpdateCoverErrorComponent'] | components['schemas']['QQuibsPartialUpdateQuibberErrorComponent'] | components['schemas']['QQuibsPartialUpdateLikesErrorComponent'] | components['schemas']['QQuibsPartialUpdateDislikesErrorComponent']; @@ -1107,22 +1129,6 @@ export interface components { code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; detail: string; }; - QQuibsPartialUpdateQuibletErrorComponent: { - /** - * @description * `quiblet` - quiblet (enum property replaced by openapi-typescript) - * @enum {string} - */ - attr: 'quiblet'; - /** - * @description * `does_not_exist` - does_not_exist - * * `incorrect_type` - incorrect_type - * * `null` - null - * * `required` - required - * @enum {string} - */ - code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; - detail: string; - }; QQuibsPartialUpdateTitleErrorComponent: { /** * @description * `title` - title (enum property replaced by openapi-typescript) @@ -1177,6 +1183,23 @@ export interface components { | 'surrogate_characters_not_allowed'; detail: string; }; + QQuibsUpdateCoverErrorComponent: { + /** + * @description * `cover` - cover (enum property replaced by openapi-typescript) + * @enum {string} + */ + attr: 'cover'; + /** + * @description * `empty` - empty + * * `invalid` - invalid + * * `invalid_image` - invalid_image + * * `max_length` - max_length + * * `no_name` - no_name + * @enum {string} + */ + code: 'empty' | 'invalid' | 'invalid_image' | 'max_length' | 'no_name'; + detail: string; + }; QQuibsUpdateDislikesErrorComponent: { /** * @description * `dislikes` - dislikes (enum property replaced by openapi-typescript) @@ -1198,7 +1221,7 @@ export interface components { | components['schemas']['QQuibsUpdateIsPublicErrorComponent'] | components['schemas']['QQuibsUpdateTitleErrorComponent'] | components['schemas']['QQuibsUpdateContentErrorComponent'] - | components['schemas']['QQuibsUpdateQuibletErrorComponent'] + | components['schemas']['QQuibsUpdateCoverErrorComponent'] | components['schemas']['QQuibsUpdateQuibberErrorComponent'] | components['schemas']['QQuibsUpdateLikesErrorComponent'] | components['schemas']['QQuibsUpdateDislikesErrorComponent']; @@ -1262,22 +1285,6 @@ export interface components { code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; detail: string; }; - QQuibsUpdateQuibletErrorComponent: { - /** - * @description * `quiblet` - quiblet (enum property replaced by openapi-typescript) - * @enum {string} - */ - attr: 'quiblet'; - /** - * @description * `does_not_exist` - does_not_exist - * * `incorrect_type` - incorrect_type - * * `null` - null - * * `required` - required - * @enum {string} - */ - code: 'does_not_exist' | 'incorrect_type' | 'null' | 'required'; - detail: string; - }; QQuibsUpdateTitleErrorComponent: { /** * @description * `title` - title (enum property replaced by openapi-typescript) @@ -1310,18 +1317,34 @@ export interface components { }; Quib: { readonly id: string; + readonly quiblet: components['schemas']['Quiblet']; /** Format: date-time */ readonly created_at: string; is_public?: boolean; title: string; readonly slug: string; content: string; - quiblet: number; + /** Format: uri */ + cover?: string | null; /** Quibbler */ quibber: number; likes?: number[]; dislikes?: number[]; }; + QuibSlim: { + readonly id: string; + readonly quiblet: components['schemas']['QuibletSlim']; + /** Format: date-time */ + readonly created_at: string; + is_public?: boolean; + title: string; + readonly slug: string; + content: string; + /** Format: uri */ + cover?: string | null; + likes?: number[]; + dislikes?: number[]; + }; Quiblet: { readonly id: number; /** Format: date-time */ @@ -1336,6 +1359,11 @@ export interface components { members?: number[]; rangers?: number[]; }; + QuibletSlim: { + name: string; + /** Format: uri */ + avatar?: string | null; + }; /** * @description * `server_error` - Server Error * @enum {string} @@ -2199,7 +2227,7 @@ export interface operations { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['Quib'][]; + 'application/json': components['schemas']['QuibSlim'][]; }; }; 500: { diff --git a/frontend/src/lib/components/pages/home/post.svelte b/frontend/src/lib/components/pages/home/quib.svelte similarity index 70% rename from frontend/src/lib/components/pages/home/post.svelte rename to frontend/src/lib/components/pages/home/quib.svelte index 4ade6bb4..a4cf5598 100644 --- a/frontend/src/lib/components/pages/home/post.svelte +++ b/frontend/src/lib/components/pages/home/quib.svelte @@ -1,22 +1,9 @@ @@ -25,14 +12,14 @@ class="relative flex flex-col gap-2 rounded-2xl border border-neutral bg-base-300 p-4 transition-colors hover:bg-base-200" >
- - -

q/{props.community.name}

+
+ +

q/{props.quiblet.name}

@@ -50,15 +37,15 @@