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