🎨 Deconstruct the snackbar
This commit is contained in:
parent
49bd6ea363
commit
9bc387cb86
@ -103,9 +103,6 @@
|
||||
Uploading your media, please stand by...
|
||||
<v-progress-linear class="snackbar-progress" indeterminate />
|
||||
</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</v-form>
|
||||
</template>
|
||||
|
||||
@ -114,15 +111,15 @@ import { reactive, ref, watch } from "vue"
|
||||
import { request } from "@/scripts/request"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useChannels } from "@/stores/channels"
|
||||
import { useUI } from "@/stores/ui"
|
||||
import Attachments from "@/components/chat/parts/ChatAttachments.vue"
|
||||
import Media from "@/components/publish/parts/PublishMedia.vue"
|
||||
|
||||
const emits = defineEmits(["sent"])
|
||||
|
||||
const chat = ref<HTMLFormElement>()
|
||||
const channels = useChannels()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const uploading = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
@ -156,11 +153,10 @@ async function sendMessage() {
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
emits("sent")
|
||||
resetEditor()
|
||||
error.value = null
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
@ -203,10 +199,3 @@ function pasteMedia(evt: ClipboardEvent) {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.snackbar-progress {
|
||||
margin: 12px -16px -14px;
|
||||
width: calc(100% + 64px);
|
||||
}
|
||||
</style>
|
||||
|
@ -12,11 +12,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">The realm has been deleted.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -24,11 +19,11 @@ import { request } from "@/scripts/request"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useChannels } from "@/stores/channels"
|
||||
import { ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const channels = useChannels()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
async function deleteMessage() {
|
||||
@ -41,9 +36,9 @@ async function deleteMessage() {
|
||||
headers: { Authorization: `Bearer ${await getAtk()}` }
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
success.value = true
|
||||
showSnackbar("The message has been deleted.")
|
||||
channels.show.messages.delete = false
|
||||
channels.related.messages.delete_to = null
|
||||
}
|
||||
|
@ -12,11 +12,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">The realm has been deleted.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -25,6 +20,7 @@ import { getAtk } from "@/stores/userinfo"
|
||||
import { useChannels } from "@/stores/channels"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import { ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@ -32,8 +28,7 @@ const channels = useChannels()
|
||||
|
||||
const emits = defineEmits(["relist"])
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
async function deleteChannel() {
|
||||
@ -46,9 +41,9 @@ async function deleteChannel() {
|
||||
headers: { Authorization: `Bearer ${await getAtk()}` }
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
success.value = true
|
||||
showSnackbar("The channel has been deleted.")
|
||||
channels.show.delete = false
|
||||
channels.related.delete_to = null
|
||||
emits("relist")
|
||||
|
@ -15,9 +15,6 @@
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -25,12 +22,13 @@ import { ref, watch } from "vue"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { request } from "@/scripts/request"
|
||||
import { useChannels } from "@/stores/channels"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const emits = defineEmits(["relist"])
|
||||
|
||||
const channels = useChannels()
|
||||
|
||||
const error = ref<null | string>(null)
|
||||
const {showErrorSnackbar} = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
const data = ref({
|
||||
@ -54,7 +52,7 @@ async function submit(evt: SubmitEvent) {
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
emits("relist")
|
||||
form.reset()
|
||||
|
@ -31,23 +31,20 @@
|
||||
<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>
|
||||
<v-btn v-bind="props" block prepend-icon="mdi-account-plus" variant="plain"> Invite someone</v-btn>
|
||||
</template>
|
||||
|
||||
<template #default="{ isActive }">
|
||||
<channel-invitation
|
||||
:item="props.item"
|
||||
@relist="listMembers"
|
||||
@error="(val) => (error = val)"
|
||||
@error="(val) => (showErrorSnackbar(val))"
|
||||
@close="isActive.value = false"
|
||||
/>
|
||||
</template>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
@ -57,6 +54,7 @@ import { request } from "@/scripts/request"
|
||||
import { getAtk, useUserinfo } from "@/stores/userinfo"
|
||||
import { computed } from "vue"
|
||||
import ChannelInvitation from "@/components/chat/channels/ChannelInvitation.vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const id = useUserinfo()
|
||||
|
||||
@ -68,8 +66,8 @@ const isOwned = computed(() => {
|
||||
return id.userinfo.idSet?.messaging === props.item?.account_id
|
||||
})
|
||||
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
watch(
|
||||
() => props.item,
|
||||
@ -85,9 +83,8 @@ async function listMembers(id: number) {
|
||||
loading.value = true
|
||||
const res = await request("messaging", `/api/channels/${id}/members`)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
error.value = null
|
||||
members.value = await res.json()
|
||||
}
|
||||
loading.value = false
|
||||
@ -103,7 +100,7 @@ async function kickMember(item: any) {
|
||||
})
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
await listMembers(props.item?.id)
|
||||
}
|
||||
|
20
src/components/common/SnackbarProvider.vue
Normal file
20
src/components/common/SnackbarProvider.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<v-snackbar v-model="ui.snackbar" v-bind="ui.snackbar">
|
||||
<div v-html="ui.snackbar.content"></div>
|
||||
|
||||
<v-progress-linear v-if="ui.snackbar.loading" class="snackbar-progress" indeterminate />
|
||||
</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const ui = useUI()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.snackbar-progress {
|
||||
margin: 12px -16px -14px;
|
||||
width: calc(100% + 64px);
|
||||
}
|
||||
</style>
|
@ -26,12 +26,6 @@
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<v-snackbar v-model="status.added" :timeout="3000">Your react has been added into post.</v-snackbar>
|
||||
<v-snackbar v-model="status.removed" :timeout="3000">Your react has been removed from post.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -39,8 +33,10 @@
|
||||
import { request } from "@/scripts/request"
|
||||
import { getAtk, useUserinfo } from "@/stores/userinfo"
|
||||
import { reactive, ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const id = useUserinfo()
|
||||
const {showSnackbar, showErrorSnackbar} = useUI()
|
||||
|
||||
const emits = defineEmits(["update"])
|
||||
const props = defineProps<{
|
||||
@ -62,9 +58,6 @@ function pickColor(): string {
|
||||
return colors[randomIndex]
|
||||
}
|
||||
|
||||
const status = reactive({ added: false, removed: false })
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
async function reactPost(symbol: string, attitude: number) {
|
||||
const res = await request("interactive", `/api/p/${props.model}/${props.item?.id}/react`, {
|
||||
method: "POST",
|
||||
@ -72,13 +65,13 @@ async function reactPost(symbol: string, attitude: number) {
|
||||
body: JSON.stringify({ symbol, attitude })
|
||||
})
|
||||
if (res.status === 201) {
|
||||
status.added = true
|
||||
showSnackbar("Your react has been added onto the post.")
|
||||
emits("update", symbol, 1)
|
||||
} else if (res.status === 204) {
|
||||
status.removed = true
|
||||
showSnackbar("Your react has been removed from the post.")
|
||||
emits("update", symbol, -1)
|
||||
} else {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -109,14 +109,10 @@
|
||||
<media ref="media" v-model:show="dialogs.media" v-model:uploading="uploading" v-model:value="data.attachments" />
|
||||
<publish-area v-model:show="dialogs.area" v-model:value="data.realm_id" />
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">Your article has been published.</v-snackbar>
|
||||
<v-snackbar v-model="uploading" :timeout="-1">
|
||||
Uploading your media, please stand by...
|
||||
<v-progress-linear class="snackbar-progress" indeterminate />
|
||||
</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -129,6 +125,7 @@ import { useRoute, useRouter } from "vue-router"
|
||||
import PlannedPublish from "@/components/publish/parts/PlannedPublish.vue"
|
||||
import Media from "@/components/publish/parts/PublishMedia.vue"
|
||||
import PublishArea from "@/components/publish/parts/PublishArea.vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const route = useRoute()
|
||||
const realms = useRealms()
|
||||
@ -160,10 +157,9 @@ const currentRealm = computed(() => {
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const reverting = ref(false)
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
const reverting = ref(false)
|
||||
const uploading = ref(false)
|
||||
|
||||
async function postArticle(evt: SubmitEvent) {
|
||||
@ -187,15 +183,15 @@ async function postArticle(evt: SubmitEvent) {
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` },
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status === 200) {
|
||||
if (res.status !== 200) {
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
const data = await res.json()
|
||||
success.value = true
|
||||
showSnackbar("Your article has been published.")
|
||||
editor.show.article = false
|
||||
|
||||
resetEditor(form)
|
||||
router.push({ name: "posts.details.articles", params: { alias: data.alias } })
|
||||
} else {
|
||||
error.value = await res.text()
|
||||
await router.push({ name: "posts.details.articles", params: { alias: data.alias } })
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
@ -19,11 +19,6 @@
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">Your comment has been published.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -31,7 +26,9 @@ import { request } from "@/scripts/request"
|
||||
import { useEditor } from "@/stores/editor"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { computed, ref, watch } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const editor = useEditor()
|
||||
|
||||
const target = computed<any>(() => editor.related.comment_to)
|
||||
@ -43,8 +40,6 @@ const postIdentifier = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
const data = ref<any>({
|
||||
@ -70,10 +65,10 @@ async function postComment(evt: SubmitEvent) {
|
||||
})
|
||||
if (res.status === 200) {
|
||||
form.reset()
|
||||
success.value = true
|
||||
showSnackbar("Your comment has been published.")
|
||||
editor.show.comment = false
|
||||
} else {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
}
|
||||
loading.value = false
|
||||
editor.done = true
|
||||
|
@ -75,14 +75,10 @@
|
||||
<media ref="media" v-model:show="dialogs.media" v-model:uploading="uploading" v-model:value="data.attachments" />
|
||||
<publish-area v-model:show="dialogs.area" v-model:value="data.realm_id" />
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">Your post has been published.</v-snackbar>
|
||||
<v-snackbar v-model="uploading" :timeout="-1">
|
||||
Uploading your media, please stand by...
|
||||
<v-progress-linear class="snackbar-progress" indeterminate />
|
||||
</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -94,6 +90,7 @@ import { useRoute, useRouter } from "vue-router"
|
||||
import PlannedPublish from "@/components/publish/parts/PlannedPublish.vue"
|
||||
import PublishArea from "@/components/publish/parts/PublishArea.vue"
|
||||
import Media from "@/components/publish/parts/PublishMedia.vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const route = useRoute()
|
||||
const editor = useEditor()
|
||||
@ -111,8 +108,7 @@ const data = ref<any>({
|
||||
attachments: []
|
||||
})
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
const uploading = ref(false)
|
||||
|
||||
@ -135,14 +131,15 @@ async function postMoment(evt: SubmitEvent) {
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status === 200) {
|
||||
resetEditor(form)
|
||||
const data = await res.json()
|
||||
success.value = true
|
||||
editor.show.moment = false
|
||||
|
||||
resetEditor(form)
|
||||
router.push({ name: "posts.details.moments", params: { alias: data.alias } })
|
||||
showSnackbar("Your post has been published.")
|
||||
|
||||
await router.push({ name: "posts.details.moments", params: { alias: data.alias } })
|
||||
} else {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
@ -12,11 +12,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">The post has been deleted.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -24,11 +19,11 @@ import { request } from "@/scripts/request"
|
||||
import { useEditor } from "@/stores/editor"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const editor = useEditor()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const {showSnackbar, showErrorSnackbar} = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
async function deletePost() {
|
||||
@ -41,9 +36,9 @@ async function deletePost() {
|
||||
headers: { Authorization: `Bearer ${await getAtk()}` }
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
success.value = true
|
||||
showSnackbar("The post has been deleted.")
|
||||
editor.show.delete = false
|
||||
editor.related.delete_to = null
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<v-dialog
|
||||
eager
|
||||
class="max-w-[540px]"
|
||||
:model-value="props.show"
|
||||
@update:model-value="(val) => emits('update:show', val)"
|
||||
|
@ -12,11 +12,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<v-snackbar v-model="success" :timeout="3000">The realm has been deleted.</v-snackbar>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -25,15 +20,15 @@ import { useRealms } from "@/stores/realms"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import { ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const { showSnackbar, showErrorSnackbar } = useUI()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const realms = useRealms()
|
||||
|
||||
const emits = defineEmits(["relist"])
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
async function deleteRealm() {
|
||||
@ -46,9 +41,9 @@ async function deleteRealm() {
|
||||
headers: { Authorization: `Bearer ${await getAtk()}` }
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
success.value = true
|
||||
showSnackbar("The realm has been deleted.")
|
||||
realms.show.delete = false
|
||||
realms.related.delete_to = null
|
||||
emits("relist")
|
||||
|
@ -22,9 +22,6 @@
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -32,6 +29,7 @@ import { ref, watch } from "vue"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { useRealms } from "@/stores/realms"
|
||||
import { request } from "@/scripts/request"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const emits = defineEmits(["relist"])
|
||||
|
||||
@ -43,7 +41,7 @@ const realmTypeOptions = [
|
||||
{ label: "Private Realm", value: 2 }
|
||||
]
|
||||
|
||||
const error = ref<null | string>(null)
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
const data = ref({
|
||||
@ -67,7 +65,7 @@ async function submit(evt: SubmitEvent) {
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
emits("relist")
|
||||
form.reset()
|
||||
|
@ -31,23 +31,20 @@
|
||||
<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>
|
||||
<v-btn v-bind="props" block prepend-icon="mdi-account-plus" variant="plain"> Invite someone</v-btn>
|
||||
</template>
|
||||
|
||||
<template #default="{ isActive }">
|
||||
<realm-invitation
|
||||
:item="props.item"
|
||||
@relist="listMembers"
|
||||
@error="(val) => (error = val)"
|
||||
@error="(val) => (showErrorSnackbar(val))"
|
||||
@close="isActive.value = false"
|
||||
/>
|
||||
</template>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -57,6 +54,7 @@ import { request } from "@/scripts/request"
|
||||
import { getAtk, useUserinfo } from "@/stores/userinfo"
|
||||
import { computed } from "vue"
|
||||
import RealmInvitation from "@/components/realms/RealmInvitation.vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const id = useUserinfo()
|
||||
|
||||
@ -68,8 +66,8 @@ const isOwned = computed(() => {
|
||||
return id.userinfo.data?.id === props.item?.account_id
|
||||
})
|
||||
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
watch(
|
||||
() => props.item,
|
||||
@ -85,9 +83,8 @@ async function listMembers(id: number) {
|
||||
loading.value = true
|
||||
const res = await request("interactive", `/api/realms/${id}/members`)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
error.value = null
|
||||
members.value = await res.json()
|
||||
}
|
||||
loading.value = false
|
||||
@ -103,7 +100,7 @@ async function kickMember(item: any) {
|
||||
})
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
await listMembers(props.item?.id)
|
||||
}
|
||||
|
@ -31,9 +31,6 @@
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -41,10 +38,11 @@ import { request } from "@/scripts/request"
|
||||
import { getAtk } from "@/stores/userinfo"
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
import { useNotifications } from "@/stores/notifications";
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const notify = useNotifications()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const submitting = ref(false)
|
||||
const loading = computed(() => notify.loading || submitting.value)
|
||||
|
||||
@ -55,10 +53,9 @@ async function markAsRead(item: any, idx: number) {
|
||||
headers: { Authorization: `Bearer ${getAtk()}` },
|
||||
})
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
notify.remove(idx)
|
||||
error.value = null
|
||||
}
|
||||
submitting.value = false
|
||||
}
|
@ -4,17 +4,19 @@
|
||||
|
||||
<router-view />
|
||||
|
||||
<snackbar-provider />
|
||||
|
||||
<realm-tools />
|
||||
<channel-tools />
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue"
|
||||
import { Capacitor } from "@capacitor/core"
|
||||
import { onMounted } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
import RealmTools from "@/components/realms/RealmTools.vue"
|
||||
import ChannelTools from "@/components/chat/channels/ChannelTools.vue"
|
||||
import SnackbarProvider from "@/components/common/SnackbarProvider.vue"
|
||||
|
||||
const ui = useUI()
|
||||
|
||||
|
@ -15,9 +15,6 @@
|
||||
</v-app-bar>
|
||||
|
||||
<router-view />
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -26,20 +23,21 @@ import { useRoute } from "vue-router"
|
||||
import { onMounted, ref, watch } from "vue"
|
||||
import { useChannels } from "@/stores/channels"
|
||||
import ChannelAction from "@/components/chat/channels/ChannelAction.vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const { showErrorSnackbar } = useUI()
|
||||
|
||||
const route = useRoute()
|
||||
const channels = useChannels()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const loading = ref(false)
|
||||
|
||||
async function readMetadata() {
|
||||
loading.value = true
|
||||
const res = await request("messaging", `/api/channels/${route.params.channel}`)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
} else {
|
||||
error.value = null
|
||||
channels.current = await res.json()
|
||||
}
|
||||
loading.value = false
|
||||
|
@ -108,7 +108,7 @@ import { useUserinfo, signout as signoutAccount } from "@/stores/userinfo"
|
||||
import { useWellKnown } from "@/stores/wellKnown"
|
||||
import { useUI } from "@/stores/ui"
|
||||
import RealmList from "@/components/realms/RealmList.vue"
|
||||
import NotificationList from "@/components/NotificationList.vue"
|
||||
import NotificationList from "@/components/users/NotificationList.vue"
|
||||
import ChannelList from "@/components/chat/channels/ChannelList.vue"
|
||||
|
||||
const ui = useUI()
|
||||
|
@ -1,11 +1,27 @@
|
||||
import { defineStore } from "pinia"
|
||||
import { reactive } from "vue"
|
||||
import { reactive, ref } from "vue"
|
||||
|
||||
export const useUI = defineStore("ui", () => {
|
||||
const snackbar = ref<any>(null)
|
||||
|
||||
const safeArea = reactive({
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
bottom: 0
|
||||
})
|
||||
|
||||
return { safeArea }
|
||||
function showSnackbar(content: string, opts?: any, timeout = 3000) {
|
||||
snackbar.value = {
|
||||
...opts,
|
||||
content,
|
||||
timeout
|
||||
}
|
||||
}
|
||||
|
||||
function showErrorSnackbar(content: string, opts?: any) {
|
||||
showSnackbar(`Something went wrong... ${content}`, {
|
||||
...opts
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
return { safeArea, snackbar, showSnackbar, showErrorSnackbar }
|
||||
})
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, type Component } from "vue"
|
||||
import Copyright from "@/components/Copyright.vue"
|
||||
import Copyright from "@/components/common/Copyright.vue"
|
||||
import CallbackNotify from "@/components/auth/CallbackNotify.vue"
|
||||
import AccountLocator from "@/components/auth/AccountLocator.vue"
|
||||
import FactorPicker from "@/components/auth/FactorPicker.vue"
|
||||
|
@ -97,7 +97,7 @@
|
||||
import { ref } from "vue"
|
||||
import { request } from "@/scripts/request"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import Copyright from "@/components/Copyright.vue"
|
||||
import Copyright from "@/components/common/Copyright.vue"
|
||||
import CallbackNotify from "@/components/auth/CallbackNotify.vue"
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
|
@ -13,9 +13,6 @@
|
||||
>
|
||||
<chat-editor class="flex-grow-1" @sent="scrollTop" />
|
||||
</v-footer>
|
||||
|
||||
<!-- @vue-ignore -->
|
||||
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -37,7 +34,7 @@ const safeAreaBottom = computed(() => {
|
||||
|
||||
const chatList = ref<HTMLDivElement>()
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const loading = ref(false)
|
||||
|
||||
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
||||
@ -52,12 +49,12 @@ async function readHistory() {
|
||||
})
|
||||
)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
throw new Error()
|
||||
} else {
|
||||
const data = await res.json()
|
||||
pagination.total = data["count"]
|
||||
channels.messages.push(...(data["data"] ?? []))
|
||||
error.value = null
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
@ -74,13 +71,15 @@ async function readMore({ done }: any) {
|
||||
}
|
||||
|
||||
pagination.page++
|
||||
await readHistory()
|
||||
|
||||
if (error.value != null) done("error")
|
||||
else {
|
||||
try {
|
||||
await readHistory()
|
||||
} catch {
|
||||
done("error")
|
||||
}
|
||||
|
||||
if (pagination.total > 0) done("ok")
|
||||
else done("empty")
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
|
@ -18,10 +18,11 @@
|
||||
import PostList from "@/components/posts/PostList.vue"
|
||||
import { request } from "@/scripts/request"
|
||||
import { reactive, ref } from "vue"
|
||||
import { useUI } from "@/stores/ui"
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
||||
|
||||
const { showErrorSnackbar } = useUI()
|
||||
const posts = ref<any[]>([])
|
||||
|
||||
async function readPosts() {
|
||||
@ -34,9 +35,9 @@ async function readPosts() {
|
||||
})
|
||||
)
|
||||
if (res.status !== 200) {
|
||||
error.value = await res.text()
|
||||
showErrorSnackbar(await res.text())
|
||||
throw new Error()
|
||||
} else {
|
||||
error.value = null
|
||||
const data = await res.json()
|
||||
pagination.total = data["count"]
|
||||
posts.value.push(...(data["data"] ?? []))
|
||||
@ -51,13 +52,14 @@ async function readMore({ done }: any) {
|
||||
}
|
||||
|
||||
pagination.page++
|
||||
try {
|
||||
await readPosts()
|
||||
} catch {
|
||||
done("error")
|
||||
}
|
||||
|
||||
if (error.value != null) done("error")
|
||||
else {
|
||||
if (pagination.total > 0) done("ok")
|
||||
else done("empty")
|
||||
}
|
||||
}
|
||||
|
||||
readPosts()
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<v-container class="wrapper h-auto no-scrollbar">
|
||||
<div class="min-w-0 name-card col-span-2">
|
||||
<div class="min-w-0 name-card md:col-span-2 max-md:order-first">
|
||||
<v-card class="w-full">
|
||||
<v-img v-if="accountBanner" cover height="280px" :src="accountBanner" />
|
||||
<v-img v-if="accountBanner" cover max-height="280px" :aspect-ratio="16 / 9" :src="accountBanner" />
|
||||
|
||||
<v-card-text class="flex px-5 gap-1">
|
||||
<v-avatar
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
<div>
|
||||
<h3 class="font-bold">UID</h3>
|
||||
<p class="text-mono opacity-90">#{{ metadata?.id.toString().padStart(12, '0') }}</p>
|
||||
<p class="text-mono opacity-90">#{{ metadata?.id.toString().padStart(12, "0") }}</p>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
Reference in New Issue
Block a user