Newer
Older
<template>
<div>
<ul class="collection with-header">
<li class="collection-header">
<router-link to="/connect" class="secondary-content">Add another account</router-link>
<h5>Connected accounts</h5>
</li>
<li class="collection-item avatar" v-for="account in accounts" :key="account.id">
<img v-if="account._source.getAvatar(account)" :src="account._source.getAvatar(account)" alt="" class="circle">
<span class="title">{{ account._source.getDisplayName(account) }}</span>
<p>{{ account._source.label }}</p>
<div v-if="isLoading && results[account.id] && results[account.id].results.isLoading">
<div class="progress">
<div v-if="results[account.id].results.progress === 'indeterminate'" :class="indeterminate"></div>
<div v-else class="determinate" :style="{width: `${results[account.id].results.progress}%`}"></div>
</div>
{{ results[account.id].results.status }}
</div>
<a @click="fetch(account.id)" class="secondary-content"><i class="material-icons">refresh</i></a>
<h2>
Suggestions
<button
@click="fetch()"
:class="['waves-effect', 'waves-light', {disabled: isLoading}, 'btn-small']" :disabled="isLoading">
<i class="material-icons left">refresh</i>Fetch data
</button>
</h2>
<div v-if="isLoading" class="progress">
<div class="indeterminate"></div>
</div>
<ul class="collection">
<li class="collection-item avatar" v-for="suggestion in filteredSuggestions" :key="suggestion.fullId">
<img v-if="suggestion.avatar" :src="suggestion.avatar" alt="" class="circle">
<a target="_blank" rel="noopener noreferrer" :href="suggestion.url" class="title">{{ suggestion.name }}</a>
<p>Score: {{ suggestion.weight }}</p>
<a v-if="retributeProfiles[suggestion.fullId] === undefined" @click="lookup(suggestion.fullId)" class="secondary-content"><i class="material-icons">search</i></a>
<div v-else-if="retributeProfiles[suggestion.fullId]">
<h6>Donation platforms</h6>
<!-- {{ retributeProfiles[suggestion.fullId] }} -->
<template v-for="mean in retributeProfiles[suggestion.fullId].means">
<a
:href="mean.url"
:key="mean.id"
target="_blank"
rel="noopener noreferrer"
:class="['waves-effect', 'waves-light', 'btn-small']">
<span :title="mean.summary">{{ mean.provider }}</span>
</a>
</template>
</div>
<div v-else>No retribute information found for this account</div>
</div>
</template>
<script>
import sources from '@/sources'
import chunk from 'lodash/chunk'
import axios from 'axios'
export default {
data () {
return {
isLoading: false,
aggregatedSuggestions: this.$store.state.cache.aggregatedSuggestions || {},
retributeProfiles: this.$store.state.cache.retributeProfiles || {},
}
},
computed: {
accounts () {
return this.$store.getters.sortedAccounts.map((a) => {
a._source = sources.sources[a.source]
return a
})
},
filteredSuggestions () {
return orderBy(Object.values(this.aggregatedSuggestions), ['weight', 'id'], ['desc', 'asc'])
},
aggregateSuggestions (results) {
const aggregated = {}
Object.keys(results).forEach((account) => {
let r = results[account]
if (!r.results || !r.results.accounts) {
} else {
Object.keys(r.results.accounts).forEach((key) => {
if (aggregated[key]) {
aggregated[key].weight += r.results.accounts[key].weight
aggregated[key].accounts.push(account)
} else {
aggregated[key] = {...r.results.accounts[key], accounts: [account], fullId: key}
}
})
}
})
return aggregated
},
async fetch (id) {
let accounts
if (id) {
accounts = this.accounts.filter((a) => {
return a.id == id
})
} else {
accounts = this.accounts
}
accounts.forEach((a) => {
let r = {isLoading: true, progress: 'indeterminate', status: ''}
let promise = a._source.fetch({account: a, store: this.$store, results: r, vue: this})
this.$set(this.results, a.id, {account: a, promise, results: r})
})
const keys = Object.keys(this.results)
for(let i = 0; i < keys.length; i++){
await this.results[keys[i]].promise
}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
},
async lookupAll () {
const toLookup = this.filteredSuggestions.filter((s) => {
return this.retributeProfiles[s.fullId] === undefined
})
const chunkSize = 5
const chunks = chunk(toLookup, chunkSize)
for (let i = 0; i < chunks.length; i++){
let chunk = chunks[i]
let ids = chunk.map((s) => {
return s.fullId
})
await this.lookups(ids)
}
},
async lookups(ids) {
const tasks = ids.map((i) => {
return this.lookup(i)
})
for (let i = 0; i < tasks.length; i++){
await tasks[i]
}
},
async lookup (id) {
const client = axios.create({timeout: 5000})
let url = `http://localhost:8000/api/v1/search/${id}`
try {
const response = await client.get(url)
this.$set(this.retributeProfiles, id, response.data)
} catch {
this.$set(this.retributeProfiles, id, null)
return
}
},
watch: {
results: {
handler (v) {
this.aggregatedSuggestions = this.aggregateSuggestions(v)
this.$store.commit('setRecursiveState', {key: 'cache.aggregatedSuggestions', value: this.aggregatedSuggestions})
},
retributeProfiles: {
handler (v) {
this.$store.commit('setRecursiveState', {key: 'cache.retributeProfiles', value: this.retributeProfiles})
},
deep: true