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