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 class="collection-item avatar" v-for="account in accounts" :key="account.fullId">
<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="isLoadingSources && 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"
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 {
isLoadingSources: false,
isLoadingRetribute: 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
})
allSuggestions () {
return Object.values(this.aggregatedSuggestions)
},
let self = this
let suggestions = this.allSuggestions.filter((s) => {
let f = true
if (self.filters.retributeOnly != null) {
f = !!this.retributeProfiles[s.fullId] === self.filters.retributeOnly
}
return f
})
return orderBy(suggestions, ['weight', 'id'], ['desc', 'asc'])
return this.retributeProfiles[s.fullId] === undefined
})
},
isLoading () {
return this.isLoadingSources || this.isLoadingRetribute
this.isLoadingSources = false
this.isLoadingRetribute = false
this.results = {}
this.aggregatedSuggestions = {}
this.retributeProfiles = {}
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
this.retributeProfiles = {}
this.loadingRetributeProfiles = []
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
}
let self = this
const toLoad = this.missingRetributeProfiles.filter((p) => {
return self.loadingRetributeProfiles.indexOf(p.fullId) === -1
})
if (toLoad.length === 0) {
return
}
this.isLoadingRetribute = true
const chunkSize = 10
// lock
toLoad.forEach((p) => {
self.loadingRetributeProfiles.push(p.fullId)
})
const chunks = chunk(toLoad, 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)
}
let self = this
ids.forEach((id) => {
self.loadingRetributeProfiles.push(id)
})
let url = config.RetributeAPIUrl + `v1/search/`
let response
try {
response = await client.post(url, {lookups: ids})
} catch {
ids.forEach((id) => {
self.$set(self.retributeProfiles, id, null)
})
return
ids.forEach((id) => {
self.$set(self.retributeProfiles, id, response.data[id])
})
this.loadingRetributeProfiles.push(id)
let url = config.RetributeAPIUrl + `v1/search/${id}`
try {
const response = await client.get(url)
this.$set(this.retributeProfiles, id, response.data)
} catch {
this.$set(this.retributeProfiles, id, null)
}
pull(this.loadingRetributeProfiles, [id])
async missingRetributeProfiles (v) {
await this.lookupAll()
},
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