Support the 'following' option on post searches

This commit is contained in:
itepechi 2023-09-27 05:20:08 +09:00
parent b3ab3be3be
commit d53fc6923f
4 changed files with 110 additions and 2 deletions

View File

@ -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) })

View File

@ -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

View File

@ -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

View 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>