fix: gallery posts not show & fix types

This commit is contained in:
Lhcfl 2024-04-12 00:22:49 +08:00
parent ef94ba1474
commit d8b4eb6f5e
7 changed files with 93 additions and 27 deletions

View file

@ -19,7 +19,9 @@ export const GalleryPostRepository = db.getRepository(GalleryPost).extend({
createdAt: post.createdAt.toISOString(),
updatedAt: post.updatedAt.toISOString(),
userId: post.userId,
user: Users.pack(post.user || post.userId, me),
user: Users.pack(post.user || post.userId, me, {
detail: true,
}),
title: post.title,
description: post.description,
fileIds: post.fileIds,

View file

@ -38,7 +38,7 @@ export const packedGalleryPostSchema = {
},
user: {
type: "object",
ref: "UserLite",
ref: "UserDetailed",
optional: false,
nullable: false,
},
@ -79,5 +79,15 @@ export const packedGalleryPostSchema = {
optional: false,
nullable: false,
},
isLiked: {
type: "boolean",
optional: true,
nullable: false,
},
likedCount: {
type: "number",
optional: false,
nullable: false,
},
},
} as const;

View file

@ -2,10 +2,24 @@
<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel">
<div class="thumbnail">
<ImgWithBlurhash
v-if="post.files && post.files.length > 0"
class="img"
:src="post.files[0].thumbnailUrl"
:hash="post.files[0].blurhash"
/>
<div
v-else
class="_fullinfo"
>
<!-- If there is no picture
This can happen if the user deletes the image in the drive
-->
<img
src="/static-assets/badges/not-found.webp"
class="img"
:alt="i18n.ts.notFound"
/>
</div>
</div>
<article>
<header>
@ -20,9 +34,11 @@
<script lang="ts" setup>
import ImgWithBlurhash from "@/components/MkImgWithBlurhash.vue";
import { i18n } from "@/i18n";
import type { entities } from "firefish-js";
const props = defineProps<{
post: any;
defineProps<{
post: entities.GalleryPost;
}>();
</script>

View file

@ -22,7 +22,7 @@
<div class="body _block">
<div class="title">{{ post.title }}</div>
<div class="description">
<Mfm :text="post.description" />
<Mfm :text="post.description || ''" />
</div>
<div class="info">
<i :class="icon('ph-clock')"></i>
@ -59,7 +59,7 @@
<div class="other">
<button
v-if="
isSignedIn && me.id === post.user.id
isSignedIn && me!.id === post.user.id
"
v-tooltip="i18n.ts.toEdit"
v-click-anime
@ -105,7 +105,7 @@
<MkAcct :user="post.user" />
</div>
<MkFollowButton
v-if="!me || me.id != post.user.id"
v-if="!isSignedIn || me!.id != post.user.id"
:user="post.user"
:inline="true"
:transparent="false"
@ -140,7 +140,7 @@
</MkPagination>
</MkContainer>
</div>
<MkError v-else-if="error" @retry="fetch()" />
<MkError v-else-if="error" @retry="fetchPost()" />
<MkLoading v-else />
</transition>
</div>
@ -163,7 +163,8 @@ import { definePageMetadata } from "@/scripts/page-metadata";
import { shareAvailable } from "@/scripts/share-available";
import { defaultStore } from "@/store";
import icon from "@/scripts/icon";
import { isSignedIn } from "@/me";
import { isSignedIn, me } from "@/me";
import type { entities } from "firefish-js";
const router = useRouter();
@ -171,18 +172,19 @@ const props = defineProps<{
postId: string;
}>();
const post = ref(null);
const post = ref<entities.GalleryPost | null>(null);
const error = ref(null);
const otherPostsPagination = {
endpoint: "users/gallery/posts" as const,
limit: 6,
params: computed(() => ({
userId: post.value.user.id,
userId: post.value!.user.id,
})),
};
function fetchPost() {
post.value = null;
error.value = null;
os.api("gallery/posts/show", {
postId: props.postId,
})
@ -196,15 +198,15 @@ function fetchPost() {
function share() {
navigator.share({
title: post.value.title,
text: post.value.description,
url: `${url}/gallery/${post.value.id}`,
title: post.value!.title,
text: post.value!.description || undefined,
url: `${url}/gallery/${post.value!.id}`,
});
}
function shareWithNote() {
os.post({
initialText: `${post.value.title} ${url}/gallery/${post.value.id}`,
initialText: `${post.value!.title} ${url}/gallery/${post.value!.id}`,
});
}
@ -212,8 +214,8 @@ function like() {
os.api("gallery/posts/like", {
postId: props.postId,
}).then(() => {
post.value.isLiked = true;
post.value.likedCount++;
post.value!.isLiked = true;
post.value!.likedCount++;
});
}
@ -221,13 +223,13 @@ async function unlike() {
os.api("gallery/posts/unlike", {
postId: props.postId,
}).then(() => {
post.value.isLiked = false;
post.value.likedCount--;
post.value!.isLiked = false;
post.value!.likedCount--;
});
}
function edit() {
router.push(`/gallery/${post.value.id}/edit`);
router.push(`/gallery/${post.value!.id}/edit`);
}
watch(() => props.postId, fetchPost, { immediate: true });

View file

@ -432,7 +432,12 @@ export type Endpoints = {
"gallery/posts/create": { req: TODO; res: TODO };
"gallery/posts/delete": { req: { postId: GalleryPost["id"] }; res: null };
"gallery/posts/like": { req: TODO; res: TODO };
"gallery/posts/show": { req: TODO; res: TODO };
"gallery/posts/show": {
req: {
postId: GalleryPost["id"];
};
res: GalleryPost;
};
"gallery/posts/unlike": { req: TODO; res: TODO };
"gallery/posts/update": { req: TODO; res: TODO };
@ -474,7 +479,14 @@ export type Endpoints = {
res: NoteFavorite[];
};
"i/gallery/likes": { req: TODO; res: TODO };
"i/gallery/posts": { req: TODO; res: TODO };
"i/gallery/posts": {
req: {
limit?: number;
sinceId?: NoteFavorite["id"];
untilId?: NoteFavorite["id"];
};
res: GalleryPost[];
};
"i/get-word-muted-notes-count": { req: TODO; res: TODO };
"i/import-following": { req: TODO; res: TODO };
"i/import-user-lists": { req: TODO; res: TODO };
@ -890,7 +902,15 @@ export type Endpoints = {
};
res: FollowingFolloweePopulated[];
};
"users/gallery/posts": { req: TODO; res: TODO };
"users/gallery/posts": {
req: {
userId: User["id"];
limit?: number;
sinceId?: NoteFavorite["id"];
untilId?: NoteFavorite["id"];
};
res: GalleryPost[];
};
"users/get-frequently-replied-users": { req: TODO; res: TODO };
"users/groups/create": { req: TODO; res: TODO };
"users/groups/delete": { req: { groupId: UserGroup["id"] }; res: null };

View file

@ -136,7 +136,21 @@ export type DriveFile = {
export type DriveFolder = TODO;
export type GalleryPost = TODO;
export type GalleryPost = {
id: ID;
createdAt: DateString;
updatedAt: DateString;
title: string;
description: string | null;
userId: User["id"];
user: UserDetailed;
fileIds?: DriveFile["id"][];
files?: DriveFile[];
tags?: string[];
isSensitive: boolean;
isLiked?: boolean;
likedCount: number;
};
export type Note = {
id: ID;

View file

@ -8,7 +8,9 @@ import type {
Notification,
PageEvent,
User,
UserDetailed,
UserGroup,
UserLite,
} from "./entities";
import type { Connection } from "./streaming";
@ -26,9 +28,9 @@ export type Channels = {
mention: (payload: Note) => void;
reply: (payload: Note) => void;
renote: (payload: Note) => void;
follow: (payload: User) => void; // 自分が他人をフォローしたとき
followed: (payload: User) => void; // 他人が自分をフォローしたとき
unfollow: (payload: User) => void; // 自分が他人をフォロー解除したとき
follow: (payload: UserDetailed) => void; // 自分が他人をフォローしたとき
followed: (payload: UserLite) => void; // 他人が自分をフォローしたとき
unfollow: (payload: UserDetailed) => void; // 自分が他人をフォロー解除したとき
meUpdated: (payload: MeDetailed) => void;
pageEvent: (payload: PageEvent) => void;
urlUploadFinished: (payload: { marker: string; file: DriveFile }) => void;