chore(client): rendering performance tweak a bit
This commit is contained in:
		
							parent
							
								
									f882e0b6b6
								
							
						
					
					
						commit
						bc73ad2e56
					
				
					 5 changed files with 85 additions and 84 deletions
				
			
		|  | @ -1,15 +1,17 @@ | ||||||
| <template> | <template> | ||||||
|  | <!-- このコンポーネントの要素のclassは親から利用されるのでむやみに弄らないこと --> | ||||||
| <section> | <section> | ||||||
| 	<header class="_acrylic" @click="shown = !shown"> | 	<header class="_acrylic" @click="shown = !shown"> | ||||||
| 		<i class="toggle fa-fw" :class="shown ? 'fas fa-chevron-down' : 'fas fa-chevron-up'"></i> <slot></slot> ({{ emojis.length }}) | 		<i class="toggle fa-fw" :class="shown ? 'fas fa-chevron-down' : 'fas fa-chevron-up'"></i> <slot></slot> ({{ emojis.length }}) | ||||||
| 	</header> | 	</header> | ||||||
| 	<div v-if="shown"> | 	<div v-if="shown" class="body"> | ||||||
| 		<button v-for="emoji in emojis" | 		<button | ||||||
|  | 			v-for="emoji in emojis" | ||||||
| 			:key="emoji" | 			:key="emoji" | ||||||
| 			class="_button" | 			class="_button item" | ||||||
| 			@click="emit('chosen', emoji, $event)" | 			@click="emit('chosen', emoji, $event)" | ||||||
| 		> | 		> | ||||||
| 			<MkEmoji :emoji="emoji" :normal="true"/> | 			<MkEmoji class="emoji" :emoji="emoji" :normal="true"/> | ||||||
| 		</button> | 		</button> | ||||||
| 	</div> | 	</div> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|  | @ -3,63 +3,67 @@ | ||||||
| 	<input ref="search" v-model.trim="q" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" :placeholder="i18n.ts.search" type="search" @paste.stop="paste" @keyup.enter="done()"> | 	<input ref="search" v-model.trim="q" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" :placeholder="i18n.ts.search" type="search" @paste.stop="paste" @keyup.enter="done()"> | ||||||
| 	<div ref="emojis" class="emojis"> | 	<div ref="emojis" class="emojis"> | ||||||
| 		<section class="result"> | 		<section class="result"> | ||||||
| 			<div v-if="searchResultCustom.length > 0"> | 			<div v-if="searchResultCustom.length > 0" class="body"> | ||||||
| 				<button v-for="emoji in searchResultCustom" | 				<button | ||||||
|  | 					v-for="emoji in searchResultCustom" | ||||||
| 					:key="emoji.id" | 					:key="emoji.id" | ||||||
| 					class="_button" | 					class="_button item" | ||||||
| 					:title="emoji.name" | 					:title="emoji.name" | ||||||
| 					tabindex="0" | 					tabindex="0" | ||||||
| 					@click="chosen(emoji, $event)" | 					@click="chosen(emoji, $event)" | ||||||
| 				> | 				> | ||||||
| 					<!--<MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/>--> | 					<!--<MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/>--> | ||||||
| 					<img :src="disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/> | 					<img class="emoji" :src="disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/> | ||||||
| 				</button> | 				</button> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div v-if="searchResultUnicode.length > 0"> | 			<div v-if="searchResultUnicode.length > 0" class="body"> | ||||||
| 				<button v-for="emoji in searchResultUnicode" | 				<button | ||||||
|  | 					v-for="emoji in searchResultUnicode" | ||||||
| 					:key="emoji.name" | 					:key="emoji.name" | ||||||
| 					class="_button" | 					class="_button item" | ||||||
| 					:title="emoji.name" | 					:title="emoji.name" | ||||||
| 					tabindex="0" | 					tabindex="0" | ||||||
| 					@click="chosen(emoji, $event)" | 					@click="chosen(emoji, $event)" | ||||||
| 				> | 				> | ||||||
| 					<MkEmoji :emoji="emoji.char"/> | 					<MkEmoji class="emoji" :emoji="emoji.char"/> | ||||||
| 				</button> | 				</button> | ||||||
| 			</div> | 			</div> | ||||||
| 		</section> | 		</section> | ||||||
| 
 | 
 | ||||||
