Compare commits

..

No commits in common. "73b1e376a372fda2e7358dee2cd4df55b9bf3cfc" and "634fedf17c2c4f69d04ed92e94d62ec2d3ea6264" have entirely different histories.

19 changed files with 37 additions and 317 deletions

View File

@ -1,7 +1,7 @@
<template>
<v-menu eager :close-on-content-click="false">
<template #activator="{ props }">
<v-btn v-bind="props" icon rounded="circle" size="small" variant="text" :loading="loading">
<v-btn v-bind="props" stacked rounded="circle" size="small" variant="text" :loading="loading">
<v-badge v-if="pagination.total > 0" color="error" :content="pagination.total">
<v-icon icon="mdi-bell" />
</v-badge>

View File

@ -1,36 +0,0 @@
<template>
<v-menu>
<template #activator="{ props }">
<v-btn v-bind="props" icon="mdi-cog" variant="text" />
</template>
<v-list density="compact" lines="one">
<v-list-item disabled append-icon="mdi-flag" title="Report" />
<v-list-item v-if="isOwned" append-icon="mdi-pencil" title="Edit" @click="editChannel" />
<v-list-item v-if="isOwned" append-icon="mdi-delete" title="Delete" @click="deleteChannel" />
</v-list>
</v-menu>
</template>
<script setup lang="ts">
import { useUserinfo } from "@/stores/userinfo"
import { useChannels } from "@/stores/channels"
import { computed } from "vue"
const id = useUserinfo()
const channels = useChannels()
const props = defineProps<{ item: any }>()
const isOwned = computed(() => props.item?.account_id === id.userinfo.idSet?.messaging)
function editChannel() {
channels.related.edit_to = props.item
channels.show.editor = true
}
function deleteChannel() {
channels.related.delete_to = props.item
channels.show.delete = true
}
</script>

View File

@ -1,61 +0,0 @@
<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

@ -1,77 +0,0 @@
<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

@ -1,42 +0,0 @@
<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

@ -1,16 +0,0 @@
<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

@ -22,7 +22,7 @@ const realms = useRealms()
const props = defineProps<{ item: any }>()
const isOwned = computed(() => props.item?.account_id === id.userinfo.idSet?.interactive)
const isOwned = computed(() => props.item?.account_id === id.userinfo.data.id)
function editRealm() {
realms.related.edit_to = props.item

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 realm will be deleted and never appear again. Are you confirm?
All posts belonging to this domain will be deleted and never appear again. Are you confirm?
</template>
<template #actions>
<div class="w-full flex justify-end">

View File

@ -1,29 +1,27 @@
<template>
<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 density="comfortable">
<v-list-subheader>
Realms
<v-badge color="warning" content="Alpha" inline />
</v-list-subheader>
<v-list-item
v-for="item in realms.available"
exact
append-icon="mdi-account-multiple"
prepend-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
append-icon="mdi-plus"
prepend-icon="mdi-plus"
title="Create a realm"
variant="plain"
:disabled="!id.userinfo.isLoggedIn"
@click="createRealm"
/>
</v-list-group>
</v-list>
</template>
<script setup lang="ts">

View File

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

View File

@ -3,9 +3,6 @@
<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>
@ -13,8 +10,6 @@
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

@ -4,13 +4,8 @@
<v-app-bar-nav-icon icon="mdi-chat" :loading="loading" />
<h2 class="ml-2 text-lg font-500">{{ channels.current?.name }}</h2>
<p class="ml-3 text-xs opacity-80">{{ channels.current?.description }}</p>
<v-spacer />
<div v-if="channels.current">
<channel-action :item="channels.current" />
</div>
</div>
</v-app-bar>
@ -25,7 +20,6 @@ import { request } from "@/scripts/request"
import { useRoute } from "vue-router"
import { ref, watch } from "vue"
import { useChannels } from "@/stores/channels"
import ChannelAction from "@/components/chat/channels/ChannelAction.vue"
const route = useRoute()
const channels = useChannels()
@ -53,13 +47,4 @@ watch(
},
{ immediate: true }
)
watch(() => channels.done, (val) => {
if (val) {
readMetadata().then(() => {
channels.messages = []
channels.done = false
})
}
}, { immediate: true })
</script>

View File

@ -34,18 +34,13 @@
</div>
</v-toolbar>
<v-list class="flex-grow-1" :opened="drawerMini ? [] : expanded" @update:opened="(val) => expanded = val">
<channel-list />
<v-divider class="border-opacity-75 my-2" />
<div class="flex-grow-1">
<realm-list />
</v-list>
</div>
<!-- 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" />
@ -57,12 +52,8 @@
</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>
@ -96,15 +87,16 @@
<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,12 +37,14 @@
</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 = reactive<{ edit_to: any; delete_to: any }>({
const related_to = 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, available, current, messages, list, connect, disconnect }
return { done, show, related_to, available, current, messages, list, connect, disconnect }
})

View File

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

View File

@ -9,7 +9,6 @@ export interface Userinfo {
isReady: boolean
isLoggedIn: boolean
displayName: string
idSet: { [id: string]: number }
data: any
}
@ -17,7 +16,6 @@ const defaultUserinfo: Userinfo = {
isReady: false,
isLoggedIn: false,
displayName: "Citizen",
idSet: {},
data: null
}
@ -49,29 +47,17 @@ export const useUserinfo = defineStore("userinfo", () => {
const res = await request("identity", "/api/users/me", {
headers: { Authorization: `Bearer ${await getAtk()}` }
})
if (res.status !== 200) {
return
}
const data = await res.json()
const federationResp = await Promise.all([
request("interactive", "/api/users/me", {
headers: { Authorization: `Bearer ${await getAtk()}` }
}),
request("messaging", "/api/users/me", {
headers: { Authorization: `Bearer ${await getAtk()}` }
})
])
userinfo.value = {
isReady: true,
isLoggedIn: true,
displayName: data["nick"],
idSet: {
interactive: (await federationResp[0].json())["id"],
messaging: (await federationResp[1].json())["id"]
},
data: data
}

View File

@ -73,14 +73,10 @@ async function readMore({ done }: any) {
}
watch(() => channels.current, (val) => {
if (val) {
pagination.page = 1
pagination.total = 0
readHistory()
}
},
{ immediate: true }
)
if (val) {
readHistory()
}
}, { immediate: true })
function scrollTop() {
window.scroll({ top: 0 })

View File

@ -105,8 +105,6 @@ watch(
() => route.params.realmId,
() => {
posts.value = []
pagination.page = 1
pagination.total = 0
readMetadata()
readPosts()
},