✨ New post editor basis
This commit is contained in:
parent
3ae72cd9e0
commit
e0bb05bee8
@ -16,6 +16,8 @@
|
|||||||
"@fontsource/roboto": "^5.0.8",
|
"@fontsource/roboto": "^5.0.8",
|
||||||
"@mdi/font": "^7.4.47",
|
"@mdi/font": "^7.4.47",
|
||||||
"@unocss/reset": "^0.58.5",
|
"@unocss/reset": "^0.58.5",
|
||||||
|
"dompurify": "^3.0.9",
|
||||||
|
"marked": "^12.0.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"universal-cookie": "^7.1.0",
|
"universal-cookie": "^7.1.0",
|
||||||
"unocss": "^0.58.5",
|
"unocss": "^0.58.5",
|
||||||
@ -26,7 +28,9 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.3.3",
|
"@rushstack/eslint-patch": "^1.3.3",
|
||||||
"@tsconfig/node20": "^20.1.2",
|
"@tsconfig/node20": "^20.1.2",
|
||||||
|
"@types/dompurify": "^3.0.5",
|
||||||
"@types/node": "^20.11.10",
|
"@types/node": "^20.11.10",
|
||||||
|
"@unocss/preset-typography": "^0.58.5",
|
||||||
"@vitejs/plugin-vue": "^5.0.3",
|
"@vitejs/plugin-vue": "^5.0.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vue/eslint-config-prettier": "^8.0.0",
|
"@vue/eslint-config-prettier": "^8.0.0",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="font-bold">{{ props.item?.author.nick }}</div>
|
<div class="font-bold">{{ props.item?.author.nick }}</div>
|
||||||
{{ props.item?.content }}
|
<div class="prose prose-post" v-html="parseContent(props.item.content)"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -21,11 +21,24 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import dompurify from "dompurify";
|
||||||
|
import { parse } from "marked";
|
||||||
|
|
||||||
const props = defineProps<{ item: any }>();
|
const props = defineProps<{ item: any }>();
|
||||||
|
|
||||||
|
function parseContent(src: string): string {
|
||||||
|
return dompurify().sanitize(parse(src) as string);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.rounded-card {
|
.rounded-card {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.prose.prose-post, p {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-infinite-scroll :items="props.posts" :onLoad="props.loader">
|
<v-infinite-scroll :items="props.posts" :onLoad="props.loader">
|
||||||
<template v-for="(item, index) in props.posts" :key="item">
|
<template v-for="item in props.posts" :key="item">
|
||||||
<div class="mb-3 px-1">
|
<div class="mb-3 px-1">
|
||||||
<post-item :item="item" />
|
<post-item :item="item" />
|
||||||
</div>
|
</div>
|
||||||
|
47
pkg/views/src/components/publish/PostEditor.vue
Normal file
47
pkg/views/src/components/publish/PostEditor.vue
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<v-dialog v-model="editor.show" class="max-w-[540px]">
|
||||||
|
<v-card title="New post">
|
||||||
|
<v-form>
|
||||||
|
<v-card-text>
|
||||||
|
<v-textarea
|
||||||
|
required
|
||||||
|
hide-details
|
||||||
|
variant="outlined"
|
||||||
|
label="What's happened?!"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="flex mt-1">
|
||||||
|
<v-tooltip text="Planned publish" location="start">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-btn v-bind="props" type="button" variant="text" icon="mdi-calendar" size="small" />
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-tooltip text="Categories" location="start">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-btn v-bind="props" type="button" variant="text" icon="mdi-shape" size="small" />
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-tooltip text="Media" location="start">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<v-btn v-bind="props" type="button" variant="text" icon="mdi-camera" size="small" />
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn type="reset" color="grey" @click="editor.show = false">Cancel</v-btn>
|
||||||
|
<v-btn type="submit" @click.prevent>Publish</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-form>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useEditor } from "@/stores/editor";
|
||||||
|
|
||||||
|
const editor = useEditor();
|
||||||
|
</script>
|
@ -25,11 +25,25 @@
|
|||||||
<v-main>
|
<v-main>
|
||||||
<router-view />
|
<router-view />
|
||||||
</v-main>
|
</v-main>
|
||||||
|
|
||||||
|
<v-fab
|
||||||
|
class="editor-fab"
|
||||||
|
icon="mdi-pencil"
|
||||||
|
color="primary"
|
||||||
|
size="64"
|
||||||
|
appear
|
||||||
|
@click="editor.show = true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<post-editor />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { useEditor } from "@/stores/editor";
|
||||||
|
import PostEditor from "@/components/publish/PostEditor.vue";
|
||||||
|
|
||||||
|
const editor = useEditor()
|
||||||
const navigationMenu = [
|
const navigationMenu = [
|
||||||
{ name: "Explore", icon: "mdi-compass", to: "explore" }
|
{ name: "Explore", icon: "mdi-compass", to: "explore" }
|
||||||
];
|
];
|
||||||
@ -40,3 +54,11 @@ function toggleDrawer() {
|
|||||||
drawerOpen.value = !drawerOpen.value;
|
drawerOpen.value = !drawerOpen.value;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.editor-fab {
|
||||||
|
position: fixed !important;
|
||||||
|
bottom: 16px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -9,6 +9,7 @@ import "vuetify/styles";
|
|||||||
import { createVuetify } from "vuetify";
|
import { createVuetify } from "vuetify";
|
||||||
import { md3 } from "vuetify/blueprints";
|
import { md3 } from "vuetify/blueprints";
|
||||||
import * as components from "vuetify/components";
|
import * as components from "vuetify/components";
|
||||||
|
import * as labsComponents from 'vuetify/labs/components'
|
||||||
import * as directives from "vuetify/directives";
|
import * as directives from "vuetify/directives";
|
||||||
|
|
||||||
import "@mdi/font/css/materialdesignicons.min.css";
|
import "@mdi/font/css/materialdesignicons.min.css";
|
||||||
@ -22,8 +23,11 @@ const app = createApp(index);
|
|||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
createVuetify({
|
createVuetify({
|
||||||
components,
|
|
||||||
directives,
|
directives,
|
||||||
|
components: {
|
||||||
|
...components,
|
||||||
|
...labsComponents,
|
||||||
|
},
|
||||||
blueprint: md3,
|
blueprint: md3,
|
||||||
theme: {
|
theme: {
|
||||||
defaultTheme: "original",
|
defaultTheme: "original",
|
||||||
|
8
pkg/views/src/stores/editor.ts
Normal file
8
pkg/views/src/stores/editor.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
export const useEditor = defineStore("editor", () => {
|
||||||
|
const show = ref(false);
|
||||||
|
|
||||||
|
return { show };
|
||||||
|
});
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-72px)] no-scrollbar">
|
<v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-64px)] no-scrollbar">
|
||||||
<div class="timeline flex-grow-1 mt-[-16px]">
|
<div class="timeline flex-grow-1 mt-[-16px]">
|
||||||
<post-list :loading="loading" :posts="posts" :loader="readMore" />
|
<post-list :loading="loading" :posts="posts" :loader="readMore" />
|
||||||
</div>
|
</div>
|
||||||
@ -56,4 +56,4 @@ async function readMore({ done }: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readPosts();
|
readPosts();
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { defineConfig, presetUno } from "unocss"
|
import { defineConfig, presetAttributify, presetTypography, presetUno } from "unocss";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
presets: [presetUno({ preflight: false })]
|
presets: [presetAttributify(), presetTypography(), presetUno({ preflight: false })]
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user