kopia lustrzana https://github.com/nextcloud/social
				
				
				
			Embedd timeline in profile page
Signed-off-by: Carl Schwan <carl@carlschwan.eu>pull/1469/head
							rodzic
							
								
									cb25fb1b4e
								
							
						
					
					
						commit
						fff26baedf
					
				| 
						 | 
				
			
			@ -37,11 +37,13 @@ use OCA\Social\Search\UnifiedSearchProvider;
 | 
			
		|||
use OCA\Social\Service\ConfigService;
 | 
			
		||||
use OCA\Social\Service\UpdateService;
 | 
			
		||||
use OCA\Social\WellKnown\WebfingerHandler;
 | 
			
		||||
use OCA\Social\Listeners\ProfileSectionListener;
 | 
			
		||||
use OCP\AppFramework\App;
 | 
			
		||||
use OCP\AppFramework\Bootstrap\IBootContext;
 | 
			
		||||
use OCP\AppFramework\Bootstrap\IBootstrap;
 | 
			
		||||
use OCP\AppFramework\Bootstrap\IRegistrationContext;
 | 
			
		||||
use OCP\AppFramework\QueryException;
 | 
			
		||||
use OCP\Profile\BeforeTemplateRenderedEvent;
 | 
			
		||||
use OCP\IDBConnection;
 | 
			
		||||
use OCP\IServerContainer;
 | 
			
		||||
use OC\DB\SchemaWrapper;
 | 
			
		||||
