Merge pull request #99 from nextcloud-gmbh/bugfix/noid/profile-info-view

Show list of followers/following on user profile
pull/113/head
Julius Härtl 2018-12-03 13:37:10 +01:00 zatwierdzone przez GitHub
commit a08cd46123
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 92 dodań i 35 usunięć

Wyświetl plik

@ -535,7 +535,9 @@ class LocalController extends Controller {
$avatar = $actor->getIcon();
$document = $this->documentService->getFromCache($avatar->getId());
return new FileDisplayResponse($document);
$response = new FileDisplayResponse($document);
$response->cacheFor(86400);
return $response;
}
return new NotFoundResponse();

Wyświetl plik

@ -565,6 +565,7 @@ class CoreRequestBuilder {
->selectAlias('ca.public_key', 'cacheactor_public_key')
->selectAlias('ca.source', 'cacheactor_source')
->selectAlias('ca.creation', 'cacheactor_creation')
->selectAlias('ca.local', 'cacheactor_local')
->leftJoin(
$this->defaultSelectAlias, CoreRequestBuilder::TABLE_CACHE_ACTORS, 'ca',
$expr->eq($pf . '.' . $fieldActorId, 'ca.id')

Wyświetl plik

@ -25,21 +25,27 @@
<div class="user-profile--info">
<avatar :user="uid" :display-name="displayName" :size="128" />
<h2>{{ displayName }}</h2>
<p>{{ accountInfo.cloudId }}</p>
<p>{{ accountInfo.account }}</p>
<p v-if="accountInfo.website">Website: <a :href="accountInfo.website.value">{{ accountInfo.website.value }}</a></p>
<button v-if="!serverData.public" class="primary" @click="follow">Follow</button>
<template v-if="currentUser.uid !== accountInfo.preferredUsername">
<button v-if="accountInfo.details && accountInfo.details.following" :class="{'icon-loading-small': followLoading}"
@click="unfollow()"
@mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')">
<span><span class="icon-checkmark" />{{ followingText }}</span></button>
<button v-else-if="accountInfo.details" :class="{'icon-loading-small': followLoading}" class="primary"
@click="follow"><span>{{ t('social', 'Follow') }}</span></button>
</template>
</div>
<ul class="user-profile--sections">
<ul v-if="accountInfo.details" class="user-profile--sections">
<li>
<router-link :to="{ name: 'profile', params: { account: uid } }" class="icon-category-monitoring">{{ accountInfo.posts }} posts</router-link>
<router-link :to="{ name: 'profile', params: { account: uid } }" class="icon-category-monitoring">{{ accountInfo.details.count.post }} {{ t('social', 'Posts') }}</router-link>
</li>
<li>
<router-link :to="{ name: 'profile.following', params: { account: uid } }" class="icon-category-social">{{ accountInfo.following }} following</router-link>
<router-link :to="{ name: 'profile.following', params: { account: uid } }" class="icon-category-social">{{ accountInfo.details.count.following }} {{ t('social', 'Following') }}</router-link>
</li>
<li>
<router-link :to="{ name: 'profile.followers', params: { account: uid } }" class="icon-category-social">{{ accountInfo.followers }} followers</router-link>
<router-link :to="{ name: 'profile.followers', params: { account: uid } }" class="icon-category-social">{{ accountInfo.details.count.followers }} {{ t('social', 'Followers') }}</router-link>
</li>
</ul>
</div>
@ -82,22 +88,31 @@
import { Avatar } from 'nextcloud-vue'
import serverData from '../mixins/serverData'
import currentUser from '../mixins/currentUserMixin'
import follow from '../mixins/follow'
export default {
name: 'ProfileInfo',
components: {
Avatar
},
mixins: [serverData],
mixins: [serverData, currentUser, follow],
props: {
uid: {
type: String,
default: ''
}
},
data: function() {
return {
followingText: t('social', 'Following')
}
},
computed: {
displayName() {
if (typeof this.accountInfo.displayname !== 'undefined') { return this.accountInfo.displayname.value || '' }
if (typeof this.accountInfo.name !== 'undefined' && this.accountInfo.name !== '') {
return this.accountInfo.name
}
return this.uid
},
accountInfo: function() {

Wyświetl plik

@ -25,10 +25,10 @@
<div class="entry-content">
<div class="user-avatar">
<avatar v-if="item.local" :size="32" :user="item.preferredUsername" />
<avatar v-else :url="item.icon.url" />
<avatar v-else :url="avatarUrl" />
</div>
<div class="user-details">
<router-link v-if="item.local" :to="{ name: 'profile', params: { account: item.account }}">
<router-link v-if="item.local" :to="{ name: 'profile', params: { account: item.preferredUsername }}">
<span class="post-author">{{ item.preferredUsername }}</span>
</router-link>
<a v-else :href="item.id" target="_blank"
@ -36,11 +36,11 @@
<!-- TODO check where the html is coming from to avoid security issues -->
<p v-html="item.summary" />
</div>
<button v-if="item.details.following" :class="{'icon-loading-small': followLoading}"
<button v-if="item.details && item.details.following" :class="{'icon-loading-small': followLoading}"
@click="unfollow()"
@mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')">
<span><span class="icon-checkmark" />{{ followingText }}</span></button>
<button v-else :class="{'icon-loading-small': followLoading}" class="primary"
<button v-else-if="item.details" :class="{'icon-loading-small': followLoading}" class="primary"
@click="follow"><span>{{ t('social', 'Follow') }}</span></button>
</div>
</div>
@ -65,6 +65,17 @@ export default {
return {
followingText: t('social', 'Following')
}
},
computed: {
id() {
if (this.item.actor_info) {
return this.item.actor_info.id
}
return this.item.id
},
avatarUrl() {
return OC.generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.id)
}
}
}
</script>

Wyświetl plik

@ -24,22 +24,54 @@ import axios from 'nextcloud-axios'
import Vue from 'vue'
const state = {
accounts: {}
accounts: {},
accountsFollowers: {},
accountsFollowing: {}
}
const mutations = {
addAccount(state, { uid, data }) {
Vue.set(state.accounts, uid, data)
},
addFollowers(state, { uid, data }) {
let users = []
for (var index in data) {
users.push(data[index].actor_info)
}
Vue.set(state.accountsFollowers, uid, users)
},
addFollowing(state, { uid, data }) {
let users = []
for (var index in data) {
users.push(data[index].actor_info)
}
Vue.set(state.accountsFollowing, uid, users)
}
}
const getters = {
getAccount(state) {
return (uid) => state.accounts[uid]
},
getAccountFollowers(state) {
return (uid) => state.accountsFollowers[uid]
},
getAccountFollowing(state) {
return (uid) => state.accountsFollowing[uid]
}
}
const actions = {
fetchAccountInfo(context, uid) {
axios.get(OC.generateUrl('apps/social/local/account/' + uid)).then((response) => {
context.commit('addAccount', { uid: uid, data: response.data })
axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/info`)).then((response) => {
context.commit('addAccount', { uid: uid, data: response.data.result.account })
})
},
fetchAccountFollowers(context, uid) {
axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/followers`)).then((response) => {
context.commit('addFollowers', { uid: uid, data: response.data.result })
})
},
fetchAccountFollowing(context, uid) {
axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/following`)).then((response) => {
context.commit('addFollowing', { uid: uid, data: response.data.result })
})
}
}

Wyświetl plik

@ -31,6 +31,7 @@
max-width: 700px;
margin: 15px auto;
display: flex;
flex-wrap: wrap;
}
.user-entry {
width: 50%;
@ -46,24 +47,19 @@ export default {
UserEntry
},
computed: {
timeline: function() {
return this.$store.getters.getTimeline
},
users() {
return [
{
id: 'admin',
displayName: 'Administrator',
description: 'My social account',
following: true
},
{
id: 'admin',
displayName: 'Administrator',
description: 'My social account',
following: false
}
]
users: function() {
if (this.$route.name === 'profile.followers') {
return this.$store.getters.getAccountFollowers(this.$route.params.account)
} else {
return this.$store.getters.getAccountFollowing(this.$route.params.account)
}
}
},
beforeMount() {
if (this.$route.name === 'profile.followers') {
this.$store.dispatch('fetchAccountFollowers', this.$route.params.account)
} else {
this.$store.dispatch('fetchAccountFollowing', this.$route.params.account)
}
}
}