Channel establish

This commit is contained in:
LittleSheep 2024-03-31 00:38:13 +08:00
parent 634fedf17c
commit 012a02751c
12 changed files with 238 additions and 29 deletions

View File

@ -0,0 +1,61 @@
<template>
<v-card title="Delete a realm" class="min-h-[540px]" :loading="loading">
<template #text>
You are deleting a channel
<b>{{ channels.related.delete_to?.name }}</b> <br />
All messaging belonging to this channel will be deleted and never appear again. Are you confirm?
</template>
<template #actions>
<div class="w-full flex justify-end">
<v-btn color="grey-darken-3" @click="channels.show.delete = false">Not really</v-btn>
<v-btn color="error" :disabled="loading" @click="deletePost">Yes</v-btn>
</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">
import { request } from "@/scripts/request"
import { getAtk } from "@/stores/userinfo"
import { useChannels } from "@/stores/channels"
import { useRoute, useRouter } from "vue-router"
import { ref } from "vue"
const route = useRoute()
const router = useRouter()
const channels = useChannels()
const emits = defineEmits(["relist"])
const error = ref<string | null>(null)
const success = ref(false)
const loading = ref(false)
async function deletePost() {
const target = channels.related.delete_to
const url = `/api/channels/${target.id}`
loading.value = true
const res = await request("messaging", url, {
method: "DELETE",
headers: { Authorization: `Bearer ${await getAtk()}` }
})
if (res.status !== 200) {
error.value = await res.text()
} else {
success.value = true
channels.show.delete = false
channels.related.delete_to = null
emits("relist")
if (route.name?.toString()?.startsWith("realm")) {
router.push({ name: "explore" })
}
}
loading.value = false
}
</script>

View File

@ -0,0 +1,77 @@
<template>
<v-card title="Establish a channel" prepend-icon="mdi-pound-box" class="min-h-[540px]" :loading="loading">
<v-form @submit.prevent="submit">
<v-card-text>
<v-text-field label="Alias" variant="outlined" density="comfortable" hint="Must be unique"
v-model="data.alias" />
<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-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn type="reset" color="grey-darken-3" @click="channels.show.editor = false">Cancel</v-btn>
<v-btn type="submit" :disabled="loading">Save</v-btn>
</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">
import { ref, watch } from "vue"
import { getAtk } from "@/stores/userinfo"
import { request } from "@/scripts/request"
import { useChannels } from "@/stores/channels"
const emits = defineEmits(["relist"])
const channels = useChannels()
const error = ref<null | string>(null)
const loading = ref(false)
const data = ref({
alias: "",
name: "",
description: ""
})
async function submit(evt: SubmitEvent) {
const form = evt.target as HTMLFormElement
const payload = data.value
if (!payload.name) return
const url = channels.related.edit_to ? `/api/channels/${channels.related.edit_to?.id}` : "/api/channels"
const method = channels.related.edit_to ? "PUT" : "POST"
loading.value = true
const res = await request("messaging", url, {
method: method,
headers: { "Content-Type": "application/json", Authorization: `Bearer ${await getAtk()}` },
body: JSON.stringify(payload)
})
if (res.status !== 200) {
error.value = await res.text()
} else {
emits("relist")
form.reset()
channels.done = true
channels.show.editor = false
channels.related.edit_to = null
}
loading.value = false
}
watch(
channels.related,
(val) => {
if (val.edit_to) {
data.value = JSON.parse(JSON.stringify(val.edit_to))
}
},
{ immediate: true }
)
</script>

View File

@ -0,0 +1,42 @@
<template>
<v-list-group value="channels">
<template #activator="{ props }">
<v-list-item
v-bind="props"
prepend-icon="mdi-chat"
title="Channels"
/>
</template>
<v-list-item
v-for="item in channels.available"
exact
append-icon="mdi-pound-box"
:to="{ name: 'chat.channel', params: { channel: item.alias } }"
:title="item.name"
/>
<v-list-item
append-icon="mdi-plus"
title="Create a channel"
variant="plain"
:disabled="!id.userinfo.isLoggedIn"
@click="createChannel"
/>
</v-list-group>
</template>
<script setup lang="ts">
import { useUserinfo } from "@/stores/userinfo"
import { useRealms } from "@/stores/realms"
import { useChannels } from "@/stores/channels"
const id = useUserinfo()
const channels = useChannels()
function createChannel() {
channels.related.edit_to = null
channels.related.delete_to = null
channels.show.editor = true
}
</script>

View File

@ -0,0 +1,16 @@
<template>
<v-bottom-sheet class="max-w-[480px]" v-model="channels.show.editor">
<channel-editor @relist="channels.list" />
</v-bottom-sheet>
<v-bottom-sheet class="max-w-[480px]" v-model="channels.show.delete">
<channel-deletion @relist="channels.list" />
</v-bottom-sheet>
</template>
<script setup lang="ts">
import { useChannels } from "@/stores/channels"
import ChannelEditor from "@/components/chat/channels/ChannelEditor.vue"
import ChannelDeletion from "@/components/chat/channels/ChannelDeletion.vue"
const channels = useChannels()
</script>

View File

@ -3,7 +3,7 @@
<template #text>
You are deleting a realm
<b>{{ realms.related.delete_to?.name }}</b> <br />
All posts belonging to this domain will be deleted and never appear again. Are you confirm?
All posts belonging to this realm will be deleted and never appear again. Are you confirm?
</template>
<template #actions>
<div class="w-full flex justify-end">

View File