| 
						 | 
				
			
			@ -62,19 +64,12 @@ class Application extends App implements IBootstrap {
 | 
			
		|||
		parent::__construct(self::APP_NAME, $params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param IRegistrationContext $context
 | 
			
		||||
	 */
 | 
			
		||||
	public function register(IRegistrationContext $context): void {
 | 
			
		||||
		$context->registerSearchProvider(UnifiedSearchProvider::class);
 | 
			
		||||
		$context->registerWellKnownHandler(WebfingerHandler::class);
 | 
			
		||||
		$context->registerEventListener(BeforeTemplateRenderedEvent::class, ProfileSectionListener::class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param IBootContext $context
 | 
			
		||||
	 */
 | 
			
		||||
	public function boot(IBootContext $context): void {
 | 
			
		||||
		$manager = $context->getServerContainer()
 | 
			
		||||
						   ->getNotificationManager();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
<?php
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
 | 
			
		||||
// SPDX-License-Identifier: AGPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
namespace OCA\Social\Listeners;
 | 
			
		||||
 | 
			
		||||
use OCP\EventDispatcher\Event;
 | 
			
		||||
use OCP\EventDispatcher\IEventListener;
 | 
			
		||||
use OCP\Profile\BeforeTemplateRenderedEvent;
 | 
			
		||||
use OCP\Util;
 | 
			
		||||
 | 
			
		||||
class ProfileSectionListener implements IEventListener {
 | 
			
		||||
	public function handle(Event $event): void {
 | 
			
		||||
		if (!($event instanceof BeforeTemplateRenderedEvent)) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		Util::addScript('social', 'social-profilePage');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
				<span class="icon-boost" />
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="boost">
 | 
			
		||||
				<router-link v-if="item.actor_info" :to="{ name: 'profile', params: { account: item.local ? item.actor_info.preferredUsername : item.actor_info.account }}">
 | 
			
		||||
				<router-link v-if="!isProfilePage && item.actor_info" :to="{ name: 'profile', params: { account: item.local ? item.actor_info.preferredUsername : item.actor_info.account }}">
 | 
			
		||||
					<span v-tooltip.bottom="item.actor_info.account" class="post-author">
 | 
			
		||||
						{{ userDisplayName(item.actor_info) }}
 | 
			
		||||
					</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,14 @@ export default {
 | 
			
		|||
		UserEntry
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
		item: { type: Object, default: () => {} }
 | 
			
		||||
		item: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			default: () => {}
 | 
			
		||||
		},
 | 
			
		||||
		isProfilePage: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@
 | 
			
		|||
		<div v-if="hasAttachments" class="post-attachments">
 | 
			
		||||
			<post-attachment :attachments="item.attachment" />
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-if="this.$route.params.type !== 'notifications' && !serverData.public" class="post-actions">
 | 
			
		||||
		<div v-if="this.$route && this.$route.params.type !== 'notifications' && !serverData.public" class="post-actions">
 | 
			
		||||
			<NcButton type="tertiary-no-background"
 | 
			
		||||
				v-tooltip="t('social', 'Reply')"
 | 
			
		||||
				@click="reply">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,9 @@ export default {
 | 
			
		|||
		 * @property 		setup
 | 
			
		||||
		 */
 | 
			
		||||
		serverData() {
 | 
			
		||||
			if (!this.$store) {
 | 
			
		||||
				return {}
 | 
			
		||||
			}
 | 
			
		||||
			return this.$store.getters.getServerData
 | 
			
		||||
		},
 | 
			
		||||
		hostname() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
// SPDX-FileCopyrigthText: 2022 Carl Schwan <carl@carlschwan.eu>
 | 
			
		||||
// SPDX-License-Identifier: AGPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line
 | 
			
		||||
__webpack_nonce__ = btoa(OC.requestToken)
 | 
			
		||||
// eslint-disable-next-line
 | 
			
		||||
__webpack_public_path__ = OC.linkTo('social', 'js/')
 | 
			
		||||
 | 
			
		||||
import ProfilePageIntegration from './views/ProfilePageIntegration.vue' 
 | 
			
		||||
import Vue from 'vue'
 | 
			
		||||
import { sync } from 'vuex-router-sync'
 | 
			
		||||
 | 
			
		||||
if (!OCA?.Core?.ProfileSections) {
 | 
			
		||||
	exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vue.prototype.t = t
 | 
			
		||||
Vue.prototype.n = n
 | 
			
		||||
Vue.prototype.OC = OC
 | 
			
		||||
Vue.prototype.OCA = OCA
 | 
			
		||||
 | 
			
		||||
const View = Vue.extend(ProfilePageIntegration)
 | 
			
		||||
 | 
			
		||||
OCA.Core.ProfileSections.registerSection((el, userId) => {
 | 
			
		||||
	return View
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
<template>
 | 
			
		||||
	<div>
 | 
			
		||||
		<h2>Social</h2>
 | 
			
		||||
		<transition-group name="list" tag="div">
 | 
			
		||||
			<TimelineEntry v-for="entry in timeline" :key="entry.id" :item="entry" :isProfilePage="true" />
 | 
			
		||||
		</transition-group>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import ProfileInfo from './../components/ProfileInfo.vue'
 | 
			
		||||
import TimelineEntry from './../components/TimelineEntry.vue'
 | 
			
		||||
import axios from '@nextcloud/axios'
 | 
			
		||||
import { generateUrl } from '@nextcloud/router'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	name: 'ProfilePageIntegration',
 | 
			
		||||
	props: {
 | 
			
		||||
		userId: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: '',
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			accountInfo: null,
 | 
			
		||||
			timeline: [],
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	components: {
 | 
			
		||||
		ProfileInfo,
 | 
			
		||||
		TimelineEntry,
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		getCount() {
 | 
			
		||||
			let account = this.accountInfo
 | 
			
		||||
			return (field) => account.details.count ? account.details.count[field] : ''
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	// Start fetching account information before mounting the component
 | 
			
		||||
	beforeMount() {
 | 
			
		||||
		let fetchMethod = 'fetchPublicAccountInfo'
 | 
			
		||||
 | 
			
		||||
		let uid = this.userId
 | 
			
		||||
 | 
			
		||||
		axios.get(generateUrl(`apps/social/api/v1/account/${uid}/info`)).then((response) => {
 | 
			
		||||
			this.accountInfo = response.data.result.account
 | 
			
		||||
			console.log(this.accountInfo)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		const since = Math.floor(Date.now() / 1000) + 1
 | 
			
		||||
 | 
			
		||||
		axios.get(generateUrl(`apps/social/api/v1/account/${uid}/stream?limit=25&since=${since}`)).then(({ data }) => {
 | 
			
		||||
			console.log(this.timeline)
 | 
			
		||||
			this.timeline = data.result
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ const webpackConfig = require('@nextcloud/webpack-vue-config')
 | 
			
		|||
webpackConfig.entry = {
 | 
			
		||||
	social: path.join(__dirname, 'src', 'main.js'),
 | 
			
		||||
	ostatus: path.join(__dirname, 'src', 'ostatus.js'),
 | 
			
		||||
	profilePage: path.join(__dirname, 'src', 'profile.js'),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = webpackConfig
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue