diff options
Diffstat (limited to 'packages/frontend/src/components/page')
17 files changed, 935 insertions, 0 deletions
diff --git a/packages/frontend/src/components/page/page.block.vue b/packages/frontend/src/components/page/page.block.vue new file mode 100644 index 0000000000..f3e7764604 --- /dev/null +++ b/packages/frontend/src/components/page/page.block.vue @@ -0,0 +1,44 @@ +<template> +<component :is="'x-' + block.type" :key="block.id" :block="block" :hpml="hpml" :h="h"/> +</template> + +<script lang="ts"> +import { defineComponent, PropType } from 'vue'; +import XText from './page.text.vue'; +import XSection from './page.section.vue'; +import XImage from './page.image.vue'; +import XButton from './page.button.vue'; +import XNumberInput from './page.number-input.vue'; +import XTextInput from './page.text-input.vue'; +import XTextareaInput from './page.textarea-input.vue'; +import XSwitch from './page.switch.vue'; +import XIf from './page.if.vue'; +import XTextarea from './page.textarea.vue'; +import XPost from './page.post.vue'; +import XCounter from './page.counter.vue'; +import XRadioButton from './page.radio-button.vue'; +import XCanvas from './page.canvas.vue'; +import XNote from './page.note.vue'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { Block } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf, XCounter, XRadioButton, XCanvas, XNote, + }, + props: { + block: { + type: Object as PropType<Block>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + h: { + type: Number, + required: true, + }, + }, +}); +</script> diff --git a/packages/frontend/src/components/page/page.button.vue b/packages/frontend/src/components/page/page.button.vue new file mode 100644 index 0000000000..83931021d8 --- /dev/null +++ b/packages/frontend/src/components/page/page.button.vue @@ -0,0 +1,66 @@ +<template> +<div> + <MkButton class="kudkigyw" :primary="block.primary" @click="click()">{{ hpml.interpolate(block.text) }}</MkButton> +</div> +</template> + +<script lang="ts"> +import { defineComponent, PropType, unref } from 'vue'; +import MkButton from '../MkButton.vue'; +import * as os from '@/os'; +import { ButtonBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +export default defineComponent({ + components: { + MkButton, + }, + props: { + block: { + type: Object as PropType<ButtonBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + methods: { + click() { + if (this.block.action === 'dialog') { + this.hpml.eval(); + os.alert({ + text: this.hpml.interpolate(this.block.content), + }); + } else if (this.block.action === 'resetRandom') { + this.hpml.updateRandomSeed(Math.random()); + this.hpml.eval(); + } else if (this.block.action === 'pushEvent') { + os.api('page-push', { + pageId: this.hpml.page.id, + event: this.block.event, + ...(this.block.var ? { + var: unref(this.hpml.vars)[this.block.var], + } : {}), + }); + + os.alert({ + type: 'success', + text: this.hpml.interpolate(this.block.message), + }); + } else if (this.block.action === 'callAiScript') { + this.hpml.callAiScript(this.block.fn); + } + }, + }, +}); +</script> + +<style lang="scss" scoped> +.kudkigyw { + display: inline-block; + min-width: 200px; + max-width: 450px; + margin: 8px 0; +} +</style> diff --git a/packages/frontend/src/components/page/page.canvas.vue b/packages/frontend/src/components/page/page.canvas.vue new file mode 100644 index 0000000000..80f6c8339c --- /dev/null +++ b/packages/frontend/src/components/page/page.canvas.vue @@ -0,0 +1,49 @@ +<template> +<div class="ysrxegms"> + <canvas ref="canvas" :width="block.width" :height="block.height"/> +</div> +</template> + +<script lang="ts"> +import { defineComponent, onMounted, PropType, Ref, ref } from 'vue'; +import * as os from '@/os'; +import { CanvasBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +export default defineComponent({ + props: { + block: { + type: Object as PropType<CanvasBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const canvas: Ref<any> = ref(null); + + onMounted(() => { + props.hpml.registerCanvas(props.block.name, canvas.value); + }); + + return { + canvas, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.ysrxegms { + display: inline-block; + vertical-align: bottom; + overflow: auto; + max-width: 100%; + + > canvas { + display: block; + } +} +</style> diff --git a/packages/frontend/src/components/page/page.counter.vue b/packages/frontend/src/components/page/page.counter.vue new file mode 100644 index 0000000000..a9e1f41a54 --- /dev/null +++ b/packages/frontend/src/components/page/page.counter.vue @@ -0,0 +1,52 @@ +<template> +<div> + <MkButton class="llumlmnx" @click="click()">{{ hpml.interpolate(block.text) }}</MkButton> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkButton from '../MkButton.vue'; +import * as os from '@/os'; +import { CounterVarBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +export default defineComponent({ + components: { + MkButton, + }, + props: { + block: { + type: Object as PropType<CounterVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function click() { + props.hpml.updatePageVar(props.block.name, value.value + (props.block.inc || 1)); + props.hpml.eval(); + } + + return { + click, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.llumlmnx { + display: inline-block; + min-width: 300px; + max-width: 450px; + margin: 8px 0; +} +</style> diff --git a/packages/frontend/src/components/page/page.if.vue b/packages/frontend/src/components/page/page.if.vue new file mode 100644 index 0000000000..372a15f0c6 --- /dev/null +++ b/packages/frontend/src/components/page/page.if.vue @@ -0,0 +1,31 @@ +<template> +<div v-show="hpml.vars.value[block.var]"> + <XBlock v-for="child in block.children" :key="child.id" :block="child" :hpml="hpml" :h="h"/> +</div> +</template> + +<script lang="ts"> +import { IfBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { defineComponent, defineAsyncComponent, PropType } from 'vue'; + +export default defineComponent({ + components: { + XBlock: defineAsyncComponent(() => import('./page.block.vue')), + }, + props: { + block: { + type: Object as PropType<IfBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + h: { + type: Number, + required: true, + }, + }, +}); +</script> diff --git a/packages/frontend/src/components/page/page.image.vue b/packages/frontend/src/components/page/page.image.vue new file mode 100644 index 0000000000..8ba70c5855 --- /dev/null +++ b/packages/frontend/src/components/page/page.image.vue @@ -0,0 +1,28 @@ +<template> +<div class="lzyxtsnt"> + <ImgWithBlurhash v-if="image" :hash="image.blurhash" :src="image.url" :alt="image.comment" :title="image.comment" :cover="false"/> +</div> +</template> + +<script lang="ts" setup> +import { defineComponent, PropType } from 'vue'; +import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue'; +import * as os from '@/os'; +import { ImageBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +const props = defineProps<{ + block: PropType<ImageBlock>, + hpml: PropType<Hpml>, +}>(); + +const image = props.hpml.page.attachedFiles.find(x => x.id === props.block.fileId); +</script> + +<style lang="scss" scoped> +.lzyxtsnt { + > img { + max-width: 100%; + } +} +</style> diff --git a/packages/frontend/src/components/page/page.note.vue b/packages/frontend/src/components/page/page.note.vue new file mode 100644 index 0000000000..7d5c484a1b --- /dev/null +++ b/packages/frontend/src/components/page/page.note.vue @@ -0,0 +1,47 @@ +<template> +<div class="voxdxuby"> + <XNote v-if="note && !block.detailed" :key="note.id + ':normal'" v-model:note="note"/> + <XNoteDetailed v-if="note && block.detailed" :key="note.id + ':detail'" v-model:note="note"/> +</div> +</template> + +<script lang="ts"> +import { defineComponent, onMounted, PropType, Ref, ref } from 'vue'; +import XNote from '@/components/MkNote.vue'; +import XNoteDetailed from '@/components/MkNoteDetailed.vue'; +import * as os from '@/os'; +import { NoteBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + XNote, + XNoteDetailed, + }, + props: { + block: { + type: Object as PropType<NoteBlock>, + required: true, + }, + }, + setup(props, ctx) { + const note: Ref<Record<string, any> | null> = ref(null); + + onMounted(() => { + os.api('notes/show', { noteId: props.block.note }) + .then(result => { + note.value = result; + }); + }); + + return { + note, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.voxdxuby { + margin: 1em 0; +} +</style> diff --git a/packages/frontend/src/components/page/page.number-input.vue b/packages/frontend/src/components/page/page.number-input.vue new file mode 100644 index 0000000000..50cf6d0770 --- /dev/null +++ b/packages/frontend/src/components/page/page.number-input.vue @@ -0,0 +1,55 @@ +<template> +<div> + <MkInput class="kudkigyw" :model-value="value" type="number" @update:model-value="updateValue($event)"> + <template #label>{{ hpml.interpolate(block.text) }}</template> + </MkInput> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkInput from '../form/input.vue'; +import * as os from '@/os'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { NumberInputVarBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + MkInput, + }, + props: { + block: { + type: Object as PropType<NumberInputVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function updateValue(newValue) { + props.hpml.updatePageVar(props.block.name, newValue); + props.hpml.eval(); + } + + return { + value, + updateValue, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.kudkigyw { + display: inline-block; + min-width: 300px; + max-width: 450px; + margin: 8px 0; +} +</style> diff --git a/packages/frontend/src/components/page/page.post.vue b/packages/frontend/src/components/page/page.post.vue new file mode 100644 index 0000000000..0ef50d65cd --- /dev/null +++ b/packages/frontend/src/components/page/page.post.vue @@ -0,0 +1,109 @@ +<template> +<div class="ngbfujlo"> + <MkTextarea :model-value="text" readonly style="margin: 0;"></MkTextarea> + <MkButton class="button" primary :disabled="posting || posted" @click="post()"> + <i v-if="posted" class="ti ti-check"></i> + <i v-else class="ti ti-send"></i> + </MkButton> +</div> +</template> + +<script lang="ts"> +import { defineComponent, PropType } from 'vue'; +import MkTextarea from '../form/textarea.vue'; +import MkButton from '../MkButton.vue'; +import { apiUrl } from '@/config'; +import * as os from '@/os'; +import { PostBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +export default defineComponent({ + components: { + MkTextarea, + MkButton, + }, + props: { + block: { + type: Object as PropType<PostBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + data() { + return { + text: this.hpml.interpolate(this.block.text), + posted: false, + posting: false, + }; + }, + watch: { + 'hpml.vars': { + handler() { + this.text = this.hpml.interpolate(this.block.text); + }, + deep: true, + }, + }, + methods: { + upload() { + const promise = new Promise((ok) => { + const canvas = this.hpml.canvases[this.block.canvasId]; + canvas.toBlob(blob => { + const formData = new FormData(); + formData.append('file', blob); + formData.append('i', this.$i.token); + if (this.$store.state.uploadFolder) { + formData.append('folderId', this.$store.state.uploadFolder); + } + + window.fetch(apiUrl + '/drive/files/create', { + method: 'POST', + body: formData, + }) + .then(response => response.json()) + .then(f => { + ok(f); + }); + }); + }); + os.promiseDialog(promise); + return promise; + }, + async post() { + this.posting = true; + const file = this.block.attachCanvasImage ? await this.upload() : null; + os.apiWithDialog('notes/create', { + text: this.text === '' ? null : this.text, + fileIds: file ? [file.id] : undefined, + }).then(() => { + this.posted = true; + }); + }, + }, +}); +</script> + +<style lang="scss" scoped> +.ngbfujlo { + position: relative; + padding: 32px; + border-radius: 6px; + box-shadow: 0 2px 8px var(--shadow); + z-index: 1; + + > .button { + margin-top: 32px; + } + + @media (max-width: 600px) { + padding: 16px; + + > .button { + margin-top: 16px; + } + } +} +</style> diff --git a/packages/frontend/src/components/page/page.radio-button.vue b/packages/frontend/src/components/page/page.radio-button.vue new file mode 100644 index 0000000000..b4d9e01a54 --- /dev/null +++ b/packages/frontend/src/components/page/page.radio-button.vue @@ -0,0 +1,45 @@ +<template> +<div> + <div>{{ hpml.interpolate(block.title) }}</div> + <MkRadio v-for="item in block.values" :key="item" :modelValue="value" :value="item" @update:model-value="updateValue($event)">{{ item }}</MkRadio> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkRadio from '../form/radio.vue'; +import * as os from '@/os'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { RadioButtonVarBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + MkRadio, + }, + props: { + block: { + type: Object as PropType<RadioButtonVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function updateValue(newValue: string) { + props.hpml.updatePageVar(props.block.name, newValue); + props.hpml.eval(); + } + + return { + value, + updateValue, + }; + }, +}); +</script> diff --git a/packages/frontend/src/components/page/page.section.vue b/packages/frontend/src/components/page/page.section.vue new file mode 100644 index 0000000000..630c1f5179 --- /dev/null +++ b/packages/frontend/src/components/page/page.section.vue @@ -0,0 +1,60 @@ +<template> +<section class="sdgxphyu"> + <component :is="'h' + h">{{ block.title }}</component> + + <div class="children"> + <XBlock v-for="child in block.children" :key="child.id" :block="child" :hpml="hpml" :h="h + 1"/> + </div> +</section> +</template> + +<script lang="ts"> +import { defineComponent, defineAsyncComponent, PropType } from 'vue'; +import * as os from '@/os'; +import { SectionBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; + +export default defineComponent({ + components: { + XBlock: defineAsyncComponent(() => import('./page.block.vue')), + }, + props: { + block: { + type: Object as PropType<SectionBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + h: { + required: true, + }, + }, +}); +</script> + +<style lang="scss" scoped> +.sdgxphyu { + margin: 1.5em 0; + + > h2 { + font-size: 1.35em; + margin: 0 0 0.5em 0; + } + + > h3 { + font-size: 1em; + margin: 0 0 0.5em 0; + } + + > h4 { + font-size: 1em; + margin: 0 0 0.5em 0; + } + + > .children { + //padding 16px + } +} +</style> diff --git a/packages/frontend/src/components/page/page.switch.vue b/packages/frontend/src/components/page/page.switch.vue new file mode 100644 index 0000000000..64dc4ff8aa --- /dev/null +++ b/packages/frontend/src/components/page/page.switch.vue @@ -0,0 +1,55 @@ +<template> +<div class="hkcxmtwj"> + <MkSwitch :model-value="value" @update:model-value="updateValue($event)">{{ hpml.interpolate(block.text) }}</MkSwitch> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkSwitch from '../form/switch.vue'; +import * as os from '@/os'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { SwitchVarBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + MkSwitch, + }, + props: { + block: { + type: Object as PropType<SwitchVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function updateValue(newValue: boolean) { + props.hpml.updatePageVar(props.block.name, newValue); + props.hpml.eval(); + } + + return { + value, + updateValue, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.hkcxmtwj { + display: inline-block; + margin: 16px auto; + + & + .hkcxmtwj { + margin-left: 16px; + } +} +</style> diff --git a/packages/frontend/src/components/page/page.text-input.vue b/packages/frontend/src/components/page/page.text-input.vue new file mode 100644 index 0000000000..840649ece6 --- /dev/null +++ b/packages/frontend/src/components/page/page.text-input.vue @@ -0,0 +1,55 @@ +<template> +<div> + <MkInput class="kudkigyw" :model-value="value" type="text" @update:model-value="updateValue($event)"> + <template #label>{{ hpml.interpolate(block.text) }}</template> + </MkInput> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkInput from '../form/input.vue'; +import * as os from '@/os'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { TextInputVarBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + MkInput, + }, + props: { + block: { + type: Object as PropType<TextInputVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function updateValue(newValue) { + props.hpml.updatePageVar(props.block.name, newValue); + props.hpml.eval(); + } + + return { + value, + updateValue, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.kudkigyw { + display: inline-block; + min-width: 300px; + max-width: 450px; + margin: 8px 0; +} +</style> diff --git a/packages/frontend/src/components/page/page.text.vue b/packages/frontend/src/components/page/page.text.vue new file mode 100644 index 0000000000..689c484521 --- /dev/null +++ b/packages/frontend/src/components/page/page.text.vue @@ -0,0 +1,68 @@ +<template> +<div class="mrdgzndn"> + <Mfm :key="text" :text="text" :is-note="false" :i="$i"/> + <MkUrlPreview v-for="url in urls" :key="url" :url="url" class="url"/> +</div> +</template> + +<script lang="ts"> +import { TextBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { defineAsyncComponent, defineComponent, PropType } from 'vue'; +import * as mfm from 'mfm-js'; +import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm'; + +export default defineComponent({ + components: { + MkUrlPreview: defineAsyncComponent(() => import('@/components/MkUrlPreview.vue')), + }, + props: { + block: { + type: Object as PropType<TextBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + data() { + return { + text: this.hpml.interpolate(this.block.text), + }; + }, + computed: { + urls(): string[] { + if (this.text) { + return extractUrlFromMfm(mfm.parse(this.text)); + } else { + return []; + } + }, + }, + watch: { + 'hpml.vars': { + handler() { + this.text = this.hpml.interpolate(this.block.text); + }, + deep: true, + }, + }, +}); +</script> + +<style lang="scss" scoped> +.mrdgzndn { + &:not(:first-child) { + margin-top: 0.5em; + } + + &:not(:last-child) { + margin-bottom: 0.5em; + } + + > .url { + margin: 0.5em 0; + } +} +</style> diff --git a/packages/frontend/src/components/page/page.textarea-input.vue b/packages/frontend/src/components/page/page.textarea-input.vue new file mode 100644 index 0000000000..507e1bd97b --- /dev/null +++ b/packages/frontend/src/components/page/page.textarea-input.vue @@ -0,0 +1,47 @@ +<template> +<div> + <MkTextarea :model-value="value" @update:model-value="updateValue($event)"> + <template #label>{{ hpml.interpolate(block.text) }}</template> + </MkTextarea> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, PropType } from 'vue'; +import MkTextarea from '../form/textarea.vue'; +import * as os from '@/os'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { HpmlTextInput } from '@/scripts/hpml'; +import { TextInputVarBlock } from '@/scripts/hpml/block'; + +export default defineComponent({ + components: { + MkTextarea, + }, + props: { + block: { + type: Object as PropType<TextInputVarBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + setup(props, ctx) { + const value = computed(() => { + return props.hpml.vars.value[props.block.name]; + }); + + function updateValue(newValue) { + props.hpml.updatePageVar(props.block.name, newValue); + props.hpml.eval(); + } + + return { + value, + updateValue, + }; + }, +}); +</script> diff --git a/packages/frontend/src/components/page/page.textarea.vue b/packages/frontend/src/components/page/page.textarea.vue new file mode 100644 index 0000000000..f809925081 --- /dev/null +++ b/packages/frontend/src/components/page/page.textarea.vue @@ -0,0 +1,39 @@ +<template> +<MkTextarea :model-value="text" readonly></MkTextarea> +</template> + +<script lang="ts"> +import { TextBlock } from '@/scripts/hpml/block'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { defineComponent, PropType } from 'vue'; +import MkTextarea from '../form/textarea.vue'; + +export default defineComponent({ + components: { + MkTextarea, + }, + props: { + block: { + type: Object as PropType<TextBlock>, + required: true, + }, + hpml: { + type: Object as PropType<Hpml>, + required: true, + }, + }, + data() { + return { + text: this.hpml.interpolate(this.block.text), + }; + }, + watch: { + 'hpml.vars': { + handler() { + this.text = this.hpml.interpolate(this.block.text); + }, + deep: true, + }, + }, +}); +</script> diff --git a/packages/frontend/src/components/page/page.vue b/packages/frontend/src/components/page/page.vue new file mode 100644 index 0000000000..b5cb73c009 --- /dev/null +++ b/packages/frontend/src/components/page/page.vue @@ -0,0 +1,85 @@ +<template> +<div v-if="hpml" class="iroscrza" :class="{ center: page.alignCenter, serif: page.font === 'serif' }"> + <XBlock v-for="child in page.content" :key="child.id" :block="child" :hpml="hpml" :h="2"/> +</div> +</template> + +<script lang="ts"> +import { defineComponent, onMounted, nextTick, onUnmounted, PropType } from 'vue'; +import { parse } from '@syuilo/aiscript'; +import XBlock from './page.block.vue'; +import { Hpml } from '@/scripts/hpml/evaluator'; +import { url } from '@/config'; +import { $i } from '@/account'; +import { defaultStore } from '@/store'; + +export default defineComponent({ + components: { + XBlock, + }, + props: { + page: { + type: Object as PropType<Record<string, any>>, + required: true, + }, + }, + setup(props, ctx) { + const hpml = new Hpml(props.page, { + randomSeed: Math.random(), + visitor: $i, + url: url, + enableAiScript: !defaultStore.state.disablePagesScript, + }); + + onMounted(() => { + nextTick(() => { + if (props.page.script && hpml.aiscript) { + let ast; + try { + ast = parse(props.page.script); + } catch (err) { + console.error(err); + /*os.alert({ + type: 'error', + text: 'Syntax error :(' + });*/ + return; + } + hpml.aiscript.exec(ast).then(() => { + hpml.eval(); + }).catch(err => { + console.error(err); + /*os.alert({ + type: 'error', + text: err + });*/ + }); + } else { + hpml.eval(); + } + }); + onUnmounted(() => { + if (hpml.aiscript) hpml.aiscript.abort(); + }); + }); + + return { + hpml, + }; + }, +}); +</script> + +<style lang="scss" scoped> +.iroscrza { + &.serif { + > div { + font-family: serif; + } + } + + &.center { + text-align: center; + } +} +</style> |