kopia lustrzana https://github.com/nextcloud/social
Implement social app setup
Signed-off-by: Julius Härtl <jus@bitgrid.net>pull/39/head
rodzic
86e90ffef8
commit
ab1c26f69c
|
@ -42,7 +42,9 @@ return [
|
|||
['name' => 'Local#accountsSearch', 'url' => '/api/v1/accounts/search', 'verb' => 'GET'],
|
||||
['name' => 'Local#accountFollow', 'url' => '/api/v1/account/follow', 'verb' => 'PUT'],
|
||||
['name' => 'Local#accountUnfollow', 'url' => '/api/v1/account/follow', 'verb' => 'DELETE'],
|
||||
['name' => 'Local#actorInfo', 'url' => '/api/v1/actor/info', 'verb' => 'GET']
|
||||
['name' => 'Local#actorInfo', 'url' => '/api/v1/actor/info', 'verb' => 'GET'],
|
||||
|
||||
]
|
||||
['name' => 'Config#setCloudAddress', 'url' => '/api/v1/config/cloudAddress', 'verb' => 'POST'],
|
||||
|
||||
]
|
||||
];
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Controller;
|
||||
|
||||
use OCA\Activity\Data;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IRequest;
|
||||
|
||||
|
||||
class ConfigController extends Controller {
|
||||
|
||||
private $configService;
|
||||
|
||||
public function __construct(string $appName, IRequest $request, ConfigService $configService) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
$this->configService = $configService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cloudAddress
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function setCloudAddress(string $cloudAddress): DataResponse {
|
||||
try {
|
||||
$this->configService->setCloudAddress($cloudAddress);
|
||||
return new DataResponse([]);
|
||||
} catch (SocialAppConfigException $e) {
|
||||
return new DataResponse([
|
||||
'message' => $e->getMessage()
|
||||
], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -122,14 +122,24 @@ class NavigationController extends Controller {
|
|||
'serverData' => [
|
||||
'public' => false,
|
||||
'firstrun' => false,
|
||||
'setup' => false
|
||||
'setup' => false,
|
||||
]
|
||||
];
|
||||
|
||||
try {
|
||||
$this->configService->getCloudAddress();
|
||||
$data['serverData']['setup'] = true;
|
||||
$data['serverData']['cloudAddress'] = $this->configService->getCloudAddress();
|
||||
} catch (SocialAppConfigException $e) {
|
||||
$data['serverData']['setup'] = true;
|
||||
$data['serverData']['isAdmin'] = \OC::$server->getGroupManager()->isAdmin($this->userId);
|
||||
if ($data['serverData']['isAdmin']) {
|
||||
$cloudAddress = $this->request->getParam('cloudAddress');
|
||||
if ($cloudAddress !== null) {
|
||||
$this->configService->setCloudAddress($cloudAddress);
|
||||
} else {
|
||||
$data['serverData']['cliUrl'] = $this->config->getSystemValue('overwrite.cli.url', \OC::$server->getURLGenerator()->getBaseUrl());
|
||||
return new TemplateResponse(Application::APP_NAME, 'setup', $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -143,6 +153,8 @@ class NavigationController extends Controller {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display the navigation page of the Social app.
|
||||
*
|
||||
|
|
|
@ -210,6 +210,16 @@ class ConfigService {
|
|||
return $this->config->getSystemValue($key, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $host
|
||||
*
|
||||
* @return string
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function setCloudAddress(string $cloudAddress) {
|
||||
// TODO: Validate
|
||||
$this->setAppValue(self::SOCIAL_ADDRESS, $cloudAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $host
|
||||
|
|
38
src/App.vue
38
src/App.vue
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="app-social">
|
||||
<div class="app-social" v-if="!serverData.setup">
|
||||
<div v-if="!serverData.public" id="app-navigation">
|
||||
<app-navigation :menu="menu" />
|
||||
</div>
|
||||
|
@ -7,12 +7,36 @@
|
|||
<router-view :key="$route.fullPath" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="setup">
|
||||
<template v-if="serverData.isAdmin">
|
||||
<h2>{{ t('social', 'Social app setup') }}</h2>
|
||||
<p>{{ t('social', 'ActivityPub requires a fixed URL to make entries unique. Please configure a URL base. Note that this cannot be changed later without resetting the social app data.') }}</p>
|
||||
<form @submit.prevent="setCloudAddress">
|
||||
<p>
|
||||
<label class="hidden">{{ t('social', 'ActivityPub URL base') }}</label>
|
||||
<input type="url" :placeholder="serverData.cliUrl" v-model="cloudAddress" required />
|
||||
<input type="submit" :value="t('social', 'Finish setup')" class="primary" />
|
||||
</p>
|
||||
</form>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>{{ t('social', 'The social app requires to be setup by the server administrator.') }}</p>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.app-social {
|
||||
width: 100%;
|
||||
}
|
||||
.setup {
|
||||
margin: auto;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.setup input[type=url] {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
@ -22,6 +46,7 @@ import {
|
|||
Multiselect,
|
||||
Avatar
|
||||
} from 'nextcloud-vue'
|
||||
import axios from 'nextcloud-axios'
|
||||
import TimelineEntry from './components/TimelineEntry'
|
||||
import ProfileInfo from './components/ProfileInfo'
|
||||
|
||||
|
@ -38,7 +63,8 @@ export default {
|
|||
data: function() {
|
||||
return {
|
||||
infoHidden: false,
|
||||
state: []
|
||||
state: [],
|
||||
cloudAddress: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -119,7 +145,13 @@ export default {
|
|||
methods: {
|
||||
hideInfo() {
|
||||
this.infoHidden = true
|
||||
},
|
||||
setCloudAddress() {
|
||||
axios.post(OC.generateUrl('apps/social/api/v1/config/cloudAddress'), {cloudAddress: this.cloudAddress}).then((response) => {
|
||||
this.$store.commit('setServerDataEntry', 'setup', false);
|
||||
this.$store.commit('setServerDataEntry', 'cloudAddress', this.cloudAddress);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
|
@ -26,6 +26,9 @@ const state = {
|
|||
const mutations = {
|
||||
setServerData(state, data) {
|
||||
state.serverData = data
|
||||
},
|
||||
setServerDataEntry(state, key, value) {
|
||||
state.serverData[key] = value;
|
||||
}
|
||||
}
|
||||
const getters = {
|
||||
|
|
|
@ -49,8 +49,11 @@ const actions = {
|
|||
fetchTimeline(context, account) {
|
||||
const sinceTimestamp = Date.parse(state.since)/1000;
|
||||
return axios.get(OC.generateUrl('apps/social/api/v1/timeline?limit=5&since=' + sinceTimestamp)).then((response) => {
|
||||
if (response.status === -1) {
|
||||
throw response.message;
|
||||
}
|
||||
context.commit('addToTimeline', response.data.result);
|
||||
return response.data.result;
|
||||
return response.data;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,17 @@ export default {
|
|||
infiniteHandler($state) {
|
||||
this.$store.dispatch('fetchTimeline', {
|
||||
account: this.currentUser.uid
|
||||
}).then((response) => { response.length > 0 ? $state.loaded() : $state.complete() });
|
||||
}).then((response) => {
|
||||
if (response.status = -1) {
|
||||
OC.Notification.showTemporary('Failed to load more timeline entries');
|
||||
console.error('Failed to load more timeline entries', response);
|
||||
$state.complete();
|
||||
return;
|
||||
}
|
||||
response.results.length > 0 ? $state.loaded() : $state.complete()
|
||||
}).catch((error) => {
|
||||
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue