✨ More places will show menu
This commit is contained in:
		
							
								
								
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
			
		||||
# Default ignored files
 | 
			
		||||
/shelf/
 | 
			
		||||
/workspace.xml
 | 
			
		||||
# Editor-based HTTP Client requests
 | 
			
		||||
/httpRequests/
 | 
			
		||||
# Datasource local storage ignored files
 | 
			
		||||
/dataSources/
 | 
			
		||||
/dataSources.local.xml
 | 
			
		||||
							
								
								
									
										9
									
								
								.idea/Interactive.iml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								.idea/Interactive.iml
									
									
									
										generated
									
									
									
								
							@@ -1,9 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module type="WEB_MODULE" version="4">
 | 
			
		||||
  <component name="Go" enabled="true" />
 | 
			
		||||
  <component name="NewModuleRootManager">
 | 
			
		||||
    <content url="file://$MODULE_DIR$" />
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										53
									
								
								.idea/codeStyles/Project.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										53
									
								
								.idea/codeStyles/Project.xml
									
									
									
										generated
									
									
									
								
							@@ -1,53 +0,0 @@
 | 
			
		||||
<component name="ProjectCodeStyleConfiguration">
 | 
			
		||||
  <code_scheme name="Project" version="173">
 | 
			
		||||
    <HTMLCodeStyleSettings>
 | 
			
		||||
      <option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
 | 
			
		||||
    </HTMLCodeStyleSettings>
 | 
			
		||||
    <JSCodeStyleSettings version="0">
 | 
			
		||||
      <option name="FORCE_SEMICOLON_STYLE" value="true" />
 | 
			
		||||
      <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
 | 
			
		||||
      <option name="FORCE_QUOTE_STYlE" value="true" />
 | 
			
		||||
      <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
 | 
			
		||||
      <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
 | 
			
		||||
      <option name="SPACES_WITHIN_IMPORTS" value="true" />
 | 
			
		||||
    </JSCodeStyleSettings>
 | 
			
		||||
    <TypeScriptCodeStyleSettings version="0">
 | 
			
		||||
      <option name="FORCE_SEMICOLON_STYLE" value="true" />
 | 
			
		||||
      <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
 | 
			
		||||
      <option name="FORCE_QUOTE_STYlE" value="true" />
 | 
			
		||||
      <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
 | 
			
		||||
      <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
 | 
			
		||||
      <option name="SPACES_WITHIN_IMPORTS" value="true" />
 | 
			
		||||
    </TypeScriptCodeStyleSettings>
 | 
			
		||||
    <codeStyleSettings language="HTML">
 | 
			
		||||
      <option name="SOFT_MARGINS" value="120" />
 | 
			
		||||
      <indentOptions>
 | 
			
		||||
        <option name="INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="CONTINUATION_INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="TAB_SIZE" value="2" />
 | 
			
		||||
      </indentOptions>
 | 
			
		||||
    </codeStyleSettings>
 | 
			
		||||
    <codeStyleSettings language="JavaScript">
 | 
			
		||||
      <option name="SOFT_MARGINS" value="120" />
 | 
			
		||||
      <indentOptions>
 | 
			
		||||
        <option name="INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="CONTINUATION_INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="TAB_SIZE" value="2" />
 | 
			
		||||
      </indentOptions>
 | 
			
		||||
    </codeStyleSettings>
 | 
			
		||||
    <codeStyleSettings language="TypeScript">
 | 
			
		||||
      <option name="SOFT_MARGINS" value="120" />
 | 
			
		||||
      <indentOptions>
 | 
			
		||||
        <option name="INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="CONTINUATION_INDENT_SIZE" value="2" />
 | 
			
		||||
        <option name="TAB_SIZE" value="2" />
 | 
			
		||||
      </indentOptions>
 | 
			
		||||
    </codeStyleSettings>
 | 
			
		||||
    <codeStyleSettings language="Vue">
 | 
			
		||||
      <option name="SOFT_MARGINS" value="120" />
 | 
			
		||||
      <indentOptions>
 | 
			
		||||
        <option name="CONTINUATION_INDENT_SIZE" value="2" />
 | 
			
		||||
      </indentOptions>
 | 
			
		||||
    </codeStyleSettings>
 | 
			
		||||
  </code_scheme>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
									
									
										generated
									
									
									
								
							@@ -1,5 +0,0 @@
 | 
			
		||||
<component name="ProjectCodeStyleConfiguration">
 | 
			
		||||
  <state>
 | 
			
		||||
    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
 | 
			
		||||
  </state>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										12
									
								
								.idea/dataSources.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										12
									
								
								.idea/dataSources.xml
									
									
									
										generated
									
									
									
								
							@@ -1,12 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
 | 
			
		||||
    <data-source source="LOCAL" name="hy_interactive@localhost" uuid="2e2101b2-4037-47ee-88ed-456dc2cb4423">
 | 
			
		||||
      <driver-ref>postgresql</driver-ref>
 | 
			
		||||
      <synchronize>true</synchronize>
 | 
			
		||||
      <jdbc-driver>org.postgresql.Driver</jdbc-driver>
 | 
			
		||||
      <jdbc-url>jdbc:postgresql://localhost:5432/hy_interactive</jdbc-url>
 | 
			
		||||
      <working-dir>$ProjectFileDir$</working-dir>
 | 
			
		||||
    </data-source>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										11
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							@@ -1,11 +0,0 @@
 | 
			
		||||
<component name="InspectionProjectProfileManager">
 | 
			
		||||
  <profile version="1.0">
 | 
			
		||||
    <option name="myName" value="Project Default" />
 | 
			
		||||
    <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
 | 
			
		||||
      <Languages>
 | 
			
		||||
        <language minSize="54" name="TypeScript" />
 | 
			
		||||
      </Languages>
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
    <inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
 | 
			
		||||
  </profile>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							@@ -1,8 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ProjectModuleManager">
 | 
			
		||||
    <modules>
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/.idea/Interactive.iml" filepath="$PROJECT_DIR$/.idea/Interactive.iml" />
 | 
			
		||||
    </modules>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										7
									
								
								.idea/sqldialects.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								.idea/sqldialects.xml
									
									
									
										generated
									
									
									
								
							@@ -1,7 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="SqlDialectMappings">
 | 
			
		||||
    <file url="file://$PROJECT_DIR$/pkg/server/moments_api.go" dialect="PostgreSQL" />
 | 
			
		||||
    <file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/2e2101b2-4037-47ee-88ed-456dc2cb4423/console.sql" dialect="PostgreSQL" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="VcsDirectoryMappings">
 | 
			
		||||
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
@@ -11,5 +11,9 @@ module.exports = {
 | 
			
		||||
  ],
 | 
			
		||||
  parserOptions: {
 | 
			
		||||
    ecmaVersion: 'latest'
 | 
			
		||||
  },
 | 
			
		||||
  rules: {
 | 
			
		||||
    'vue/multi-word-component-names': 'off',
 | 
			
		||||
    'vue/valid-v-for': 'off'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								pkg/views/src/components/posts/PostAction.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								pkg/views/src/components/posts/PostAction.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-menu>
 | 
			
		||||
    <template #activator="{ props }">
 | 
			
		||||
      <v-btn v-bind="props" icon="mdi-dots-vertical" variant="text" size="x-small" />
 | 
			
		||||
    </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="editPost" />
 | 
			
		||||
      <v-list-item v-if="isOwned" append-icon="mdi-delete" title="Delete" @click="deletePost" />
 | 
			
		||||
    </v-list>
 | 
			
		||||
  </v-menu>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { useEditor } from "@/stores/editor"
 | 
			
		||||
import { useUserinfo } from "@/stores/userinfo";
 | 
			
		||||
import { computed } from "vue"
 | 
			
		||||
 | 
			
		||||
const id = useUserinfo()
 | 
			
		||||
const editor = useEditor()
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{ item: any }>()
 | 
			
		||||
 | 
			
		||||
const isOwned = computed(() => props.item?.author_id === id.userinfo.data.id)
 | 
			
		||||
 | 
			
		||||
function editPost() {
 | 
			
		||||
  editor.related.edit_to = props.item
 | 
			
		||||
  if (editor.show.hasOwnProperty(props.item.model_type)) {
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    editor.show[props.item.model_type] = true
 | 
			
		||||
  }
 | 
			
		||||
  if (props.item.model_type === "comment") {
 | 
			
		||||
    editor.related.comment_to = props.item
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function deletePost() {
 | 
			
		||||
  editor.related.delete_to = JSON.parse(JSON.stringify(props.item))
 | 
			
		||||
  editor.related.delete_to.model_type = props.item.model_type + "s"
 | 
			
		||||
  editor.show.delete = true
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="flex-grow-1 relative">
 | 
			
		||||
    <div class="flex-grow-1">
 | 
			
		||||
      <div class="font-bold">{{ props.item?.author.nick }}</div>
 | 
			
		||||
 | 
			
		||||
      <div v-if="props.item?.model_type === 'article'" class="text-xs text-grey-darken-4 mb-2">
 | 
			
		||||
@@ -36,66 +36,35 @@
 | 
			
		||||
      <div class="mt-1 text-xs opacity-80 flex gap-2 items-center">
 | 
			
		||||
        <span>Posted at {{ new Date(props.item?.created_at).toLocaleString() }}</span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
      <v-menu>
 | 
			
		||||
        <template #activator="{ props }">
 | 
			
		||||
          <div class="absolute right-0 top-0">
 | 
			
		||||
            <v-btn v-bind="props" icon="mdi-dots-vertical" variant="text" size="x-small" />
 | 
			
		||||
          </div>
 | 
			
		||||
        </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="editPost" />
 | 
			
		||||
          <v-list-item v-if="isOwned" append-icon="mdi-delete" title="Delete" @click="deletePost" />
 | 
			
		||||
        </v-list>
 | 
			
		||||
      </v-menu>
 | 
			
		||||
    <div>
 | 
			
		||||
      <post-action :item="props.item" />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, type Component } from "vue"
 | 
			
		||||
import { type Component } from "vue"
 | 
			
		||||
import { useUserinfo } from "@/stores/userinfo"
 | 
			
		||||
import { useEditor } from "@/stores/editor"
 | 
			
		||||
import ArticleContent from "@/components/posts/ArticleContent.vue"
 | 
			
		||||
import MomentContent from "@/components/posts/MomentContent.vue"
 | 
			
		||||
import CommentContent from "@/components/posts/CommentContent.vue"
 | 
			
		||||
import PostAttachment from "./PostAttachment.vue"
 | 
			
		||||
import PostAttachment from "@/components/posts/PostAttachment.vue"
 | 
			
		||||
import PostReaction from "@/components/posts/PostReaction.vue"
 | 
			
		||||
import PostAction from "@/components/posts/PostAction.vue"
 | 
			
		||||
 | 
			
		||||
const id = useUserinfo()
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{ item: any; brief?: boolean }>()
 | 
			
		||||
const emits = defineEmits(["update:item"])
 | 
			
		||||
 | 
			
		||||
const editor = useEditor()
 | 
			
		||||
 | 
			
		||||
const renderer: { [id: string]: Component } = {
 | 
			
		||||
  article: ArticleContent,
 | 
			
		||||
  moment: MomentContent,
 | 
			
		||||
  comment: CommentContent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const isOwned = computed(() => props.item?.author_id === id.userinfo.data.id)
 | 
			
		||||
 | 
			
		||||
function editPost() {
 | 
			
		||||
  editor.related.edit_to = props.item
 | 
			
		||||
  if (editor.show.hasOwnProperty(props.item.model_type)) {
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    editor.show[props.item.model_type] = true
 | 
			
		||||
  }
 | 
			
		||||
  if (props.item.model_type === "comment") {
 | 
			
		||||
    editor.related.comment_to = props.item
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function deletePost() {
 | 
			
		||||
  editor.related.delete_to = JSON.parse(JSON.stringify(props.item))
 | 
			
		||||
  editor.related.delete_to.model_type = props.item.model_type + "s"
 | 
			
		||||
  editor.show.delete = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updateReactions(symbol: string, num: number) {
 | 
			
		||||
  const item = JSON.parse(JSON.stringify(props.item))
 | 
			
		||||
  if (item.reaction_list == null) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								pkg/views/src/components/realms/RealmEditor.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								pkg/views/src/components/realms/RealmEditor.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <v-dialog :model-value="props.show" @update:model-value="(val) => emits('update:show', val)" class="max-w-[540px]">
 | 
			
		||||
    <v-card title="Organize a realm" prepend-icon="mdi-account-multiple" :loading="loading">
 | 
			
		||||
      <v-form @submit.prevent="submit">
 | 
			
		||||
        <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-card-text>
 | 
			
		||||
        <v-card-actions>
 | 
			
		||||
          <v-spacer></v-spacer>
 | 
			
		||||
 | 
			
		||||
          <v-btn type="reset" color="grey-darken-3" @click="emits('update:show', false)">Cancel</v-btn>
 | 
			
		||||
          <v-btn type="submit" :disabled="loading">Save</v-btn>
 | 
			
		||||
        </v-card-actions>
 | 
			
		||||
      </v-form>
 | 
			
		||||
    </v-card>
 | 
			
		||||
  </v-dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue"
 | 
			
		||||
import { getAtk } from "@/stores/userinfo"
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{ show: boolean }>()
 | 
			
		||||
const emits = defineEmits(["update:show", "relist"])
 | 
			
		||||
 | 
			
		||||
const realmTypeOptions = [
 | 
			
		||||
  { label: "Public Realm", value: 0 },
 | 
			
		||||
  { label: "Restricted Realm", value: 1 },
 | 
			
		||||
  { label: "Private Realm", value: 2 }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const error = ref<null | string>(null)
 | 
			
		||||
const loading = ref(false)
 | 
			
		||||
 | 
			
		||||
const data = ref({
 | 
			
		||||
  name: "",
 | 
			
		||||
  description: "",
 | 
			
		||||
  realm_type: 0
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
async function submit(evt: SubmitEvent) {
 | 
			
		||||
  const form = evt.target as HTMLFormElement
 | 
			
		||||
  const payload = data.value
 | 
			
		||||
  if (!payload.name) return
 | 
			
		||||
 | 
			
		||||
  loading.value = true
 | 
			
		||||
  const res = await fetch("/api/realms", {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
 | 
			
		||||
    body: JSON.stringify(payload)
 | 
			
		||||
  })
 | 
			
		||||
  if (res.status !== 200) {
 | 
			
		||||
    error.value = await res.text()
 | 
			
		||||
  } else {
 | 
			
		||||
    emits("relist")
 | 
			
		||||
    form.reset()
 | 
			
		||||
    emits("update:show", false)
 | 
			
		||||
  }
 | 
			
		||||
  loading.value = false
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -2,11 +2,7 @@
 | 
			
		||||
  <v-list density="comfortable">
 | 
			
		||||
    <v-list-subheader>
 | 
			
		||||
      Realms
 | 
			
		||||
      <v-badge
 | 
			
		||||
        color="warning"
 | 
			
		||||
        content="Alpha"
 | 
			
		||||
        inline
 | 
			
		||||
      />
 | 
			
		||||
      <v-badge color="warning" content="Alpha" inline />
 | 
			
		||||
    </v-list-subheader>
 | 
			
		||||
 | 
			
		||||
    <v-list-item
 | 
			
		||||
@@ -27,101 +23,35 @@
 | 
			
		||||
    />
 | 
			
		||||
  </v-list>
 | 
			
		||||
 | 
			
		||||
  <v-dialog v-model="creating" class="max-w-[540px]">
 | 
			
		||||
    <v-card title="Create a realm" prepend-icon="mdi-account-multiple-plus" :loading="loading">
 | 
			
		||||
      <v-form @submit.prevent="submit">
 | 
			
		||||
        <v-card-text>
 | 
			
		||||
          <v-text-field
 | 
			
		||||
            label="Name"
 | 
			
		||||
            variant="outlined"
 | 
			
		||||
            density="comfortable"
 | 
			
		||||
            v-model="requestData.name"
 | 
			
		||||
          />
 | 
			
		||||
          <v-textarea
 | 
			
		||||
            label="Description"
 | 
			
		||||
            variant="outlined"
 | 
			
		||||
            density="comfortable"
 | 
			
		||||
            v-model="requestData.description"
 | 
			
		||||
          />
 | 
			
		||||
          <v-select
 | 
			
		||||
            label="Realm type"
 | 
			
		||||
            item-title="label"
 | 
			
		||||
            item-value="value"
 | 
			
		||||
            variant="outlined"
 | 
			
		||||
            density="comfortable"
 | 
			
		||||
            :items="realmTypeOptions"
 | 
			
		||||
            v-model="requestData.realm_type"
 | 
			
		||||
          />
 | 
			
		||||
        </v-card-text>
 | 
			
		||||
        <v-card-actions>
 | 
			
		||||
          <v-spacer></v-spacer>
 | 
			
		||||
 | 
			
		||||
          <v-btn type="reset" color="grey-darken-3" @click="creating = false">Cancel</v-btn>
 | 
			
		||||
          <v-btn type="submit" :disabled="loading">Save</v-btn>
 | 
			
		||||
        </v-card-actions>
 | 
			
		||||
      </v-form>
 | 
			
		||||
    </v-card>
 | 
			
		||||
  </v-dialog>
 | 
			
		||||
  <realm-editor v-model:show="creating" @relist="list" />
 | 
			
		||||
 | 
			
		||||
  <!-- @vue-ignore -->
 | 
			
		||||
  <v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, ref } from "vue";
 | 
			
		||||
import { getAtk, useUserinfo } from "@/stores/userinfo";
 | 
			
		||||
import { useEditor } from "@/stores/editor";
 | 
			
		||||
import { computed, ref } from "vue"
 | 
			
		||||
import { useUserinfo } from "@/stores/userinfo"
 | 
			
		||||
import { useEditor } from "@/stores/editor"
 | 
			
		||||
import RealmEditor from "@/components/realms/RealmEditor.vue"
 | 
			
		||||
 | 
			
		||||
const id = useUserinfo();
 | 
			
		||||
const editor = useEditor();
 | 
			
		||||
const id = useUserinfo()
 | 
			
		||||
const editor = useEditor()
 | 
			
		||||
 | 
			
		||||
const realms = computed(() => editor.availableRealms);
 | 
			
		||||
const requestData = ref({
 | 
			
		||||
  name: "",
 | 
			
		||||
  description: "",
 | 
			
		||||
  realm_type: 0
 | 
			
		||||
});
 | 
			
		||||
const realms = computed(() => editor.availableRealms)
 | 
			
		||||
 | 
			
		||||
const realmTypeOptions = [
 | 
			
		||||
  { label: "Public Realm", value: 0 },
 | 
			
		||||
  { label: "Restricted Realm", value: 1 },
 | 
			
		||||
  { label: "Private Realm", value: 2 }
 | 
			
		||||
];
 | 
			
		||||
const creating = ref(false)
 | 
			
		||||
 | 
			
		||||
const creating = ref(false);
 | 
			
		||||
 | 
			
		||||
const error = ref<string | null>(null);
 | 
			
		||||
const reverting = ref(false);
 | 
			
		||||
const loading = ref(false);
 | 
			
		||||
const error = ref<string | null>(null)
 | 
			
		||||
const reverting = ref(false)
 | 
			
		||||
 | 
			
		||||
async function list() {
 | 
			
		||||
  reverting.value = true;
 | 
			
		||||
  reverting.value = true
 | 
			
		||||
  try {
 | 
			
		||||
    await editor.listRealms();
 | 
			
		||||
    await editor.listRealms()
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    error.value = (err as Error).message;
 | 
			
		||||
    error.value = (err as Error).message
 | 
			
		||||
  }
 | 
			
		||||
  reverting.value = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function submit(evt: SubmitEvent) {
 | 
			
		||||
  const form = evt.target as HTMLFormElement;
 | 
			
		||||
  const payload = requestData.value;
 | 
			
		||||
  if (!payload.name) return;
 | 
			
		||||
 | 
			
		||||
  loading.value = true;
 | 
			
		||||
  const res = await fetch("/api/realms", {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
 | 
			
		||||
    body: JSON.stringify(payload)
 | 
			
		||||
  });
 | 
			
		||||
  if (res.status !== 200) {
 | 
			
		||||
    error.value = await res.text();
 | 
			
		||||
  } else {
 | 
			
		||||
    await list();
 | 
			
		||||
    form.reset();
 | 
			
		||||
    creating.value = false;
 | 
			
		||||
  }
 | 
			
		||||
  loading.value = false;
 | 
			
		||||
  reverting.value = false
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
import { defineStore } from "pinia";
 | 
			
		||||
import { reactive, ref } from "vue";
 | 
			
		||||
import { checkLoggedIn, getAtk } from "@/stores/userinfo";
 | 
			
		||||
import { defineStore } from "pinia"
 | 
			
		||||
import { reactive, ref } from "vue"
 | 
			
		||||
import { checkLoggedIn, getAtk } from "@/stores/userinfo"
 | 
			
		||||
 | 
			
		||||
export const useEditor = defineStore("editor", () => {
 | 
			
		||||
  const done = ref(false);
 | 
			
		||||
  const done = ref(false)
 | 
			
		||||
 | 
			
		||||
  const show = reactive({
 | 
			
		||||
    moment: false,
 | 
			
		||||
    article: false,
 | 
			
		||||
    comment: false,
 | 
			
		||||
    delete: false
 | 
			
		||||
  });
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const related = reactive<{
 | 
			
		||||
    edit_to: any
 | 
			
		||||
@@ -24,24 +24,24 @@ export const useEditor = defineStore("editor", () => {
 | 
			
		||||
    reply_to: null,
 | 
			
		||||
    repost_to: null,
 | 
			
		||||
    delete_to: null
 | 
			
		||||
  });
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const availableRealms = ref<any[]>([]);
 | 
			
		||||
  const availableRealms = ref<any[]>([])
 | 
			
		||||
 | 
			
		||||
  async function listRealms() {
 | 
			
		||||
    if (!checkLoggedIn()) return;
 | 
			
		||||
    if (!checkLoggedIn()) return
 | 
			
		||||
 | 
			
		||||
    const res = await fetch("/api/realms/me/available", {
 | 
			
		||||
      headers: { Authorization: `Bearer ${getAtk()}` }
 | 
			
		||||
    });
 | 
			
		||||
    })
 | 
			
		||||
    if (res.status !== 200) {
 | 
			
		||||
      throw new Error(await res.text());
 | 
			
		||||
      throw new Error(await res.text())
 | 
			
		||||
    } else {
 | 
			
		||||
      availableRealms.value = await res.json();
 | 
			
		||||
      availableRealms.value = await res.json()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  listRealms().then(() => console.log("[STARTUP HOOK] Fetch available realm successes."));
 | 
			
		||||
  listRealms().then(() => console.log("[STARTUP HOOK] Fetch available realm successes."))
 | 
			
		||||
 | 
			
		||||
  return { show, related, availableRealms, listRealms, done };
 | 
			
		||||
});
 | 
			
		||||
  return { show, related, availableRealms, listRealms, done }
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,15 @@
 | 
			
		||||
      <v-card :loading="loading">
 | 
			
		||||
        <article>
 | 
			
		||||
          <v-card-text>
 | 
			
		||||
            <div class="px-3">
 | 
			
		||||
              <h1 class="text-lg font-medium">{{ post?.title }}</h1>
 | 
			
		||||
              <p class="text-sm">{{ post?.description }}</p>
 | 
			
		||||
            <div class="flex justify-between px-3">
 | 
			
		||||
              <div>
 | 
			
		||||
                <h1 class="text-lg font-medium">{{ post?.title }}</h1>
 | 
			
		||||
                <p class="text-sm">{{ post?.description }}</p>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div>
 | 
			
		||||
                <post-action :item="post" />
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <v-divider class="my-5 mx-[-16px] border-opacity-50" />
 | 
			
		||||
@@ -56,11 +62,12 @@
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue"
 | 
			
		||||
import { useRoute } from "vue-router"
 | 
			
		||||
import { request } from "@/scripts/request"
 | 
			
		||||
import ArticleContent from "@/components/posts/ArticleContent.vue"
 | 
			
		||||
import PostReaction from "@/components/posts/PostReaction.vue"
 | 
			
		||||
import PostAction from "@/components/posts/PostAction.vue"
 | 
			
		||||
import CommentList from "@/components/comments/CommentList.vue"
 | 
			
		||||
import { useRoute } from "vue-router"
 | 
			
		||||
 | 
			
		||||
const loading = ref(false)
 | 
			
		||||
const error = ref<string | null>(null)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,19 +4,25 @@
 | 
			
		||||
      <v-card :loading="loading">
 | 
			
		||||
        <article>
 | 
			
		||||
          <v-card-text>
 | 
			
		||||
            <div class="flex gap-2">
 | 
			
		||||
              <v-avatar
 | 
			
		||||
                color="grey-lighten-2"
 | 
			
		||||
                icon="mdi-account-circle"
 | 
			
		||||
                class="rounded-card"
 | 
			
		||||
                :image="post?.author.avatar"
 | 
			
		||||
              />
 | 
			
		||||
            <div class="flex justify-between px-3">
 | 
			
		||||
              <div class="flex gap-1">
 | 
			
		||||
                <v-avatar
 | 
			
		||||
                  color="grey-lighten-2"
 | 
			
		||||
                  icon="mdi-account-circle"
 | 
			
		||||
                  class="rounded-card me-2"
 | 
			
		||||
                  :image="post?.author.avatar"
 | 
			
		||||
                />
 | 
			
		||||
 | 
			
		||||
                <div>
 | 
			
		||||
                  <p class="font-bold">{{ post?.author.nick }}</p>
 | 
			
		||||
                  <p class="opacity-80">
 | 
			
		||||
                    {{ post?.author.description ? post?.author.description : "No description yet." }}
 | 
			
		||||
                  </p>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div>
 | 
			
		||||
                <p class="font-bold">{{ post?.author.nick }}</p>
 | 
			
		||||
                <p class="opacity-80">
 | 
			
		||||
                  {{ post?.author.description ? post?.author.description : "No description yet." }}
 | 
			
		||||
                </p>
 | 
			
		||||
                <post-action :item="post" />
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +75,7 @@ import MomentContent from "@/components/posts/MomentContent.vue"
 | 
			
		||||
import PostReaction from "@/components/posts/PostReaction.vue"
 | 
			
		||||
import CommentList from "@/components/comments/CommentList.vue"
 | 
			
		||||
import PostAttachment from "@/components/posts/PostAttachment.vue"
 | 
			
		||||
import PostAction from "@/components/posts/PostAction.vue"
 | 
			
		||||
 | 
			
		||||
const loading = ref(false)
 | 
			
		||||
const error = ref<string | null>(null)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user