Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin): preview routing #482

Merged
merged 1 commit into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/admin/app/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,19 @@
</KeepAlive>
</RouterView>

<iframe ref="iframe" :src="previewUrl" class="h-full flex-1" />
<Preview />
</main>
</template>

<script lang="ts">
import { defineComponent, provide, ref, onBeforeMount } from 'vue3'
import { defineComponent } from 'vue3'
import AppHeader from './components/AppHeader.vue'
import { useApi } from './plugins/api'
import Preview from './components/Preview.vue'

export default defineComponent({
components: {
AppHeader
},

setup() {
const api = useApi()

const previewUrl = ref('http://localhost:4000')

onBeforeMount(async () => {
const { url } = (await api.get('/preview')) as any

previewUrl.value = url
})

provide('previewUrl', previewUrl)

return {
previewUrl
}
AppHeader,
Preview
}
})
</script>
16 changes: 10 additions & 6 deletions src/admin/app/components/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<template>
<textarea v-model="frontmatter" class="h-24 w-full" />
<textarea v-model="content" class="w-full h-full" />
<textarea
v-model="frontmatter"
class="h-24 w-full font-mono px-4 py-2 d-border-primary border-b outline-none text-sm"
/>
<textarea v-model="content" class="w-full h-full font-mono px-4 py-2 outline-none text-sm" />
</template>

<script lang="ts">
import YAML from 'js-yaml'
import { GrayMatterFile } from 'gray-matter'
import { defineComponent, computed, ref, watch, PropType } from 'vue3'
import { useApi } from '../plugins/api'
Expand Down Expand Up @@ -36,14 +40,14 @@ export default defineComponent({
// Stringified reference for frontmatter text-area
const frontmatter = computed({
get() {
return JSON.stringify(data.value, null, 2)
return YAML.dump(data.value, null, 2)
},
set(value: string) {
try {
data.value = JSON.parse(value)
data.value = YAML.parse(value)
} catch (e) {
// New value is not a valid JSON string.
// Do nothing and wait for the next valid JSON input.
// New value is not a valid YAML string.
// Do nothing and wait for the next valid YAML input.
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion src/admin/app/components/FilesTreeIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>

<span v-else-if="!isRoot || hasOneDir(files)" class="mr-1 inline-block h-4 w-4" />
<span v-else class="mr-1 inline-block h-4 w-4" />

<svg
v-if="isDir(file)"
Expand Down
36 changes: 36 additions & 0 deletions src/admin/app/components/Preview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script setup lang="ts">
import { onBeforeMount, ref, watch } from 'vue3'
import { fetchPreviewOrigin, previewUrl, previewPath } from '../composables/preview'

const iframe = ref<HTMLIFrameElement>()

onBeforeMount(() => fetchPreviewOrigin())

watch(
[previewUrl, iframe],
() => {
if (!iframe.value) return
try {
iframe.value.contentWindow.$nuxt.$router.push(previewPath.value)
} catch (e) {
// fallback to hard refresh when working with cross-origin
iframe.value.src = previewUrl.value
}
},
{ flush: 'post' }
)

function refresh() {
iframe.value.src += ''
}
</script>

<template>
<div class="h-full flex-1 grid grid-rows-[min-content,1fr]">
<div class="p-2 flex d-border-primary border-b">
<div class="flex-auto my-auto px-2">{{ previewUrl }}</div>
<button class="border d-border-primary rounded px-2 py-1" @click="refresh">Refresh</button>
</div>
<iframe ref="iframe" :src="previewOrigin" class="w-full h-full" />
</div>
</template>
1 change: 1 addition & 0 deletions src/admin/app/composables/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './preview'
21 changes: 21 additions & 0 deletions src/admin/app/composables/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ref, computed } from 'vue3'
import { useApi } from '../plugins/api'

export const previewOrigin = ref('http://localhost:4000')
export const previewPath = ref('/')
export const previewUrl = computed(() => previewOrigin.value + previewPath.value)

const api = useApi()

export async function fetchPreviewOrigin() {
const { url } = (await api.get('/preview')) as any

previewOrigin.value = url
}

export function navigateToFile(filepath: string) {
previewPath.value = filepath
.replace(/\/\d+\./g, '/')
.replace(/\.md$/, '')
.replace(/\/index$/, '/')
}
6 changes: 5 additions & 1 deletion src/admin/app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { reactive, defineComponent, onMounted, toRefs } from 'vue3'
import FilesTree from '../components/FilesTree.vue'
import Editor from '../components/Editor.vue'
import { useApi } from '../plugins/api'
import { navigateToFile } from '../composables/preview'

export default defineComponent({
components: {
Expand All @@ -30,7 +31,10 @@ export default defineComponent({
currentFile: null
})

const openFile = async file => (state.currentFile = await api.get(`/pages${file.path}`))
const openFile = async file => {
navigateToFile(file.path)
state.currentFile = await api.get(`/pages${file.path}`)
}

onMounted(async () => (state.files = await api.get('/pages')))

Expand Down
45 changes: 15 additions & 30 deletions src/admin/app/pages/static.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,27 @@
</div>
</template>

<script>
<script setup lang="ts">
import { onMounted, ref } from 'vue3'
import FilesTree from '../components/FilesTree.vue'
import Editor from '../components/Editor.vue'
import { useApi } from '../plugins/api'
import { isImage } from '../utils'
import { previewUrl } from '../composables/preview'

export default {
components: {
FilesTree,
Editor
},
const api = useApi()
const files = ref([])
const currentFile = ref(null)

inject: ['previewUrl'],
onMounted(async () => {
files.value = await api.get('/static')
})

setup() {
return { isImage }
},

data() {
return {
files: [],
currentFile: null
}
},

async mounted() {
this.files = await this.$api.get('/static')
},

methods: {
async openFile(file) {
if (this.isImage(file)) {
this.currentFile = file
} else {
this.currentFile = await this.$api.get(`/static${file.path}`)
}
}
async function openFile(file) {
if (isImage(file)) {
currentFile.value = file
} else {
currentFile.value = await api.get(`/static${file.path}`)
}
}
</script>