2020-03-29 12:29:55 +02:00

134 lines
3.2 KiB
Vue

<template>
<base-card class="follow-list">
<template v-if="connections && connections.length">
<ds-text tag="h5" color="soft" class="spacer-x-small">
{{ userName | truncate(15) }} {{ $t(`profile.network.${type}`) }}
</ds-text>
<div :class="connectionsClass">
<user-teaser
v-for="connection in filteredConnections"
class="spacer-x-small"
:user="connection"
:key="connection.id"
/>
</div>
<base-button
v-if="allConnectionsCount - connections.length"
@click="$emit('fetchAllConnections', type)"
:loading="loading"
size="small"
color="softer"
class="spacer-x-small"
>
{{
$t('profile.network.andMore', {
number: allConnectionsCount - connections.length,
})
}}
</base-button>
<ds-input
v-if="connections.length > 7"
@input.native="setFilter"
:placeholder="filter"
v-focus="true"
size="small"
icon="filter"
:name="`${type}Filter`"
class="spacer-x-small"
/>
</template>
<p v-else class="nobody-message">{{ userName }} {{ $t(`profile.network.${type}Nobody`) }}</p>
</base-card>
</template>
<script>
import UserTeaser from '~/components/UserTeaser/UserTeaser'
export default {
name: 'FollowerList',
components: {
UserTeaser,
},
props: {
user: { type: Object, default: null },
type: { type: String, default: 'following' },
loading: { type: Boolean, default: false },
},
data() {
return {
filter: null,
}
},
computed: {
userName() {
const { name } = this.user || {}
return name || this.$t('profile.userAnonym')
},
allConnectionsCount() {
return this.user[`${this.type}Count`]
},
connections() {
return this.user[this.type]
},
connectionsClass() {
const overflow = this.connections.length > 7 ? ' --overflow' : ''
return `connections${overflow}`
},
filteredConnections() {
if (!this.filter) {
return this.connections
}
const fuzzyExpression = new RegExp(
`${this.filter.split('').reduce((part, c) => `${part}[^${c}]*${c}`)}`,
'i',
)
const fuzzyScores = this.connections
.map((user) => {
const match = user.name.match(fuzzyExpression)
return {
user,
score: match ? match[0].length * (match.index + 1) : -1,
}
})
.filter((score) => score.score !== -1)
.sort((a, b) => a.score - b.score)
return fuzzyScores.map((score) => score.user)
},
},
methods: {
setFilter(evt) {
this.filter = evt.target.value
},
},
}
</script>
<style lang="scss">
.follow-list {
display: flex;
flex-direction: column;
position: relative;
//max-height: ($size-avatar-small + $space-x-small * 2) * 8;
width: auto;
.connections.--overflow {
height: ($size-avatar-base + $space-x-small * 2) * 5;
margin-top: -$space-x-small;
overflow-y: auto;
}
.nobody-message {
text-align: center;
color: $text-color-soft;
}
.spacer-x-small {
margin: $space-x-small 0;
}
}
</style>