mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-09 19:43:09 +02:00
parent
cac99ebdd4
commit
f655b54937
7 changed files with 159 additions and 49 deletions
|
@ -1104,6 +1104,7 @@ _pages:
|
|||
created: "ページを作成しました"
|
||||
updated: "ページを更新しました"
|
||||
deleted: "ページを削除しました"
|
||||
pageSetting: "ページ設定"
|
||||
nameAlreadyExists: "指定されたページURLは既に存在しています"
|
||||
invalidNameTitle: "不正なページURLです"
|
||||
invalidNameText: "空白でないか確認してください"
|
||||
|
@ -1115,6 +1116,7 @@ _pages:
|
|||
my: "自分のページ"
|
||||
liked: "いいねしたページ"
|
||||
inspector: "インスペクター"
|
||||
contents: "コンテンツ"
|
||||
content: "ページブロック"
|
||||
variables: "変数"
|
||||
title: "タイトル"
|
||||
|
@ -1175,6 +1177,11 @@ _pages:
|
|||
width: "幅"
|
||||
height: "高さ"
|
||||
|
||||
note: "ノート埋め込み"
|
||||
_note:
|
||||
id: "ノートID"
|
||||
idDescription: "ノートURLをペーストして設定することもできます。"
|
||||
|
||||
switch: "スイッチ"
|
||||
_switch:
|
||||
name: "変数名"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<MkA :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1">
|
||||
<MkA :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj _panel" tabindex="-1">
|
||||
<div class="thumbnail" v-if="page.eyeCatchingImage" :style="`background-image: url('${page.eyeCatchingImage.thumbnailUrl}')`"></div>
|
||||
<article>
|
||||
<header>
|
||||
|
@ -35,16 +35,11 @@ export default defineComponent({
|
|||
<style lang="scss" scoped>
|
||||
.vhpxefrj {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
border: solid var(--lineWidth) var(--urlPreviewBorder);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--divider);
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
border-color: var(--urlPreviewBorderHover);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
> .thumbnail {
|
||||
|
|
|
@ -18,10 +18,11 @@ 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';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf, XCounter, XRadioButton, XCanvas
|
||||
XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf, XCounter, XRadioButton, XCanvas, XNote
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
|
|
39
src/client/components/page/page.note.vue
Normal file
39
src/client/components/page/page.note.vue
Normal file
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div class="voxdxuby">
|
||||
<XNote v-if="note" v-model:note="note" :key="note.id"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNote from '@/components/note.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNote
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
hpml: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
note: null,
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.note = await os.api('notes/show', { noteId: this.value.note });
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.voxdxuby {
|
||||
margin: 1em 0;
|
||||
}
|
||||
</style>
|
62
src/client/pages/page-editor/els/page-editor.el.note.vue
Normal file
62
src/client/pages/page-editor/els/page-editor.el.note.vue
Normal file
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<XContainer @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><Fa :icon="faStickyNote"/> {{ $t('_pages.blocks.note') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 0 16px;">
|
||||
<MkInput v-model:value="id">
|
||||
<span>{{ $t('_pages.blocks._note.id') }}</span>
|
||||
<template #desc>{{ $t('_pages.blocks._note.idDescription') }}</template>
|
||||
</MkInput>
|
||||
|
||||
<XNote v-if="note" v-model:note="note" :key="note.id" style="margin-bottom: 16px;"/>
|
||||
</section>
|
||||
</XContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { faStickyNote } from '@fortawesome/free-solid-svg-icons';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
import MkInput from '@/components/ui/input.vue';
|
||||
import XNote from '@/components/note.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XContainer, MkInput, XNote
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
id: this.value.note,
|
||||
note: null,
|
||||
faStickyNote
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
id: {
|
||||
async handler() {
|
||||
if (this.id && (this.id.startsWith('http://') || this.id.startsWith('https://'))) {
|
||||
this.value.note = this.id.endsWith('/') ? this.id.substr(0, this.id.length - 1).split('/').pop() : this.id.split('/').pop();
|
||||
} else {
|
||||
this.value.note = this.id;
|
||||
}
|
||||
|
||||
this.note = await os.api('notes/show', { noteId: this.value.note });
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.note == null) this.value.note = null;
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -20,12 +20,13 @@ import XPost from './els/page-editor.el.post.vue';
|
|||
import XCounter from './els/page-editor.el.counter.vue';
|
||||
import XRadioButton from './els/page-editor.el.radio-button.vue';
|
||||
import XCanvas from './els/page-editor.el.canvas.vue';
|
||||
import XNote from './els/page-editor.el.note.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XDraggable: defineAsyncComponent(() => import('vue-draggable-next').then(x => x.VueDraggableNext)),
|
||||
XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter, XRadioButton, XCanvas
|
||||
XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter, XRadioButton, XCanvas, XNote
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
|
@ -1,57 +1,54 @@
|
|||
<template>
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<div class="gwbmwxkm _panel _vMargin">
|
||||
<header>
|
||||
<div class="title"><Fa :icon="faStickyNote"/> {{ readonly ? $t('_pages.readPage') : pageId ? $t('_pages.editPage') : $t('_pages.newPage') }}</div>
|
||||
<div class="buttons">
|
||||
<button class="_button" @click="del()" v-if="!readonly"><Fa :icon="faTrashAlt"/></button>
|
||||
<button class="_button" @click="() => showOptions = !showOptions"><Fa :icon="faCog"/></button>
|
||||
<button class="_button" @click="save()" v-if="!readonly"><Fa :icon="faSave"/></button>
|
||||
</div>
|
||||
</header>
|
||||
<MkA class="view" v-if="pageId" :to="`/@${ author.username }/pages/${ currentName }`"><Fa :icon="faExternalLinkSquareAlt"/> {{ $t('_pages.viewPage') }}</MkA>
|
||||
|
||||
<section>
|
||||
<MkA class="view" v-if="pageId" :to="`/@${ author.username }/pages/${ currentName }`"><Fa :icon="faExternalLinkSquareAlt"/> {{ $t('_pages.viewPage') }}</MkA>
|
||||
<MkButton @click="save" primary class="save" style="margin: 16px auto 16px auto;"><Fa :icon="faSave"/> {{ $t('save') }}</MkButton>
|
||||
|
||||
<MkContainer :body-togglable="true" :expanded="true" class="_vMargin">
|
||||
<template #header><Fa :icon="faCog"/> {{ $t('_pages.pageSetting') }}</template>
|
||||
<div class="_section">
|
||||
<MkInput v-model:value="title">
|
||||
<span>{{ $t('_pages.title') }}</span>
|
||||
</MkInput>
|
||||
|
||||
<template v-if="showOptions">
|
||||
<MkInput v-model:value="summary">
|
||||
<span>{{ $t('_pages.summary') }}</span>
|
||||
</MkInput>
|
||||
<MkInput v-model:value="summary">
|
||||
<span>{{ $t('_pages.summary') }}</span>
|
||||
</MkInput>
|
||||
|
||||
<MkInput v-model:value="name">
|
||||
<template #prefix>{{ url }}/@{{ author.username }}/pages/</template>
|
||||
<span>{{ $t('_pages.url') }}</span>
|
||||
</MkInput>
|
||||
<MkInput v-model:value="name">
|
||||
<template #prefix>{{ url }}/@{{ author.username }}/pages/</template>
|
||||
<span>{{ $t('_pages.url') }}</span>
|
||||
</MkInput>
|
||||
|
||||
<MkSwitch v-model:value="alignCenter">{{ $t('_pages.alignCenter') }}</MkSwitch>
|
||||
<MkSwitch v-model:value="alignCenter">{{ $t('_pages.alignCenter') }}</MkSwitch>
|
||||
|
||||
<MkSelect v-model:value="font">
|
||||
<template #label>{{ $t('_pages.font') }}</template>
|
||||
<option value="serif">{{ $t('_pages.fontSerif') }}</option>
|
||||
<option value="sans-serif">{{ $t('_pages.fontSansSerif') }}</option>
|
||||
</MkSelect>
|
||||
<MkSelect v-model:value="font">
|
||||
<template #label>{{ $t('_pages.font') }}</template>
|
||||
<option value="serif">{{ $t('_pages.fontSerif') }}</option>
|
||||
<option value="sans-serif">{{ $t('_pages.fontSansSerif') }}</option>
|
||||
</MkSelect>
|
||||
|
||||
<MkSwitch v-model:value="hideTitleWhenPinned">{{ $t('_pages.hideTitleWhenPinned') }}</MkSwitch>
|
||||
<MkSwitch v-model:value="hideTitleWhenPinned">{{ $t('_pages.hideTitleWhenPinned') }}</MkSwitch>
|
||||
|
||||
<div class="eyeCatch">
|
||||
<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage()"><Fa :icon="faPlus"/> {{ $t('_pages.eyeCatchingImageSet') }}</MkButton>
|
||||
<div v-else-if="eyeCatchingImage">
|
||||
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name"/>
|
||||
<MkButton @click="removeEyeCatchingImage()" v-if="!readonly"><Fa :icon="faTrashAlt"/> {{ $t('_pages.eyeCatchingImageRemove') }}</MkButton>
|
||||
</div>
|
||||
<div class="eyeCatch">
|
||||
<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><Fa :icon="faPlus"/> {{ $t('_pages.eyeCatchingImageSet') }}</MkButton>
|
||||
<div v-else-if="eyeCatchingImage">
|
||||
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name" style="max-width: 100%;"/>
|
||||
<MkButton @click="removeEyeCatchingImage()" v-if="!readonly"><Fa :icon="faTrashAlt"/> {{ $t('_pages.eyeCatchingImageRemove') }}</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</MkContainer>
|
||||
|
||||
<MkContainer :body-togglable="true" :expanded="true" class="_vMargin">
|
||||
<template #header><Fa :icon="faStickyNote"/> {{ $t('_pages.contents') }}</template>
|
||||
<div class="_section">
|
||||
<XBlocks class="content" v-model:value="content" :hpml="hpml"/>
|
||||
|
||||
<MkButton @click="add()" v-if="!readonly"><Fa :icon="faPlus"/></MkButton>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</MkContainer>
|
||||
|
||||
<MkContainer :body-togglable="true" class="_vMargin">
|
||||
<template #header><Fa :icon="faMagic"/> {{ $t('_pages.variables') }}</template>
|
||||
|
@ -85,14 +82,14 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, defineAsyncComponent } from 'vue';
|
||||
import { defineComponent, defineAsyncComponent, computed } from 'vue';
|
||||
import 'prismjs';
|
||||
import { highlight, languages } from 'prismjs/components/prism-core';
|
||||
import 'prismjs/components/prism-clike';
|
||||
import 'prismjs/components/prism-javascript';
|
||||
import 'prismjs/themes/prism-okaidia.css';
|
||||
import 'vue-prism-editor/dist/prismeditor.min.css';
|
||||
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import XVariable from './page-editor.script-block.vue';
|
||||
|
@ -108,6 +105,7 @@ import { HpmlTypeChecker } from '@/scripts/hpml/type-checker';
|
|||
import { url } from '@/config';
|
||||
import { collectPageVars } from '@/scripts/collect-page-vars';
|
||||
import * as os from '@/os';
|
||||
import { selectFile } from '@/scripts/select-file';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
@ -132,6 +130,13 @@ export default defineComponent({
|
|||
|
||||
data() {
|
||||
return {
|
||||
INFO: computed(() => this.initPageId ? {
|
||||
title: this.$t('_pages.editPage'),
|
||||
icon: faPencilAlt,
|
||||
} : {
|
||||
title: this.$t('_pages.newPage'),
|
||||
icon: faPencilAlt,
|
||||
}),
|
||||
author: this.$store.state.i,
|
||||
readonly: false,
|
||||
page: null,
|
||||
|
@ -149,7 +154,6 @@ export default defineComponent({
|
|||
variables: [],
|
||||
hpml: null,
|
||||
script: '',
|
||||
showOptions: false,
|
||||
url,
|
||||
faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode
|
||||
};
|
||||
|
@ -353,6 +357,7 @@ export default defineComponent({
|
|||
{ value: 'text', text: this.$t('_pages.blocks.text') },
|
||||
{ value: 'image', text: this.$t('_pages.blocks.image') },
|
||||
{ value: 'textarea', text: this.$t('_pages.blocks.textarea') },
|
||||
{ value: 'note', text: this.$t('_pages.blocks.note') },
|
||||
{ value: 'canvas', text: this.$t('_pages.blocks.canvas') },
|
||||
]
|
||||
}, {
|
||||
|
@ -413,8 +418,8 @@ export default defineComponent({
|
|||
return list;
|
||||
},
|
||||
|
||||
setEyeCatchingImage() {
|
||||
os.selectDriveFile(false).then(file => {
|
||||
setEyeCatchingImage(e) {
|
||||
selectFile(e.currentTarget || e.target, null, false).then(file => {
|
||||
this.eyeCatchingImageId = file.id;
|
||||
});
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue