Support the 'following' option on post searches
This commit is contained in:
		
							parent
							
								
									b3ab3be3be
								
							
						
					
					
						commit
						d53fc6923f
					
				
					 4 changed files with 110 additions and 2 deletions
				
			
		|  | @ -282,6 +282,7 @@ const getNodeInfo = async ({ store }) => { | ||||||
|       store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled }) |       store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled }) | ||||||
|       store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') }) |       store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') }) | ||||||
|       store.dispatch('setInstanceOption', { name: 'searchTypeMediaEnabled', value: features.includes('bnakkoma:search_type_media') }) |       store.dispatch('setInstanceOption', { name: 'searchTypeMediaEnabled', value: features.includes('bnakkoma:search_type_media') }) | ||||||
|  |       store.dispatch('setInstanceOption', { name: 'searchOptionFollowingEnabled', value: features.includes('bnakkoma:search_option_following') }) | ||||||
| 
 | 
 | ||||||
|       const uploadLimits = metadata.uploadLimits |       const uploadLimits = metadata.uploadLimits | ||||||
|       store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) }) |       store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) }) | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ import FollowCard from '../follow_card/follow_card.vue' | ||||||
| import Conversation from '../conversation/conversation.vue' | import Conversation from '../conversation/conversation.vue' | ||||||
| import Status from '../status/status.vue' | import Status from '../status/status.vue' | ||||||
| import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' | import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' | ||||||
|  | import SearchFilters from './search_filters.vue' | ||||||
| import map from 'lodash/map' | import map from 'lodash/map' | ||||||
| import { library } from '@fortawesome/fontawesome-svg-core' | import { library } from '@fortawesome/fontawesome-svg-core' | ||||||
| import { | import { | ||||||
|  | @ -20,7 +21,8 @@ const Search = { | ||||||
|     FollowCard, |     FollowCard, | ||||||
|     Conversation, |     Conversation, | ||||||
|     Status, |     Status, | ||||||
|     TabSwitcher |     TabSwitcher, | ||||||
|  |     SearchFilters | ||||||
|   }, |   }, | ||||||
|   props: [ |   props: [ | ||||||
|     'query' |     'query' | ||||||
|  | @ -41,7 +43,8 @@ const Search = { | ||||||
|       lastStatusFetchCount: 0, |       lastStatusFetchCount: 0, | ||||||
|       mediaOffset: 0, |       mediaOffset: 0, | ||||||
|       lastMediaFetchCount: 0, |       lastMediaFetchCount: 0, | ||||||
|       lastQuery: '' |       lastQuery: '', | ||||||
|  |       filter: {} | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|  | @ -64,6 +67,9 @@ const Search = { | ||||||
|     }, |     }, | ||||||
|     canSearchMediaPosts () { |     canSearchMediaPosts () { | ||||||
|       return this.$store.state.instance.searchTypeMediaEnabled === true |       return this.$store.state.instance.searchTypeMediaEnabled === true | ||||||
|  |     }, | ||||||
|  |     canSearchFollowing () { | ||||||
|  |       return this.$store.state.instance.searchOptionFollowingEnabled === true | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   mounted () { |   mounted () { | ||||||
|  | @ -73,6 +79,13 @@ const Search = { | ||||||
|     query (newValue) { |     query (newValue) { | ||||||
|       this.searchTerm = newValue |       this.searchTerm = newValue | ||||||
|       this.search(newValue) |       this.search(newValue) | ||||||
|  |     }, | ||||||
|  |     filter: { | ||||||
|  |       deep: true, | ||||||
|  |       handler () { | ||||||
|  |         this.lastQuery = "" // invalidate state
 | ||||||
|  |         this.search(this.searchTerm) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  | @ -113,6 +126,8 @@ const Search = { | ||||||
|         resolve: true, |         resolve: true, | ||||||
|         offset: searchOffset, |         offset: searchOffset, | ||||||
|         'type': searchType, |         'type': searchType, | ||||||
|  |         following: | ||||||
|  |           'followingOnly' in this.filter && this.filter.followingOnly | ||||||
|       }) |       }) | ||||||
|         .then(data => { |         .then(data => { | ||||||
|           this.loading = false |           this.loading = false | ||||||
|  |  | ||||||
|  | @ -4,6 +4,10 @@ | ||||||
|       <div class="title"> |       <div class="title"> | ||||||
|         {{ $t('nav.search') }} |         {{ $t('nav.search') }} | ||||||
|       </div> |       </div> | ||||||
|  |       <SearchFilters | ||||||
|  |         v-show="canSearchFollowing" | ||||||
|  |         v-model="filter" | ||||||
|  |       /> | ||||||
|     </div> |     </div> | ||||||
|     <div class="search-input-container"> |     <div class="search-input-container"> | ||||||
|       <input |       <input | ||||||
|  |  | ||||||
							
								
								
									
										88
									
								
								src/components/search/search_filters.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/components/search/search_filters.vue
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | ||||||
|  | <template> | ||||||
|  |   <Popover | ||||||
|  |     trigger="click" | ||||||
|  |     class="SearchFilters" | ||||||
|  |     placement="bottom" | ||||||
|  |     :bound-to="{ x: 'container' }" | ||||||
|  |   > | ||||||
|  |     <template #content> | ||||||
|  |       <div class="dropdown-menu"> | ||||||
|  |         <button | ||||||
|  |           class="button-default dropdown-item" | ||||||
|  |           @click="toggleFilter('followingOnly')" | ||||||
|  |         > | ||||||
|  |           <span | ||||||
|  |             class="menu-checkbox" | ||||||
|  |             :class="{ 'menu-checkbox-checked': currentFilter.followingOnly }" | ||||||
|  |           />{{ $t('lists.following_only') }} | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |     </template> | ||||||
|  |     <template #trigger> | ||||||
|  |       <button class="filter-trigger-button button-unstyled"> | ||||||
|  |         <FAIcon icon="filter" /> | ||||||
|  |       </button> | ||||||
|  |     </template> | ||||||
|  |   </Popover> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  | import Popover from '../popover/popover.vue' | ||||||
|  | import { library } from '@fortawesome/fontawesome-svg-core' | ||||||
|  | import { faFilter } from '@fortawesome/free-solid-svg-icons' | ||||||
|  | 
 | ||||||
|  | library.add( | ||||||
|  |   faFilter | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   components: { Popover }, | ||||||
|  |   props: [ | ||||||
|  |     'modelValue' | ||||||
|  |   ], | ||||||
|  |   emits: [ | ||||||
|  |     'update:modelValue' | ||||||
|  |   ], | ||||||
|  |   data () { | ||||||
|  |     return { | ||||||
|  |       currentFilter: { | ||||||
|  |         followingOnly: false | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created () { | ||||||
|  |     for (const filterName of Object.entries(this.currentFilter)) { | ||||||
|  |       if (this.modelValue && filterName in this.modelValue) { | ||||||
|  |         this.currentFilter[filterName] = this.modelValue[filterName] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     toggleFilter (filterName) { | ||||||
|  |       if (filterName in this.currentFilter) { | ||||||
|  |         this.currentFilter[filterName] = !this.currentFilter[filterName] | ||||||
|  |       } else { | ||||||
|  |         this.currentFilter[filterName] = true | ||||||
|  |       } | ||||||
|  |       this.$emit('update:modelValue', this.currentFilter) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss"> | ||||||
|  | .SearchFilters { | ||||||
|  |   align-self: stretch; | ||||||
|  | 
 | ||||||
|  |   > button { | ||||||
|  |     line-height: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     width: var(--__panel-heading-height-inner); | ||||||
|  |     text-align: center; | ||||||
|  | 
 | ||||||
|  |     svg { | ||||||
|  |       font-size: 1.2em; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
		Loading…
	
		Reference in a new issue