✨ Invite accounts
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
html, body, #app, .v-application {
|
||||
overflow: auto !important;
|
||||
font-family: "Roboto Sans", ui-sans-serif, system-ui, sans-serif;
|
||||
html,
|
||||
body,
|
||||
#app,
|
||||
.v-application {
|
||||
overflow: auto !important;
|
||||
font-family: "Roboto Sans", ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
.no-scrollbar {
|
||||
scrollbar-width: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
width: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
@@ -3,13 +3,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dompurify from "dompurify";
|
||||
import { parse } from "marked";
|
||||
import dompurify from "dompurify"
|
||||
import { parse } from "marked"
|
||||
|
||||
const props = defineProps<{ item: any }>();
|
||||
const props = defineProps<{ item: any }>()
|
||||
|
||||
function parseContent(src: string): string {
|
||||
return dompurify().sanitize(parse(src) as string);
|
||||
return dompurify().sanitize(parse(src) as string)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useEditor } from "@/stores/editor"
|
||||
import { useUserinfo } from "@/stores/userinfo";
|
||||
import { useUserinfo } from "@/stores/userinfo"
|
||||
import { computed } from "vue"
|
||||
|
||||
const id = useUserinfo()
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<div class="mb-3 px-1">
|
||||
<v-card>
|
||||
<template #text>
|
||||
<post-item brief :item="item" @update:item="val => updateItem(idx, val)" />
|
||||
<post-item brief :item="item" @update:item="(val) => updateItem(idx, val)" />
|
||||
</template>
|
||||
</v-card>
|
||||
</div>
|
||||
@@ -15,14 +15,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PostItem from "@/components/posts/PostItem.vue";
|
||||
import PostItem from "@/components/posts/PostItem.vue"
|
||||
|
||||
const props = defineProps<{ posts: any[], loader: (opts: any) => Promise<any> }>();
|
||||
const emits = defineEmits(["update:posts"]);
|
||||
const props = defineProps<{ posts: any[]; loader: (opts: any) => Promise<any> }>()
|
||||
const emits = defineEmits(["update:posts"])
|
||||
|
||||
function updateItem(idx: number, data: any) {
|
||||
const posts = JSON.parse(JSON.stringify(props.posts));
|
||||
posts[idx] = data;
|
||||
emits("update:posts", posts);
|
||||
const posts = JSON.parse(JSON.stringify(props.posts))
|
||||
posts[idx] = data
|
||||
emits("update:posts", posts)
|
||||
}
|
||||
</script>
|
||||
|
@@ -25,18 +25,37 @@
|
||||
You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b>
|
||||
</v-alert>
|
||||
|
||||
<v-textarea required class="mb-3" variant="outlined" label="Content"
|
||||
hint="The content supports markdown syntax" v-model="data.content" @paste="pasteMedia" />
|
||||
<v-textarea
|
||||
required
|
||||
class="mb-3"
|
||||
variant="outlined"
|
||||
label="Content"
|
||||
hint="The content supports markdown syntax"
|
||||
v-model="data.content"
|
||||
@paste="pasteMedia"
|
||||
/>
|
||||
|
||||
<v-expansion-panels>
|
||||
<v-expansion-panel title="Brief describe">
|
||||
<template #text>
|
||||
<div class="mt-1">
|
||||
<v-text-field required variant="solo-filled" density="comfortable" label="Title" :loading="reverting"
|
||||
v-model="data.title" />
|
||||
<v-text-field
|
||||
required
|
||||
variant="solo-filled"
|
||||
density="comfortable"
|
||||
label="Title"
|
||||
:loading="reverting"
|
||||
v-model="data.title"
|
||||
/>
|
||||
|
||||
<v-textarea required auto-grow variant="solo-filled" density="comfortable" label="Description"
|
||||
v-model="data.description" />
|
||||
<v-textarea
|
||||
required
|
||||
auto-grow
|
||||
variant="solo-filled"
|
||||
density="comfortable"
|
||||
label="Description"
|
||||
v-model="data.description"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</v-expansion-panel>
|
||||
@@ -47,7 +66,8 @@
|
||||
<div>
|
||||
<p class="text-xs">Your content will visible for public at</p>
|
||||
<p class="text-lg font-medium">
|
||||
{{ data.published_at ? new Date(data.published_at).toLocaleString() : new Date().toLocaleString()
|
||||
{{
|
||||
data.published_at ? new Date(data.published_at).toLocaleString() : new Date().toLocaleString()
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
@@ -103,12 +123,12 @@
|
||||
import { request } from "@/scripts/request"
|
||||
import { useEditor } from "@/stores/editor"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useRealms } from "@/stores/realms";
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import { useRealms } from "@/stores/realms"
|
||||
import { computed, reactive, ref, watch } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import PlannedPublish from "@/components/publish/parts/PlannedPublish.vue"
|
||||
import Media from "@/components/publish/parts/Media.vue"
|
||||
import PublishArea from "@/components/publish/parts/PublishArea.vue";
|
||||
import PublishArea from "@/components/publish/parts/PublishArea.vue"
|
||||
|
||||
const route = useRoute()
|
||||
const realms = useRealms()
|
||||
@@ -118,7 +138,7 @@ const dialogs = reactive({
|
||||
plan: false,
|
||||
categories: false,
|
||||
media: false,
|
||||
area: false,
|
||||
area: false
|
||||
})
|
||||
|
||||
const data = ref<any>({
|
||||
|
@@ -6,20 +6,40 @@
|
||||
You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b>
|
||||
</v-alert>
|
||||
|
||||
<v-textarea required persistent-counter variant="outlined" label="What's happened?!" counter="1024"
|
||||
v-model="data.content" @paste="pasteMedia" />
|
||||
<v-textarea
|
||||
required
|
||||
persistent-counter
|
||||
variant="outlined"
|
||||
label="What's happened?!"
|
||||
counter="1024"
|
||||
v-model="data.content"
|
||||
@paste="pasteMedia"
|
||||
/>
|
||||
|
||||
<div class="flex mt-[-18px]">
|
||||
<v-tooltip text="Planned publish" location="start">
|
||||
<template #activator="{ props }">
|
||||
<v-btn v-bind="props" type="button" variant="text" icon="mdi-calendar" size="small"
|
||||
@click="dialogs.plan = true" />
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
type="button"
|
||||
variant="text"
|
||||
icon="mdi-calendar"
|
||||
size="small"
|
||||
@click="dialogs.plan = true"
|
||||
/>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip text="Media" location="start">
|
||||
<template #activator="{ props }">
|
||||
<v-btn v-bind="props" icon class="text-none" type="button" variant="text" size="small"
|
||||
@click="dialogs.media = true">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon
|
||||
class="text-none"
|
||||
type="button"
|
||||
variant="text"
|
||||
size="small"
|
||||
@click="dialogs.media = true"
|
||||
>
|
||||
<v-badge v-if="data.attachments.length > 0" :content="data.attachments.length">
|
||||
<v-icon icon="mdi-camera" />
|
||||
</v-badge>
|
||||
|
@@ -20,6 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { request } from "@/scripts/request"
|
||||
import { useEditor } from "@/stores/editor"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { ref } from "vue"
|
||||
@@ -35,7 +36,7 @@ async function deletePost() {
|
||||
const url = `/api/p/${target.model_type}/${target.id}`
|
||||
|
||||
loading.value = true
|
||||
const res = await fetch(url, {
|
||||
const res = await request(url, {
|
||||
method: "DELETE",
|
||||
headers: { Authorization: `Bearer ${getAtk()}` }
|
||||
})
|
||||
|
@@ -28,10 +28,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRealms } from "@/stores/realms";
|
||||
import { useRealms } from "@/stores/realms"
|
||||
|
||||
const realms = useRealms();
|
||||
const realms = useRealms()
|
||||
|
||||
const props = defineProps<{ show: boolean; value: string | null }>();
|
||||
const emits = defineEmits(["update:show", "update:value"]);
|
||||
const props = defineProps<{ show: boolean; value: string | null }>()
|
||||
const emits = defineEmits(["update:show", "update:value"])
|
||||
</script>
|
||||
|
@@ -13,8 +13,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRealms } from "@/stores/realms";
|
||||
import { useUserinfo } from "@/stores/userinfo";
|
||||
import { useRealms } from "@/stores/realms"
|
||||
import { useUserinfo } from "@/stores/userinfo"
|
||||
import { computed } from "vue"
|
||||
|
||||
const id = useUserinfo()
|
||||
|
@@ -20,6 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { request } from "@/scripts/request"
|
||||
import { useRealms } from "@/stores/realms"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
@@ -40,7 +41,7 @@ async function deletePost() {
|
||||
const url = `/api/realms/${target.id}`
|
||||
|
||||
loading.value = true
|
||||
const res = await fetch(url, {
|
||||
const res = await request(url, {
|
||||
method: "DELETE",
|
||||
headers: { Authorization: `Bearer ${getAtk()}` }
|
||||
})
|
||||
|
@@ -4,8 +4,15 @@
|
||||
<v-card-text>
|
||||
<v-text-field label="Name" variant="outlined" density="comfortable" v-model="data.name" />
|
||||
<v-textarea label="Description" variant="outlined" density="comfortable" v-model="data.description" />
|
||||
<v-select label="Realm type" item-title="label" item-value="value" variant="outlined" density="comfortable"
|
||||
:items="realmTypeOptions" v-model="data.realm_type" />
|
||||
<v-select
|
||||
label="Realm type"
|
||||
item-title="label"
|
||||
item-value="value"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
:items="realmTypeOptions"
|
||||
v-model="data.realm_type"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
@@ -24,6 +31,7 @@
|
||||
import { ref, watch } from "vue"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useRealms } from "@/stores/realms"
|
||||
import { request } from "@/scripts/request"
|
||||
|
||||
const emits = defineEmits(["relist"])
|
||||
|
||||
@@ -53,7 +61,7 @@ async function submit(evt: SubmitEvent) {
|
||||
const method = realms.related.edit_to ? "PUT" : "POST"
|
||||
|
||||
loading.value = true
|
||||
const res = await fetch(url, {
|
||||
const res = await request(url, {
|
||||
method: method,
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
|
||||
body: JSON.stringify(payload)
|
||||
|
126
pkg/views/src/components/realms/RealmMembers.vue
Normal file
126
pkg/views/src/components/realms/RealmMembers.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-list density="comfortable" lines="one">
|
||||
<v-list-item v-for="item in members" :title="item.account.nick">
|
||||
<template #prepend>
|
||||
<v-avatar
|
||||
color="grey-lighten-2"
|
||||
icon="mdi-account-circle"
|
||||
class="rounded-card me-2"
|
||||
size="small"
|
||||
:image="item?.account.avatar"
|
||||
/>
|
||||
</template>
|
||||
<template #subtitle>@{{ item.account.name }}</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<div v-if="isOwned">
|
||||
<v-divider class="mt-2 mb-3 border-opacity-50 mx-[-1rem]" />
|
||||
|
||||
<div class="px-3">
|
||||
<v-dialog class="max-w-[540px]">
|
||||
<template #activator="{ props }">
|
||||
<v-btn v-bind="props" block prepend-icon="mdi-account-plus" variant="plain"> Invite someone </v-btn>
|
||||
</template>
|
||||
|
||||
<template #default="{ isActive }">
|
||||
<v-card prepend-icon="mdi-account-plus" title="Invite someone">
|
||||
<v-form @submit.prevent="inviteMember">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
label="Username"
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
hint="Require username not the nickname"
|
||||
v-model="data.account_name"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn type="reset" color="grey-darken-3" @click="isActive.value = false">Cancel</v-btn>
|
||||
<v-btn type="submit" :disabled="loading">Invite</v-btn>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue"
|
||||
import { request } from "@/scripts/request"
|
||||
import { getAtk, useUserinfo } from "@/stores/userinfo"
|
||||
import { computed } from "vue"
|
||||
|
||||
const id = useUserinfo()
|
||||
|
||||
const props = defineProps<{ item: any }>()
|
||||
|
||||
const data = ref<any>({
|
||||
account_name: ""
|
||||
})
|
||||
|
||||
const members = ref<any[]>([])
|
||||
|
||||
const isOwned = computed(() => {
|
||||
return id.userinfo.data?.id === props.item?.account_id
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
watch(
|
||||
() => props.item,
|
||||
(val) => {
|
||||
if (val?.id) {
|
||||
listMembers(val.id)
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
async function listMembers(id: number) {
|
||||
loading.value = true
|
||||
const res = await request(`/api/realms/${id}/members`)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
} else {
|
||||
error.value = null
|
||||
members.value = await res.json()
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
async function inviteMember(evt: SubmitEvent) {
|
||||
const form = evt.target as HTMLFormElement
|
||||
const payload = data.value
|
||||
|
||||
loading.value = true
|
||||
const res = await request(`/api/realms/${props.item?.id}/invite`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
} else {
|
||||
form.reset()
|
||||
await listMembers(props.item?.id)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.rounded-card {
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
@@ -99,7 +99,7 @@ import { useUserinfo } from "@/stores/userinfo"
|
||||
import { useWellKnown } from "@/stores/wellKnown"
|
||||
import PostTools from "@/components/publish/PostTools.vue"
|
||||
import RealmTools from "@/components/realms/RealmTools.vue"
|
||||
import RealmList from "@/components/realms/RealmList.vue";
|
||||
import RealmList from "@/components/realms/RealmList.vue"
|
||||
|
||||
const id = useUserinfo()
|
||||
const editor = useEditor()
|
||||
|
@@ -1,32 +1,32 @@
|
||||
import "virtual:uno.css";
|
||||
import "virtual:uno.css"
|
||||
|
||||
import "./assets/utils.css";
|
||||
import "./assets/utils.css"
|
||||
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import { createApp } from "vue"
|
||||
import { createPinia } from "pinia"
|
||||
|
||||
import "vuetify/styles";
|
||||
import { createVuetify } from "vuetify";
|
||||
import { md3 } from "vuetify/blueprints";
|
||||
import * as components from "vuetify/components";
|
||||
import * as labsComponents from 'vuetify/labs/components'
|
||||
import * as directives from "vuetify/directives";
|
||||
import "vuetify/styles"
|
||||
import { createVuetify } from "vuetify"
|
||||
import { md3 } from "vuetify/blueprints"
|
||||
import * as components from "vuetify/components"
|
||||
import * as labsComponents from "vuetify/labs/components"
|
||||
import * as directives from "vuetify/directives"
|
||||
|
||||
import "@mdi/font/css/materialdesignicons.min.css";
|
||||
import "@fontsource/roboto/latin.css";
|
||||
import "@unocss/reset/tailwind.css";
|
||||
import "@mdi/font/css/materialdesignicons.min.css"
|
||||
import "@fontsource/roboto/latin.css"
|
||||
import "@unocss/reset/tailwind.css"
|
||||
|
||||
import index from "./index.vue";
|
||||
import router from "./router";
|
||||
import index from "./index.vue"
|
||||
import router from "./router"
|
||||
|
||||
const app = createApp(index);
|
||||
const app = createApp(index)
|
||||
|
||||
app.use(
|
||||
createVuetify({
|
||||
directives,
|
||||
components: {
|
||||
...components,
|
||||
...labsComponents,
|
||||
...labsComponents
|
||||
},
|
||||
blueprint: md3,
|
||||
theme: {
|
||||
@@ -46,9 +46,9 @@ app.use(
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
app.use(createPinia());
|
||||
app.use(router);
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
app.mount("#app");
|
||||
app.mount("#app")
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import MasterLayout from "@/layouts/master.vue";
|
||||
import { createRouter, createWebHistory } from "vue-router"
|
||||
import MasterLayout from "@/layouts/master.vue"
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@@ -14,7 +14,6 @@ const router = createRouter({
|
||||
component: () => import("@/views/explore.vue")
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/p/moments/:alias",
|
||||
name: "posts.details.moments",
|
||||
@@ -34,6 +33,6 @@ const router = createRouter({
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
|
||||
export default router;
|
||||
export default router
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { reactive, ref } from "vue"
|
||||
import { defineStore } from "pinia"
|
||||
import { checkLoggedIn, getAtk } from "@/stores/userinfo"
|
||||
import { request } from "@/scripts/request"
|
||||
|
||||
export const useRealms = defineStore("realms", () => {
|
||||
const done = ref(false)
|
||||
@@ -20,7 +21,7 @@ export const useRealms = defineStore("realms", () => {
|
||||
async function list() {
|
||||
if (!checkLoggedIn()) return
|
||||
|
||||
const res = await fetch("/api/realms/me/available", {
|
||||
const res = await request("/api/realms/me/available", {
|
||||
headers: { Authorization: `Bearer ${getAtk()}` }
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
|
@@ -31,25 +31,25 @@ export const useUserinfo = defineStore("userinfo", () => {
|
||||
|
||||
async function readProfiles() {
|
||||
if (!checkLoggedIn()) {
|
||||
isReady.value = true;
|
||||
}
|
||||
|
||||
const res = await request("/api/users/me", {
|
||||
headers: { "Authorization": `Bearer ${getAtk()}` }
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
userinfo.value = {
|
||||
isReady: true,
|
||||
isLoggedIn: true,
|
||||
displayName: data["nick"],
|
||||
data: data
|
||||
};
|
||||
isReady.value = true
|
||||
}
|
||||
|
||||
const res = await request("/api/users/me", {
|
||||
headers: { Authorization: `Bearer ${getAtk()}` }
|
||||
})
|
||||
|
||||
if (res.status !== 200) {
|
||||
return
|
||||
}
|
||||
|
||||
const data = await res.json()
|
||||
|
||||
userinfo.value = {
|
||||
isReady: true,
|
||||
isLoggedIn: true,
|
||||
displayName: data["nick"],
|
||||
data: data
|
||||
}
|
||||
}
|
||||
|
||||
return { userinfo, isReady, readProfiles }
|
||||
|
@@ -15,46 +15,49 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PostList from "@/components/posts/PostList.vue";
|
||||
import { reactive, ref } from "vue";
|
||||
import { request } from "@/scripts/request";
|
||||
import PostList from "@/components/posts/PostList.vue"
|
||||
import { reactive, ref } from "vue"
|
||||
import { request } from "@/scripts/request"
|
||||
|
||||
const error = ref<string | null>(null);
|
||||
const pagination = reactive({ page: 1, pageSize: 10, total: 0 });
|
||||
const error = ref<string | null>(null)
|
||||
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
||||
|
||||
const posts = ref<any[]>([]);
|
||||
const posts = ref<any[]>([])
|
||||
|
||||
async function readPosts() {
|
||||
const res = await request(`/api/feed?` + new URLSearchParams({
|
||||
take: pagination.pageSize.toString(),
|
||||
offset: ((pagination.page - 1) * pagination.pageSize).toString()
|
||||
}));
|
||||
const res = await request(
|
||||
`/api/feed?` +
|
||||
new URLSearchParams({
|
||||
take: pagination.pageSize.toString(),
|
||||
offset: ((pagination.page - 1) * pagination.pageSize).toString()
|
||||
})
|
||||
)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text();
|
||||
error.value = await res.text()
|
||||
} else {
|
||||
error.value = null;
|
||||
const data = await res.json();
|
||||
pagination.total = data["count"];
|
||||
posts.value.push(...(data["data"] ?? []));
|
||||
error.value = null
|
||||
const data = await res.json()
|
||||
pagination.total = data["count"]
|
||||
posts.value.push(...(data["data"] ?? []))
|
||||
}
|
||||
}
|
||||
|
||||
async function readMore({ done }: any) {
|
||||
// Reach the end of data
|
||||
if (pagination.total <= pagination.page * pagination.pageSize) {
|
||||
done("empty");
|
||||
return;
|
||||
done("empty")
|
||||
return
|
||||
}
|
||||
|
||||
pagination.page++;
|
||||
await readPosts();
|
||||
pagination.page++
|
||||
await readPosts()
|
||||
|
||||
if (error.value != null) done("error");
|
||||
if (error.value != null) done("error")
|
||||
else {
|
||||
if (pagination.total > 0) done("ok");
|
||||
else done("empty");
|
||||
if (pagination.total > 0) done("ok")
|
||||
else done("empty")
|
||||
}
|
||||
}
|
||||
|
||||
readPosts();
|
||||
readPosts()
|
||||
</script>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
</div>
|
||||
|
||||
<div class="aside md:sticky top-0 w-full h-fit md:min-w-[280px] md:max-w-[320px] max-md:order-first">
|
||||
<v-card title="Realm Info" :loading="loading">
|
||||
<v-card :loading="loading">
|
||||
<template #title>
|
||||
<div class="flex justify-between">
|
||||
<span>Realm Info</span>
|
||||
@@ -23,6 +23,10 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<v-card class="mt-3 pb-3" title="Realm Members">
|
||||
<realm-members :item="metadata" />
|
||||
</v-card>
|
||||
</div>
|
||||
</v-container>
|
||||
</template>
|
||||
@@ -36,6 +40,7 @@ import { parse } from "marked"
|
||||
import dompurify from "dompurify"
|
||||
import PostList from "@/components/posts/PostList.vue"
|
||||
import RealmAction from "@/components/realms/RealmAction.vue"
|
||||
import RealmMembers from "@/components/realms/RealmMembers.vue"
|
||||
|
||||
const route = useRoute()
|
||||
const realms = useRealms()
|
||||
|
Reference in New Issue
Block a user