diff --git a/kitsune-fe/src/components/Post.vue b/kitsune-fe/src/components/Post.vue index ef1ea5a34..a969f65b0 100644 --- a/kitsune-fe/src/components/Post.vue +++ b/kitsune-fe/src/components/Post.vue @@ -115,7 +115,7 @@ & * { width: 100%; - max-height: 50ch; + max-height: 30ch; } } } diff --git a/kitsune-fe/src/graphql/post.ts b/kitsune-fe/src/graphql/post.ts new file mode 100644 index 000000000..1aa5cb252 --- /dev/null +++ b/kitsune-fe/src/graphql/post.ts @@ -0,0 +1,40 @@ +import { useQuery } from '@urql/vue'; + +import { computed } from 'vue'; + +import { graphql } from './types'; + +function getPostById(id: string) { + const { data } = useQuery({ + query: graphql(` + query getPostById($id: UUID!) { + getPostById(id: $id) { + id + subject + content + account { + id + displayName + username + avatar { + url + } + url + } + attachments { + contentType + description + url + } + } + } + `), + variables: { + id, + }, + }); + + return computed(() => data.value?.getPostById); +} + +export { getPostById }; diff --git a/kitsune-fe/src/graphql/types/gql.ts b/kitsune-fe/src/graphql/types/gql.ts index 900545c40..61c73b533 100644 --- a/kitsune-fe/src/graphql/types/gql.ts +++ b/kitsune-fe/src/graphql/types/gql.ts @@ -18,6 +18,8 @@ const documents = { types.RegisterUserDocument, '\n query getInstanceInfo {\n instance {\n description\n domain\n localPostCount\n registrationsOpen\n name\n userCount\n version\n captcha {\n backend\n key\n }\n }\n }\n ': types.GetInstanceInfoDocument, + '\n query getPostById($id: UUID!) {\n getPostById(id: $id) {\n id\n subject\n content\n account {\n id\n displayName\n username\n avatar {\n url\n }\n url\n }\n attachments {\n contentType\n description\n url\n }\n }\n }\n ': + types.GetPostByIdDocument, '\n query getHomeTimeline {\n homeTimeline(before: "00000000-0000-0000-0000-000000000000")\n @_relayPagination(mergeMode: "after") {\n nodes {\n id\n subject\n content\n url\n account {\n id\n avatar {\n url\n }\n displayName\n username\n url\n }\n attachments {\n contentType\n description\n url\n }\n }\n pageInfo {\n startCursor\n endCursor\n }\n }\n }\n ': types.GetHomeTimelineDocument, '\n mutation registerOauthApplication(\n $name: String!\n $redirect_uri: String!\n ) {\n registerOauthApplication(name: $name, redirectUri: $redirect_uri) {\n id\n secret\n redirectUri\n }\n }\n ': @@ -50,6 +52,12 @@ export function graphql( export function graphql( source: '\n query getInstanceInfo {\n instance {\n description\n domain\n localPostCount\n registrationsOpen\n name\n userCount\n version\n captcha {\n backend\n key\n }\n }\n }\n ', ): (typeof documents)['\n query getInstanceInfo {\n instance {\n description\n domain\n localPostCount\n registrationsOpen\n name\n userCount\n version\n captcha {\n backend\n key\n }\n }\n }\n ']; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql( + source: '\n query getPostById($id: UUID!) {\n getPostById(id: $id) {\n id\n subject\n content\n account {\n id\n displayName\n username\n avatar {\n url\n }\n url\n }\n attachments {\n contentType\n description\n url\n }\n }\n }\n ', +): (typeof documents)['\n query getPostById($id: UUID!) {\n getPostById(id: $id) {\n id\n subject\n content\n account {\n id\n displayName\n username\n avatar {\n url\n }\n url\n }\n attachments {\n contentType\n description\n url\n }\n }\n }\n ']; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/kitsune-fe/src/graphql/types/graphql.ts b/kitsune-fe/src/graphql/types/graphql.ts index 2c0ce6426..0a158790d 100644 --- a/kitsune-fe/src/graphql/types/graphql.ts +++ b/kitsune-fe/src/graphql/types/graphql.ts @@ -285,6 +285,34 @@ export type GetInstanceInfoQuery = { }; }; +export type GetPostByIdQueryVariables = Exact<{ + id: Scalars['UUID']['input']; +}>; + +export type GetPostByIdQuery = { + __typename?: 'RootQuery'; + getPostById: { + __typename?: 'Post'; + id: any; + subject?: string | null; + content: string; + account: { + __typename?: 'Account'; + id: any; + displayName?: string | null; + username: string; + url: string; + avatar?: { __typename?: 'MediaAttachment'; url: string } | null; + }; + attachments: Array<{ + __typename?: 'MediaAttachment'; + contentType: string; + description?: string | null; + url: string; + }>; + }; +}; + export type GetHomeTimelineQueryVariables = Exact<{ [key: string]: never }>; export type GetHomeTimelineQuery = { @@ -503,6 +531,103 @@ export const GetInstanceInfoDocument = { GetInstanceInfoQuery, GetInstanceInfoQueryVariables >; +export const GetPostByIdDocument = { + kind: 'Document', + definitions: [ + { + kind: 'OperationDefinition', + operation: 'query', + name: { kind: 'Name', value: 'getPostById' }, + variableDefinitions: [ + { + kind: 'VariableDefinition', + variable: { kind: 'Variable', name: { kind: 'Name', value: 'id' } }, + type: { + kind: 'NonNullType', + type: { kind: 'NamedType', name: { kind: 'Name', value: 'UUID' } }, + }, + }, + ], + selectionSet: { + kind: 'SelectionSet', + selections: [ + { + kind: 'Field', + name: { kind: 'Name', value: 'getPostById' }, + arguments: [ + { + kind: 'Argument', + name: { kind: 'Name', value: 'id' }, + value: { + kind: 'Variable', + name: { kind: 'Name', value: 'id' }, + }, + }, + ], + selectionSet: { + kind: 'SelectionSet', + selections: [ + { kind: 'Field', name: { kind: 'Name', value: 'id' } }, + { kind: 'Field', name: { kind: 'Name', value: 'subject' } }, + { kind: 'Field', name: { kind: 'Name', value: 'content' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'account' }, + selectionSet: { + kind: 'SelectionSet', + selections: [ + { kind: 'Field', name: { kind: 'Name', value: 'id' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'displayName' }, + }, + { + kind: 'Field', + name: { kind: 'Name', value: 'username' }, + }, + { + kind: 'Field', + name: { kind: 'Name', value: 'avatar' }, + selectionSet: { + kind: 'SelectionSet', + selections: [ + { + kind: 'Field', + name: { kind: 'Name', value: 'url' }, + }, + ], + }, + }, + { kind: 'Field', name: { kind: 'Name', value: 'url' } }, + ], + }, + }, + { + kind: 'Field', + name: { kind: 'Name', value: 'attachments' }, + selectionSet: { + kind: 'SelectionSet', + selections: [ + { + kind: 'Field', + name: { kind: 'Name', value: 'contentType' }, + }, + { + kind: 'Field', + name: { kind: 'Name', value: 'description' }, + }, + { kind: 'Field', name: { kind: 'Name', value: 'url' } }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], +} as unknown as DocumentNode; export const GetHomeTimelineDocument = { kind: 'Document', definitions: [ diff --git a/kitsune-fe/src/router.ts b/kitsune-fe/src/router.ts index 4fe1c1c46..e9a396c21 100644 --- a/kitsune-fe/src/router.ts +++ b/kitsune-fe/src/router.ts @@ -29,6 +29,10 @@ const routes = [ path: '/oauth-callback', component: () => import('./views/OAuthCallback.vue'), }, + { + path: '/posts/:id', + component: () => import('./views/PostPage.vue'), + }, { path: '/:catchAll(.*)', component: () => import('./views/NotFound.vue'), diff --git a/kitsune-fe/src/views/PostPage.vue b/kitsune-fe/src/views/PostPage.vue new file mode 100644 index 000000000..764c803ee --- /dev/null +++ b/kitsune-fe/src/views/PostPage.vue @@ -0,0 +1,28 @@ + + + + +