| 		<div v-if="tab === 'index'" class="index"> | 		<div v-if="tab === 'index'" class="group index"> | ||||||
| 			<section v-if="showPinned"> | 			<section v-if="showPinned"> | ||||||
| 				<div> | 				<div class="body"> | ||||||
| 					<button v-for="emoji in pinned" | 					<button | ||||||
|  | 						v-for="emoji in pinned" | ||||||
| 						:key="emoji" | 						:key="emoji" | ||||||
| 						class="_button" | 						class="_button item" | ||||||
| 						tabindex="0" | 						tabindex="0" | ||||||
| 						@click="chosen(emoji, $event)" | 						@click="chosen(emoji, $event)" | ||||||
| 					> | 					> | ||||||
| 						<MkEmoji :emoji="emoji" :normal="true"/> | 						<MkEmoji class="emoji" :emoji="emoji" :normal="true"/> | ||||||
| 					</button> | 					</button> | ||||||
| 				</div> | 				</div> | ||||||
| 			</section> | 			</section> | ||||||
| 
 | 
 | ||||||
| 			<section> | 			<section> | ||||||
| 				<header class="_acrylic"><i class="far fa-clock fa-fw"></i> {{ i18n.ts.recentUsed }}</header> | 				<header class="_acrylic"><i class="far fa-clock fa-fw"></i> {{ i18n.ts.recentUsed }}</header> | ||||||
| 				<div> | 				<div class="body"> | ||||||
| 					<button v-for="emoji in recentlyUsedEmojis" | 					<button | ||||||
|  | 						v-for="emoji in recentlyUsedEmojis" | ||||||
| 						:key="emoji" | 						:key="emoji" | ||||||
| 						class="_button" | 						class="_button item" | ||||||
| 						@click="chosen(emoji, $event)" | 						@click="chosen(emoji, $event)" | ||||||
| 					> | 					> | ||||||
| 						<MkEmoji :emoji="emoji" :normal="true"/> | 						<MkEmoji class="emoji" :emoji="emoji" :normal="true"/> | ||||||
| 					</button> | 					</button> | ||||||
| 				</div> | 				</div> | ||||||
| 			</section> | 			</section> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div> | 		<div class="group"> | ||||||
| 			<header class="_acrylic">{{ i18n.ts.customEmojis }}</header> | 			<header class="_acrylic">{{ i18n.ts.customEmojis }}</header> | ||||||
| 			<XSection v-for="category in customEmojiCategories" :key="'custom:' + category" :initial-shown="false" :emojis="customEmojis.filter(e => e.category === category).map(e => ':' + e.name + ':')" @chosen="chosen">{{ category || i18n.ts.other }}</XSection> | 			<XSection v-for="category in customEmojiCategories" :key="'custom:' + category" :initial-shown="false" :emojis="customEmojis.filter(e => e.category === category).map(e => ':' + e.name + ':')" @chosen="chosen">{{ category || i18n.ts.other }}</XSection> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div> | 		<div class="group"> | ||||||
| 			<header class="_acrylic">{{ i18n.ts.emoji }}</header> | 			<header class="_acrylic">{{ i18n.ts.emoji }}</header> | ||||||
| 			<XSection v-for="category in categories" :key="category" :emojis="emojilist.filter(e => e.category === category).map(e => e.char)" @chosen="chosen">{{ category }}</XSection> | 			<XSection v-for="category in categories" :key="category" :emojis="emojilist.filter(e => e.category === category).map(e => e.char)" @chosen="chosen">{{ category }}</XSection> | ||||||
| 		</div> | 		</div> | ||||||
|  | @ -76,6 +80,7 @@ | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import { ref, computed, watch, onMounted } from 'vue'; | import { ref, computed, watch, onMounted } from 'vue'; | ||||||
| import * as Misskey from 'misskey-js'; | import * as Misskey from 'misskey-js'; | ||||||
|  | import XSection from './emoji-picker.section.vue'; | ||||||
| import { emojilist, UnicodeEmojiDef, unicodeEmojiCategories as categories } from '@/scripts/emojilist'; | import { emojilist, UnicodeEmojiDef, unicodeEmojiCategories as categories } from '@/scripts/emojilist'; | ||||||
| import { getStaticImageUrl } from '@/scripts/get-static-image-url'; | import { getStaticImageUrl } from '@/scripts/get-static-image-url'; | ||||||
| import Ripple from '@/components/ripple.vue'; | import Ripple from '@/components/ripple.vue'; | ||||||
|  | @ -83,7 +88,6 @@ import * as os from '@/os'; | ||||||
| import { isTouchUsing } from '@/scripts/touch'; | import { isTouchUsing } from '@/scripts/touch'; | ||||||
| import { deviceKind } from '@/scripts/device-kind'; | import { deviceKind } from '@/scripts/device-kind'; | ||||||
| import { emojiCategories, instance } from '@/instance'; | import { emojiCategories, instance } from '@/instance'; | ||||||
| import XSection from './emoji-picker.section.vue'; |  | ||||||
| import { i18n } from '@/i18n'; | import { i18n } from '@/i18n'; | ||||||
| import { defaultStore } from '@/store'; | import { defaultStore } from '@/store'; | ||||||
| 
 | 
 | ||||||