@ -1,27 +1,29 @@
<template>
<v-list density="comfortable">
<v-list-subheader>
Realms
<v-badge color="warning" content="Alpha" inline />
</v-list-subheader>
<v-list-group value="realms">
<template #activator="{ props }">
<v-list-item
v-bind="props"
prepend-icon="mdi-account-box-multiple"
title="Realms"
/>
</template>
<v-list-item
v-for="item in realms.available"
exact
prepend-icon="mdi-account-multiple"
append-icon="mdi-account-multiple"
:to="{ name: 'realms.page', params: { realmId: item.id } }"
:title="item.name"
/>
<v-divider v-if="realms.available.length > 0" class="border-opacity-75 my-2" />
<v-list-item
prepend-icon="mdi-plus"
append-icon="mdi-plus"
title="Create a realm"
variant="plain"
:disabled="!id.userinfo.isLoggedIn"
@click="createRealm"
/>
</v-list>
</v-list-group>
</template>
<script setup lang="ts">

View File

@ -1,8 +1,8 @@
<template>
<v-bottom-sheet v-model="realms.show.editor">
<v-bottom-sheet class="max-w-[480px]" v-model="realms.show.editor">
<realm-editor @relist="realms.list" />
</v-bottom-sheet>
<v-bottom-sheet v-model="realms.show.delete">
<v-bottom-sheet class="max-w-[480px]" v-model="realms.show.delete">
<realm-deletion @relist="realms.list" />
</v-bottom-sheet>
</template>

View File

@ -3,6 +3,9 @@
<v-system-bar v-show="ui.safeArea.top > 0" color="primary" :order="1" :height="ui.safeArea.top" />
<router-view />
<realm-tools />
<channel-tools />
</v-app>
</template>
@ -10,6 +13,8 @@
import { onMounted, ref } from "vue"
import { Capacitor } from "@capacitor/core"
import { useUI } from "@/stores/ui"
import RealmTools from "@/components/realms/RealmTools.vue"
import ChannelTools from "@/components/chat/channels/ChannelTools.vue"
const ui = useUI()

View File

@ -34,13 +34,18 @@
</div>
</v-toolbar>
<div class="flex-grow-1">
<v-list class="flex-grow-1" :opened="drawerMini ? [] : expanded" @update:opened="(val) => expanded = val">
<channel-list />
<v-divider class="border-opacity-75 my-2" />
<realm-list />
</div>
</v-list>
<!-- User info -->
<v-list class="border-opacity-15 h-[64px]" style="border-top-width: thin"
:style="`margin-bottom: ${safeAreaBottom}`">
<v-list
class="border-opacity-15 h-[64px]"
style="border-top-width: thin"
:style="`margin-bottom: ${safeAreaBottom}`"
>
<v-list-item :subtitle="username" :title="nickname">
<template #prepend>
<v-avatar icon="mdi-account-circle" :image="id.userinfo.data?.picture" />
@ -52,8 +57,12 @@
</template>
<v-list density="compact">
<v-list-item title="Solarpass" prepend-icon="mdi-passport-biometric" target="_blank"
:href="passportUrl" />
<v-list-item
title="Solarpass"
prepend-icon="mdi-passport-biometric"
target="_blank"
:href="passportUrl"
/>
</v-list>
</v-menu>
@ -87,16 +96,15 @@
<script setup lang="ts">
import { computed, ref } from "vue"
import { useEditor } from "@/stores/editor"
import { useUserinfo } from "@/stores/userinfo"
import { useWellKnown } from "@/stores/wellKnown"
import { useUI } from "@/stores/ui"
import PostTools from "@/components/publish/PostTools.vue"
import RealmTools from "@/components/realms/RealmTools.vue"
import RealmList from "@/components/realms/RealmList.vue"
import NotificationList from "@/components/NotificationList.vue"
import ChannelList from "@/components/chat/channels/ChannelList.vue"
const ui = useUI()
const expanded = ref<string[]>(["channels"])
const safeAreaTop = computed(() => {
return `${ui.safeArea.top}px`

View File

@ -37,14 +37,12 @@
</v-fab>
<post-tools />
<realm-tools />
</template>
<script setup lang="ts">
import PostTools from "@/components/publish/PostTools.vue"
import RealmTools from "@/components/realms/RealmTools.vue"
import { useEditor } from "@/stores/editor"
import { useUserinfo } from "@/stores/userinfo"
import PostTools from "@/components/publish/PostTools.vue"
const id = useUserinfo()
const editor = useEditor()

View File

@ -13,7 +13,7 @@ export const useChannels = defineStore("channels", () => {
delete: false
})
const related_to = reactive<{ edit_to: any; delete_to: any }>({
const related = reactive<{ edit_to: any; delete_to: any }>({
edit_to: null,
delete_to: null
})
@ -64,5 +64,5 @@ export const useChannels = defineStore("channels", () => {
socket.close()
}
return { done, show, related_to, available, current, messages, list, connect, disconnect }
return { done, show, related, available, current, messages, list, connect, disconnect }
})

View File

@ -11,7 +11,7 @@ export const useRealms = defineStore("realms", () => {
delete: false
})
const related_to = reactive<{ edit_to: any; delete_to: any }>({
const related = reactive<{ edit_to: any; delete_to: any }>({
edit_to: null,
delete_to: null
})
@ -31,5 +31,5 @@ export const useRealms = defineStore("realms", () => {
}
}
return { done, show, related: related_to, available, list }
return { done, show, related, available, list }
})