Merge pull request #52 from nextcloud-gmbh/frontend-implement-different-streams

Frontend implement different streams
pull/56/head
Maxence Lange 2018-11-22 17:04:33 -01:00 zatwierdzone przez GitHub
commit f6f7f2cd6a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
9 zmienionych plików z 82 dodań i 41 usunięć

Wyświetl plik

@ -73,6 +73,9 @@ class ActivityPubController extends Controller {
/** @var MiscService */ /** @var MiscService */
private $miscService; private $miscService;
/** @var NavigationController */
private $navigationController;
/** /**
* ActivityPubController constructor. * ActivityPubController constructor.
@ -90,11 +93,13 @@ class ActivityPubController extends Controller {
IRequest $request, SocialPubController $socialPubController, IRequest $request, SocialPubController $socialPubController,
ActivityService $activityService, ImportService $importService, ActivityService $activityService, ImportService $importService,
FollowService $followService, ActorService $actorService, NotesRequest $notesRequest, FollowService $followService, ActorService $actorService, NotesRequest $notesRequest,
NavigationController $navigationController,
MiscService $miscService MiscService $miscService
) { ) {
parent::__construct(Application::APP_NAME, $request); parent::__construct(Application::APP_NAME, $request);
$this->socialPubController = $socialPubController; $this->socialPubController = $socialPubController;
$this->navigationController = $navigationController;
$this->activityService = $activityService; $this->activityService = $activityService;
$this->importService = $importService; $this->importService = $importService;
@ -119,10 +124,11 @@ class ActivityPubController extends Controller {
* @param string $username * @param string $username
* *
* @return Response * @return Response
* @throws \OC\User\NoUserException
*/ */
public function actor(string $username): Response { public function actor(string $username): Response {
if (!$this->checkSourceActivityStreams()) { if (!$this->checkSourceActivityStreams()) {
return $this->socialPubController->actor($username); return $this->navigationController->public($username);
} }
try { try {
@ -326,7 +332,7 @@ class ActivityPubController extends Controller {
private function checkSourceActivityStreams(): bool { private function checkSourceActivityStreams(): bool {
// uncomment this line to display the result that would be return to an ActivityPub service (TEST) // uncomment this line to display the result that would be return to an ActivityPub service (TEST)
return true; // return true;
if ($this->request->getHeader('Accept') if ($this->request->getHeader('Accept')
=== 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"') { === 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"') {

Wyświetl plik

@ -95,7 +95,7 @@ class LocalController extends Controller {
* @param MiscService $miscService * @param MiscService $miscService
*/ */
public function __construct( public function __construct(
IRequest $request, string $userId, PersonService $personService, IRequest $request, $userId, PersonService $personService,
FollowService $followService, ActorService $actorService, FollowService $followService, ActorService $actorService,
PostService $postService, NoteService $noteService, PostService $postService, NoteService $noteService,
MiscService $miscService MiscService $miscService
@ -181,11 +181,11 @@ class LocalController extends Controller {
* *
* @return DataResponse * @return DataResponse
*/ */
public function streamHome(): DataResponse { public function streamHome(int $since = 0, int $limit = 5): DataResponse {
try { try {
$actor = $this->actorService->getActorFromUserId($this->userId); $actor = $this->actorService->getActorFromUserId($this->userId);
$posts = $this->noteService->getHomeNotesForActor($actor); $posts = $this->noteService->getHomeNotesForActor($actor, $since, $limit);
return $this->success($posts); return $this->success($posts);
} catch (Exception $e) { } catch (Exception $e) {
@ -203,11 +203,11 @@ class LocalController extends Controller {
* *
* @return DataResponse * @return DataResponse
*/ */
public function streamDirect(): DataResponse { public function streamDirect(int $since = 0, int $limit = 5): DataResponse {
try { try {
$actor = $this->actorService->getActorFromUserId($this->userId); $actor = $this->actorService->getActorFromUserId($this->userId);
$posts = $this->noteService->getDirectNotesForActor($actor); $posts = $this->noteService->getDirectNotesForActor($actor, $since, $limit);
return $this->success($posts); return $this->success($posts);
} catch (Exception $e) { } catch (Exception $e) {

Wyświetl plik

@ -142,11 +142,12 @@ class NotesRequest extends NotesRequestBuilder {
* *
* @return array * @return array
*/ */
public function getHomeNotesForActorId(string $actorId): array { public function getHomeNotesForActorId(string $actorId, $since, $limit): array {
$qb = $this->getNotesSelectSql(); $qb = $this->getNotesSelectSql();
$this->rightJoinFollowing($qb); $this->rightJoinFollowing($qb);
$this->limitToActorId($qb, $actorId, 'f'); $this->limitToActorId($qb, $actorId, 'f');
$this->limitPaginate($qb, $since, $limit);
// $this->leftJoinCacheActors($qb, 'attributed_to'); // $this->leftJoinCacheActors($qb, 'attributed_to');
$notes = []; $notes = [];
@ -192,9 +193,10 @@ class NotesRequest extends NotesRequestBuilder {
* *
* @return array * @return array
*/ */
public function getDirectNotesForActorId(string $actorId): array { public function getDirectNotesForActorId(string $actorId, $since, $limit): array {
$qb = $this->getNotesSelectSql(); $qb = $this->getNotesSelectSql();
$this->limitToRecipient($qb, $actorId); $this->limitToRecipient($qb, $actorId);
$this->limitPaginate($qb, $since, $limit);
$this->leftJoinCacheActors($qb, 'attributed_to'); $this->leftJoinCacheActors($qb, 'attributed_to');
$notes = []; $notes = [];

Wyświetl plik

@ -312,8 +312,8 @@ class NoteService implements ICoreService {
* *
* @return Note[] * @return Note[]
*/ */
public function getHomeNotesForActor(Person $actor): array { public function getHomeNotesForActor(Person $actor, $since, $limit): array {
return $this->notesRequest->getHomeNotesForActorId($actor->getId()); return $this->notesRequest->getHomeNotesForActorId($actor->getId(), $since, $limit);
} }
@ -322,8 +322,8 @@ class NoteService implements ICoreService {
* *
* @return Note[] * @return Note[]
*/ */
public function getDirectNotesForActor(Person $actor): array { public function getDirectNotesForActor(Person $actor, $since, $limit): array {
return $this->notesRequest->getDirectNotesForActorId($actor->getId()); return $this->notesRequest->getDirectNotesForActorId($actor->getId(), $since, $limit);
} }

Wyświetl plik

@ -89,12 +89,22 @@ export default {
{ {
id: 'social-timeline', id: 'social-timeline',
classes: [], classes: [],
icon: 'icon-category-monitoring', icon: 'icon-home',
text: t('social', 'Timeline'), text: t('social', 'Home'),
router: { router: {
name: 'timeline' name: 'timeline'
} }
}, },
{
id: 'social-direct-messages',
classes: [],
router: {
name: 'timeline',
params: { type: 'direct' }
},
icon: 'icon-comment',
text: t('social', 'Direct messages')
},
{ {
id: 'social-account', id: 'social-account',
classes: [], classes: [],
@ -106,28 +116,28 @@ export default {
} }
}, },
{ {
id: 'social-friends', id: 'social-spacer',
classes: [], classes: []
href: '#',
icon: 'icon-category-social',
text: t('social', 'Friends')
}, },
{ {
id: 'social-favorites', id: 'social-local',
classes: [], classes: [],
href: '#', icon: 'icon-category-monitoring',
icon: 'icon-favorite', text: t('social', 'Local timeline'),
text: t('social', 'Favorites') router: {
name: 'timeline',
params: { type: 'timeline' }
}
}, },
{ {
id: 'social-direct-messages', id: 'social-global',
classes: [], classes: [],
href: '#', icon: 'icon-link',
icon: 'icon-comment', text: t('social', 'Global timeline'),
utils: { router: {
counter: 3 name: 'timeline',
}, params: { type: 'federated' }
text: t('social', 'Direct messages') }
} }
] ]
return { return {

Wyświetl plik

@ -33,13 +33,13 @@
<ul class="user-profile--sections"> <ul class="user-profile--sections">
<li> <li>
<router-link to="./" class="icon-category-monitoring">{{ accountInfo.posts }} posts</router-link> <router-link :to="{ name: 'profile', params: { account: $route.params.account }}" class="icon-category-monitoring">{{ accountInfo.posts }} posts</router-link>
</li> </li>
<li> <li>
<router-link to="./following" class="icon-category-social">{{ accountInfo.following }} following</router-link> <router-link :to="{ name: 'following', params: { account: $route.params.account }}" class="icon-category-social">{{ accountInfo.following }} following</router-link>
</li> </li>
<li> <li>
<router-link to="./followers" class="icon-category-social">{{ accountInfo.followers }} followers</router-link> <router-link :to="{ name: 'followers', params: { account: $route.params.account }}" class="icon-category-social">{{ accountInfo.followers }} followers</router-link>
</li> </li>
</ul> </ul>
</div> </div>

Wyświetl plik

@ -41,6 +41,10 @@ export default new Router({
routes: [ routes: [
{ {
path: '/:index(index.php/)?apps/social/', path: '/:index(index.php/)?apps/social/',
redirect: { name: 'timeline' }
},
{
path: '/:index(index.php/)?apps/social/timeline/:type?',
components: { components: {
default: Timeline default: Timeline
}, },
@ -48,7 +52,7 @@ export default new Router({
name: 'timeline' name: 'timeline'
}, },
{ {
path: '/:index(index.php/)?apps/social/account/:account', path: '/:index(index.php/)?apps/social/account/@:account',
components: { components: {
default: Profile default: Profile
}, },
@ -78,7 +82,7 @@ export default new Router({
] ]
}, },
{ {
path: '/:index(index.php/)?apps/social/:account', path: '/:index(index.php/)?apps/social/@:account',
component: Profile, component: Profile,
props: true, props: true,
name: 'public' name: 'public'

Wyświetl plik

@ -25,18 +25,25 @@ import Vue from 'vue'
const state = { const state = {
timeline: {}, timeline: {},
since: new Date() since: Math.floor(Date.now() / 1000) + 1,
type: 'home'
} }
const mutations = { const mutations = {
addToTimeline(state, data) { addToTimeline(state, data) {
for (let item in data) { for (let item in data) {
state.since = data[item].published state.since = data[item].publishedTime
Vue.set(state.timeline, data[item].id, data[item]) Vue.set(state.timeline, data[item].id, data[item])
} }
}, },
addPost(state, data) { addPost(state, data) {
// FIXME: push data we receive to the timeline array // FIXME: push data we receive to the timeline array
// state.timeline.push(data) // state.timeline.push(data)
},
resetTimeline(state) {
state.timeline = {}
},
setTimelineType(state, type) {
state.type = type
} }
} }
const getters = { const getters = {
@ -47,6 +54,10 @@ const getters = {
} }
} }
const actions = { const actions = {
changeTimelineType(context, type) {
context.commit('resetTimeline')
context.commit('setTimelineType', type)
},
post(context, post) { post(context, post) {
return axios.post(OC.generateUrl('apps/social/api/v1/post'), { data: post }).then((response) => { return axios.post(OC.generateUrl('apps/social/api/v1/post'), { data: post }).then((response) => {
context.commit('addPost', { data: response.data }) context.commit('addPost', { data: response.data })
@ -60,9 +71,9 @@ const actions = {
}, },
fetchTimeline(context, { account, sinceTimestamp }) { fetchTimeline(context, { account, sinceTimestamp }) {
if (typeof sinceTimestamp === 'undefined') { if (typeof sinceTimestamp === 'undefined') {
sinceTimestamp = Date.parse(state.since) / 1000 sinceTimestamp = state.since - 1
} }
return axios.get(OC.generateUrl('apps/social/api/v1/stream/timeline?limit=5&since=' + sinceTimestamp)).then((response) => { return axios.get(OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=5&since=` + sinceTimestamp)).then((response) => {
if (response.status === -1) { if (response.status === -1) {
throw response.message throw response.message
} }

Wyświetl plik

@ -1,5 +1,6 @@
<template> <template>
<div class="social__wrapper"> <div class="social__wrapper">
{{ type }}
<div class="social__container"> <div class="social__container">
<transition name="slide-fade"> <transition name="slide-fade">
<div v-if="showInfo" class="social__welcome"> <div v-if="showInfo" class="social__welcome">
@ -124,6 +125,12 @@ export default {
} }
}, },
computed: { computed: {
type: function() {
if (this.$route.params.type) {
return this.$route.params.type
}
return 'home'
},
url: function() { url: function() {
return OC.linkTo('social', 'img/nextcloud.png') return OC.linkTo('social', 'img/nextcloud.png')
}, },
@ -181,7 +188,7 @@ export default {
} }
}, },
beforeMount: function() { beforeMount: function() {
this.$store.dispatch('changeTimelineType', this.type)
}, },
methods: { methods: {
hideInfo() { hideInfo() {
@ -201,6 +208,7 @@ export default {
}).catch((error) => { }).catch((error) => {
OC.Notification.showTemporary('Failed to load more timeline entries') OC.Notification.showTemporary('Failed to load more timeline entries')
console.error('Failed to load more timeline entries', error) console.error('Failed to load more timeline entries', error)
$state.complete()
}) })
} }
} }