|  | @ -266,7 +270,7 @@ watch(q, () => { | ||||||
| function focus() { | function focus() { | ||||||
| 	if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) { | 	if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) { | ||||||
| 		search.value?.focus({ | 		search.value?.focus({ | ||||||
| 			preventScroll: true | 			preventScroll: true, | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -415,19 +419,16 @@ defineExpose({ | ||||||
| 					font-size: 15px; | 					font-size: 15px; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				> div { | 				> .body { | ||||||
| 					display: grid; | 					display: grid; | ||||||
| 					grid-template-columns: var(--columns); | 					grid-template-columns: var(--columns); | ||||||
|  | 					font-size: 30px; | ||||||
| 
 | 
 | ||||||
| 					> button { | 					> .item { | ||||||
| 						aspect-ratio: 1 / 1; | 						aspect-ratio: 1 / 1; | ||||||
| 						width: auto; | 						width: auto; | ||||||
| 						height: auto; | 						height: auto; | ||||||
| 						min-width: 0; | 						min-width: 0; | ||||||
| 
 |  | ||||||
| 						> * { |  | ||||||
| 							font-size: 30px; |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -478,7 +479,7 @@ defineExpose({ | ||||||
| 			display: none; | 			display: none; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> div { | 		> .group { | ||||||
| 			&:not(.index) { | 			&:not(.index) { | ||||||
| 				padding: 4px 0 8px 0; | 				padding: 4px 0 8px 0; | ||||||
| 				border-top: solid 0.5px var(--divider); | 				border-top: solid 0.5px var(--divider); | ||||||
|  | @ -513,16 +514,18 @@ defineExpose({ | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			> div { | 			> .body { | ||||||
| 				position: relative; | 				position: relative; | ||||||
| 				padding: $pad; | 				padding: $pad; | ||||||
| 
 | 
 | ||||||
| 				> button { | 				> .item { | ||||||
| 					position: relative; | 					position: relative; | ||||||
| 					padding: 0; | 					padding: 0; | ||||||
| 					width: var(--eachSize); | 					width: var(--eachSize); | ||||||
| 					height: var(--eachSize); | 					height: var(--eachSize); | ||||||
|  | 					contain: strict; | ||||||
| 					border-radius: 4px; | 					border-radius: 4px; | ||||||
|  | 					font-size: 24px; | ||||||
| 
 | 
 | ||||||
| 					&:focus-visible { | 					&:focus-visible { | ||||||
| 						outline: solid 2px var(--focus); | 						outline: solid 2px var(--focus); | ||||||
|  | @ -538,8 +541,7 @@ defineExpose({ | ||||||
| 						box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15); | 						box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					> * { | 					> .emoji { | ||||||
| 						font-size: 24px; |  | ||||||
| 						height: 1.25em; | 						height: 1.25em; | ||||||
| 						vertical-align: -.25em; | 						vertical-align: -.25em; | ||||||
| 						pointer-events: none; | 						pointer-events: none; | ||||||
|  |  | ||||||
|  | @ -2,9 +2,9 @@ | ||||||
| <div v-if="hide" class="qjewsnkg" @click="hide = false"> | <div v-if="hide" class="qjewsnkg" @click="hide = false"> | ||||||
| 	<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.comment" :alt="image.comment"/> | 	<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.comment" :alt="image.comment"/> | ||||||
| 	<div class="text"> | 	<div class="text"> | ||||||
| 		<div> | 		<div class="wrapper"> | ||||||
| 			<b><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b> | 			<b style="display: block;"><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b> | ||||||
| 			<span>{{ $ts.clickToShow }}</span> | 			<span style="display: block;">{{ $ts.clickToShow }}</span> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
|  | @ -68,15 +68,11 @@ watch(() => props.image, () => { | ||||||
| 		justify-content: center; | 		justify-content: center; | ||||||
| 		align-items: center; | 		align-items: center; | ||||||
| 
 | 
 | ||||||
| 		> div { | 		> .wrapper { | ||||||
| 			display: table-cell; | 			display: table-cell; | ||||||
| 			text-align: center; | 			text-align: center; | ||||||
| 			font-size: 0.8em; | 			font-size: 0.8em; | ||||||
| 			color: #fff; | 			color: #fff; | ||||||
| 
 |  | ||||||
| 			> * { |  | ||||||
| 				display: block; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| <div v-show="files.length != 0" class="skeikyzd"> | <div v-show="files.length != 0" class="skeikyzd"> | ||||||
| 	<XDraggable v-model="_files" class="files" item-key="id" animation="150" delay="100" delay-on-touch-only="true"> | 	<XDraggable v-model="_files" class="files" item-key="id" animation="150" delay="100" delay-on-touch-only="true"> | ||||||
| 		<template #item="{element}"> | 		<template #item="{element}"> | ||||||
| 			<div @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)"> | 			<div class="file" @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)"> | ||||||
| 				<MkDriveFileThumbnail :data-id="element.id" class="thumbnail" :file="element" fit="cover"/> | 				<MkDriveFileThumbnail :data-id="element.id" class="thumbnail" :file="element" fit="cover"/> | ||||||
| 				<div v-if="element.isSensitive" class="sensitive"> | 				<div v-if="element.isSensitive" class="sensitive"> | ||||||
| 					<i class="fas fa-exclamation-triangle icon"></i> | 					<i class="fas fa-exclamation-triangle icon"></i> | ||||||
|  | @ -22,18 +22,18 @@ import * as os from '@/os'; | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		XDraggable: defineAsyncComponent(() => import('vuedraggable').then(x => x.default)), | 		XDraggable: defineAsyncComponent(() => import('vuedraggable').then(x => x.default)), | ||||||
| 		MkDriveFileThumbnail | 		MkDriveFileThumbnail, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	props: { | 	props: { | ||||||
| 		files: { | 		files: { | ||||||
| 			type: Array, | 			type: Array, | ||||||
| 			required: true | 			required: true, | ||||||
| 		}, | 		}, | ||||||
| 		detachMediaFn: { | 		detachMediaFn: { | ||||||
| 			type: Function, | 			type: Function, | ||||||
| 			required: false | 			required: false, | ||||||
| 		} | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['updated', 'detach', 'changeSensitive', 'changeName'], | 	emits: ['updated', 'detach', 'changeSensitive', 'changeName'], | ||||||
|  | @ -51,8 +51,8 @@ export default defineComponent({ | ||||||
| 			}, | 			}, | ||||||
| 			set(value) { | 			set(value) { | ||||||
| 				this.$emit('updated', value); | 				this.$emit('updated', value); | ||||||
| 			} | 			}, | ||||||
| 		} | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
|  | @ -66,7 +66,7 @@ export default defineComponent({ | ||||||
| 		toggleSensitive(file) { | 		toggleSensitive(file) { | ||||||
| 			os.api('drive/files/update', { | 			os.api('drive/files/update', { | ||||||
| 				fileId: file.id, | 				fileId: file.id, | ||||||
| 				isSensitive: !file.isSensitive | 				isSensitive: !file.isSensitive, | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
| 				this.$emit('changeSensitive', file, !file.isSensitive); | 				this.$emit('changeSensitive', file, !file.isSensitive); | ||||||
| 			}); | 			}); | ||||||
|  | @ -75,12 +75,12 @@ export default defineComponent({ | ||||||
| 			const { canceled, result } = await os.inputText({ | 			const { canceled, result } = await os.inputText({ | ||||||
| 				title: this.$ts.enterFileName, | 				title: this.$ts.enterFileName, | ||||||
| 				default: file.name, | 				default: file.name, | ||||||
| 				allowEmpty: false | 				allowEmpty: false, | ||||||
| 			}); | 			}); | ||||||
| 			if (canceled) return; | 			if (canceled) return; | ||||||
| 			os.api('drive/files/update', { | 			os.api('drive/files/update', { | ||||||
| 				fileId: file.id, | 				fileId: file.id, | ||||||
| 				name: result | 				name: result, | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
| 				this.$emit('changeName', file, result); | 				this.$emit('changeName', file, result); | ||||||
| 				file.name = result; | 				file.name = result; | ||||||
|  | @ -88,13 +88,13 @@ export default defineComponent({ | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		async describe(file) { | 		async describe(file) { | ||||||
| 			os.popup(defineAsyncComponent(() => import("@/components/media-caption.vue")), { | 			os.popup(defineAsyncComponent(() => import('@/components/media-caption.vue')), { | ||||||
| 				title: this.$ts.describeFile, | 				title: this.$ts.describeFile, | ||||||
| 				input: { | 				input: { | ||||||
| 					placeholder: this.$ts.inputNewDescription, | 					placeholder: this.$ts.inputNewDescription, | ||||||
| 					default: file.comment !== null ? file.comment : "", | 					default: file.comment !== null ? file.comment : '', | ||||||
| 				}, | 				}, | ||||||
| 				image: file | 				image: file, | ||||||
| 			}, { | 			}, { | ||||||
| 				done: result => { | 				done: result => { | ||||||
| 					if (!result || result.canceled) return; | 					if (!result || result.canceled) return; | ||||||
|  | @ -105,7 +105,7 @@ export default defineComponent({ | ||||||
| 					}).then(() => { | 					}).then(() => { | ||||||
| 						file.comment = comment; | 						file.comment = comment; | ||||||
| 					}); | 					}); | ||||||
| 				} | 				}, | ||||||
| 			}, 'closed'); | 			}, 'closed'); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | @ -114,22 +114,22 @@ export default defineComponent({ | ||||||
| 			this.menu = os.popupMenu([{ | 			this.menu = os.popupMenu([{ | ||||||
| 				text: this.$ts.renameFile, | 				text: this.$ts.renameFile, | ||||||
| 				icon: 'fas fa-i-cursor', | 				icon: 'fas fa-i-cursor', | ||||||
| 				action: () => { this.rename(file); } | 				action: () => { this.rename(file); }, | ||||||
| 			}, { | 			}, { | ||||||
| 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, | 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, | ||||||
| 				icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', | 				icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', | ||||||
| 				action: () => { this.toggleSensitive(file); } | 				action: () => { this.toggleSensitive(file); }, | ||||||
| 			}, { | 			}, { | ||||||
| 				text: this.$ts.describeFile, | 				text: this.$ts.describeFile, | ||||||
| 				icon: 'fas fa-i-cursor', | 				icon: 'fas fa-i-cursor', | ||||||
| 				action: () => { this.describe(file); } | 				action: () => { this.describe(file); }, | ||||||
| 			}, { | 			}, { | ||||||
| 				text: this.$ts.attachCancel, | 				text: this.$ts.attachCancel, | ||||||
| 				icon: 'fas fa-times-circle', | 				icon: 'fas fa-times-circle', | ||||||
| 				action: () => { this.detachMedia(file.id); } | 				action: () => { this.detachMedia(file.id); }, | ||||||
| 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null); | 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null); | ||||||
| 		} | 		}, | ||||||
| 	} | 	}, | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  | @ -142,7 +142,7 @@ export default defineComponent({ | ||||||
| 		display: flex; | 		display: flex; | ||||||
| 		flex-wrap: wrap; | 		flex-wrap: wrap; | ||||||
| 
 | 
 | ||||||
| 		> div { | 		> .file { | ||||||
| 			position: relative; | 			position: relative; | ||||||
| 			width: 64px; | 			width: 64px; | ||||||
| 			height: 64px; | 			height: 64px; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| <template> | <template> | ||||||
| <div v-size="{ max: [310, 500] }" class="gafaadew" | <div | ||||||
|  | 	v-size="{ max: [310, 500] }" class="gafaadew" | ||||||
| 	:class="{ modal, _popup: modal }" | 	:class="{ modal, _popup: modal }" | ||||||
| 	@dragover.stop="onDragover" | 	@dragover.stop="onDragover" | ||||||
| 	@dragenter="onDragenter" | 	@dragenter="onDragenter" | ||||||
|  | @ -11,7 +12,7 @@ | ||||||
| 		<button v-click-anime v-tooltip="i18n.ts.switchAccount" class="account _button" @click="openAccountMenu"> | 		<button v-click-anime v-tooltip="i18n.ts.switchAccount" class="account _button" @click="openAccountMenu"> | ||||||
| 			<MkAvatar :user="postAccount ?? $i" class="avatar"/> | 			<MkAvatar :user="postAccount ?? $i" class="avatar"/> | ||||||
| 		</button> | 		</button> | ||||||
| 		<div> | 		<div class="right"> | ||||||
| 			<span class="text-count" :class="{ over: textLength > maxTextLength }">{{ maxTextLength - textLength }}</span> | 			<span class="text-count" :class="{ over: textLength > maxTextLength }">{{ maxTextLength - textLength }}</span> | ||||||
| 			<span v-if="localOnly" class="local-only"><i class="fas fa-biohazard"></i></span> | 			<span v-if="localOnly" class="local-only"><i class="fas fa-biohazard"></i></span> | ||||||
| 			<button ref="visibilityButton" v-tooltip="i18n.ts.visibility" class="_button visibility" :disabled="channel != null" @click="setVisibility"> | 			<button ref="visibilityButton" v-tooltip="i18n.ts.visibility" class="_button visibility" :disabled="channel != null" @click="setVisibility"> | ||||||
|  | @ -68,6 +69,8 @@ import * as misskey from 'misskey-js'; | ||||||
| import insertTextAtCursor from 'insert-text-at-cursor'; | import insertTextAtCursor from 'insert-text-at-cursor'; | ||||||
| import { length } from 'stringz'; | import { length } from 'stringz'; | ||||||
| import { toASCII } from 'punycode/'; | import { toASCII } from 'punycode/'; | ||||||
|  | import * as Acct from 'misskey-js/built/acct'; | ||||||
|  | import { throttle } from 'throttle-debounce'; | ||||||
| import XNoteSimple from './note-simple.vue'; | import XNoteSimple from './note-simple.vue'; | ||||||
| import XNotePreview from './note-preview.vue'; | import XNotePreview from './note-preview.vue'; | ||||||
| import XPostFormAttaches from './post-form-attaches.vue'; | import XPostFormAttaches from './post-form-attaches.vue'; | ||||||
|  | @ -75,14 +78,12 @@ import XPollEditor from './poll-editor.vue'; | ||||||
| import { host, url } from '@/config'; | import { host, url } from '@/config'; | ||||||
| import { erase, unique } from '@/scripts/array'; | import { erase, unique } from '@/scripts/array'; | ||||||
| import { extractMentions } from '@/scripts/extract-mentions'; | import { extractMentions } from '@/scripts/extract-mentions'; | ||||||
| import * as Acct from 'misskey-js/built/acct'; |  | ||||||
| import { formatTimeString } from '@/scripts/format-time-string'; | import { formatTimeString } from '@/scripts/format-time-string'; | ||||||
| import { Autocomplete } from '@/scripts/autocomplete'; | import { Autocomplete } from '@/scripts/autocomplete'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import { stream } from '@/stream'; | import { stream } from '@/stream'; | ||||||
| import { selectFiles } from '@/scripts/select-file'; | import { selectFiles } from '@/scripts/select-file'; | ||||||
| import { defaultStore, notePostInterruptors, postFormActions } from '@/store'; | import { defaultStore, notePostInterruptors, postFormActions } from '@/store'; | ||||||
| import { throttle } from 'throttle-debounce'; |  | ||||||
| import MkInfo from '@/components/ui/info.vue'; | import MkInfo from '@/components/ui/info.vue'; | ||||||
| import { i18n } from '@/i18n'; | import { i18n } from '@/i18n'; | ||||||
| import { instance } from '@/instance'; | import { instance } from '@/instance'; | ||||||
|  | @ -181,7 +182,7 @@ const placeholder = $computed((): string => { | ||||||
| 			i18n.ts._postForm._placeholders.c, | 			i18n.ts._postForm._placeholders.c, | ||||||
| 			i18n.ts._postForm._placeholders.d, | 			i18n.ts._postForm._placeholders.d, | ||||||
| 			i18n.ts._postForm._placeholders.e, | 			i18n.ts._postForm._placeholders.e, | ||||||
| 			i18n.ts._postForm._placeholders.f | 			i18n.ts._postForm._placeholders.f, | ||||||
| 		]; | 		]; | ||||||
| 		return xs[Math.floor(Math.random() * xs.length)]; | 		return xs[Math.floor(Math.random() * xs.length)]; | ||||||
| 	} | 	} | ||||||
|  | @ -263,7 +264,7 @@ if (props.reply && ['home', 'followers', 'specified'].includes(props.reply.visib | ||||||
| 	visibility = props.reply.visibility; | 	visibility = props.reply.visibility; | ||||||
| 	if (props.reply.visibility === 'specified') { | 	if (props.reply.visibility === 'specified') { | ||||||
| 		os.api('users/show', { | 		os.api('users/show', { | ||||||
| 			userIds: props.reply.visibleUserIds.filter(uid => uid !== $i.id && uid !== props.reply.userId) | 			userIds: props.reply.visibleUserIds.filter(uid => uid !== $i.id && uid !== props.reply.userId), | ||||||
| 		}).then(users => { | 		}).then(users => { | ||||||
| 			users.forEach(pushVisibleUser); | 			users.forEach(pushVisibleUser); | ||||||
| 		}); | 		}); | ||||||
|  | @ -399,7 +400,7 @@ function setVisibility() { | ||||||
| 			if (defaultStore.state.rememberNoteVisibility) { | 			if (defaultStore.state.rememberNoteVisibility) { | ||||||
| 				defaultStore.set('localOnly', localOnly); | 				defaultStore.set('localOnly', localOnly); | ||||||
| 			} | 			} | ||||||
| 		} | 		}, | ||||||
| 	}, 'closed'); | 	}, 'closed'); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -522,8 +523,8 @@ function saveDraft() { | ||||||
| 			visibility: visibility, | 			visibility: visibility, | ||||||
| 			localOnly: localOnly, | 			localOnly: localOnly, | ||||||
| 			files: files, | 			files: files, | ||||||
| 			poll: poll | 			poll: poll, | ||||||
| 		} | 		}, | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	localStorage.setItem('drafts', JSON.stringify(draftData)); | 	localStorage.setItem('drafts', JSON.stringify(draftData)); | ||||||
|  | @ -612,11 +613,11 @@ function showActions(ev) { | ||||||
| 		text: action.title, | 		text: action.title, | ||||||
| 		action: () => { | 		action: () => { | ||||||
| 			action.handler({ | 			action.handler({ | ||||||
| 				text: text | 				text: text, | ||||||
| 			}, (key, value) => { | 			}, (key, value) => { | ||||||
| 				if (key === 'text') { text = value; } | 				if (key === 'text') { text = value; } | ||||||
| 			}); | 			}); | ||||||
| 		} | 		}, | ||||||
| 	})), ev.currentTarget ?? ev.target); | 	})), ev.currentTarget ?? ev.target); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -726,7 +727,7 @@ onMounted(() => { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> div { | 		> .right { | ||||||
| 			position: absolute; | 			position: absolute; | ||||||
| 			top: 0; | 			top: 0; | ||||||
| 			right: 0; | 			right: 0; | ||||||
|  | @ -924,7 +925,7 @@ onMounted(() => { | ||||||
| 				line-height: 50px; | 				line-height: 50px; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			> div { | 			> .right { | ||||||
| 				> .text-count { | 				> .text-count { | ||||||
| 					line-height: 50px; | 					line-height: 50px; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue