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> <template #text>
You are deleting a realm You are deleting a realm
<b>{{ realms.related.delete_to?.name }}</b> <br /> <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>
<template #actions> <template #actions>
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">

View File

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

View File

@ -1,8 +1,8 @@
<template> <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" /> <realm-editor @relist="realms.list" />
</v-bottom-sheet> </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" /> <realm-deletion @relist="realms.list" />
</v-bottom-sheet> </v-bottom-sheet>
</template> </template>

View File

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

View File

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

View File

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

View File

@ -13,7 +13,7 @@ export const useChannels = defineStore("channels", () => {
delete: false delete: false
}) })
const related_to = reactive<{ edit_to: any; delete_to: any }>({ const related = reactive<{ edit_to: any; delete_to: any }>({
edit_to: null, edit_to: null,
delete_to: null delete_to: null
}) })
@ -64,5 +64,5 @@ export const useChannels = defineStore("channels", () => {
socket.close() 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 delete: false
}) })
const related_to = reactive<{ edit_to: any; delete_to: any }>({ const related = reactive<{ edit_to: any; delete_to: any }>({
edit_to: null, edit_to: null,
delete_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 }
}) })