wip
This commit is contained in:
		
							parent
							
								
									d09d06e4cb
								
							
						
					
					
						commit
						3b585a9020
					
				
					 2 changed files with 50 additions and 21 deletions
				
			
		|  | @ -1,13 +1,16 @@ | |||
| <template> | ||||
| <div class="mk-autocomplete" @contextmenu.prevent="() => {}"> | ||||
| 	<ol class="users" ref="suggests" v-if="users.length > 0"> | ||||
| 		<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1"> | ||||
| 	<ol class="users" ref="suggests" v-if="type === 'user'"> | ||||
| 		<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1" class="user"> | ||||
| 			<img class="avatar" :src="user.avatarUrl" alt=""/> | ||||
| 			<span class="name"> | ||||
| 				<mk-user-name :user="user" :key="user.id"/> | ||||
| 			</span> | ||||
| 			<span class="username">@{{ user | acct }}</span> | ||||
| 		</li> | ||||
| 		<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose"> | ||||
| 			{{ $t('choose-user') }} | ||||
| 		</li> | ||||
| 	</ol> | ||||
| 	<ol class="hashtags" ref="suggests" v-if="hashtags.length > 0"> | ||||
| 		<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1"> | ||||
|  | @ -81,11 +84,11 @@ export default Vue.extend({ | |||
| 
 | ||||
| 		q: { | ||||
| 			type: String, | ||||
| 			required: true, | ||||
| 			required: false, | ||||
| 		}, | ||||
| 
 | ||||
| 		textarea: { | ||||
| 			type: Object, | ||||
| 			type: HTMLTextAreaElement, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 
 | ||||
|  | @ -134,24 +137,12 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 
 | ||||
| 	updated() { | ||||
| 		//#region 位置調整 | ||||
| 		if (this.x + this.$el.offsetWidth > window.innerWidth) { | ||||
| 			this.$el.style.left = (window.innerWidth - this.$el.offsetWidth) + 'px'; | ||||
| 		} else { | ||||
| 			this.$el.style.left = this.x + 'px'; | ||||
| 		} | ||||
| 
 | ||||
| 		if (this.y + this.$el.offsetHeight > window.innerHeight) { | ||||
| 			this.$el.style.top = (this.y - this.$el.offsetHeight) + 'px'; | ||||
| 			this.$el.style.marginTop = '0'; | ||||
| 		} else { | ||||
| 			this.$el.style.top = this.y + 'px'; | ||||
| 			this.$el.style.marginTop = 'calc(1em + 8px)'; | ||||
| 		} | ||||
| 		//#endregion | ||||
| 		this.setPosition(); | ||||
| 	}, | ||||
| 
 | ||||
| 	mounted() { | ||||
| 		this.setPosition(); | ||||
| 
 | ||||
| 		//#region Construct Emoji DB | ||||
| 		const customEmojis = (this.$root.getMetaSync() || { emojis: [] }).emojis || []; | ||||
| 		const emojiDefinitions: EmojiDef[] = []; | ||||
|  | @ -208,6 +199,22 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		setPosition() { | ||||
| 			if (this.x + this.$el.offsetWidth > window.innerWidth) { | ||||
| 				this.$el.style.left = (window.innerWidth - this.$el.offsetWidth) + 'px'; | ||||
| 			} else { | ||||
| 				this.$el.style.left = this.x + 'px'; | ||||
| 			} | ||||
| 
 | ||||
| 			if (this.y + this.$el.offsetHeight > window.innerHeight) { | ||||
| 				this.$el.style.top = (this.y - this.$el.offsetHeight) + 'px'; | ||||
| 				this.$el.style.marginTop = '0'; | ||||
| 			} else { | ||||
| 				this.$el.style.top = this.y + 'px'; | ||||
| 				this.$el.style.marginTop = 'calc(1em + 8px)'; | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		exec() { | ||||
| 			this.select = -1; | ||||
| 			if (this.$refs.suggests) { | ||||
|  | @ -217,6 +224,12 @@ export default Vue.extend({ | |||
| 			} | ||||
| 
 | ||||
| 			if (this.type == 'user') { | ||||
| 				if (this.q == null) { | ||||
| 					this.users = []; | ||||
| 					this.fetching = false; | ||||
| 					return; | ||||
| 				} | ||||
| 
 | ||||
| 				const cacheKey = `autocomplete:user:${this.q}`; | ||||
| 				const cache = sessionStorage.getItem(cacheKey); | ||||
| 				if (cache) { | ||||
|  | @ -358,6 +371,15 @@ export default Vue.extend({ | |||
| 
 | ||||
| 			this.items[this.select].setAttribute('data-selected', 'true'); | ||||
| 			(this.items[this.select] as any).focus(); | ||||
| 		}, | ||||
| 
 | ||||
| 		chooseUser() { | ||||
| 			setTimeout(() => { | ||||
| 				this.complete('user', { | ||||
| 					host: null, | ||||
| 					username: 'test' | ||||
| 				}); | ||||
| 			}, 2000); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
|  | @ -416,7 +438,7 @@ export default Vue.extend({ | |||
| 				&, * | ||||
| 					color #fff !important | ||||
| 
 | ||||
| 	> .users > li | ||||
| 	> .users > li.user | ||||
| 
 | ||||
| 		.avatar | ||||
| 			min-width 28px | ||||
|  | @ -433,6 +455,9 @@ export default Vue.extend({ | |||
| 		.username | ||||
| 			color var(--autocompleteItemTextSub) | ||||
| 
 | ||||
| 	> .users > li.choose | ||||
| 		color var(--autocompleteItemText) | ||||
| 
 | ||||
| 	> .hashtags > li | ||||
| 
 | ||||
| 		.name | ||||
|  |  | |||
|  | @ -99,6 +99,9 @@ class Autocomplete { | |||
| 			if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) { | ||||
| 				this.open('user', username); | ||||
| 				opened = true; | ||||
| 			} else if (username === '') { | ||||
| 				this.open('user', null); | ||||
| 				opened = true; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -126,7 +129,7 @@ class Autocomplete { | |||
| 	/** | ||||
| 	 * サジェストを提示します。 | ||||
| 	 */ | ||||
| 	private async open(type, q) { | ||||
| 	private async open(type: string, q: string) { | ||||
| 		if (type != this.currentType) { | ||||
| 			this.close(); | ||||
| 		} | ||||
|  | @ -144,6 +147,7 @@ class Autocomplete { | |||
| 		//#endregion
 | ||||
| 
 | ||||
| 		if (this.suggestion) { | ||||
| 			// TODO: Vueの警告が出るのでなんとかする
 | ||||
| 			this.suggestion.x = x; | ||||
| 			this.suggestion.y = y; | ||||
| 			this.suggestion.q = q; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue