fix: Make the app navigation a second named router-view

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Ferdinand Thiessen 2023-10-30 19:10:42 +01:00
Родитель 5b9f53a039
Коммит c18aa03193
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 45FAE7268762B400
4 изменённых файлов: 84 добавлений и 94 удалений

Просмотреть файл

@ -1,76 +0,0 @@
/**
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
*
* @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/>.
*
*/
$(function() {
OCA.Activity = OCA.Activity || {};
OCA.Activity.FeedSettings = {
urlInput: null,
enableCheckbox: null,
init: function () {
this.urlInput = $('#rssurl');
this.enableCheckbox = $('#enable_rss');
this.enableCheckbox.change(_.bind(this._toggle, this));
},
_toggle: function (event) {
var self = this;
$.ajax({
url: OC.generateUrl('/apps/activity/settings/feed'),
type: 'post',
data: {
enable: event.target.checked
},
success: function(response) {
if (event.target.checked) {
self.urlInput.find('input').val(response.data.rsslink);
self.urlInput.removeClass('hidden');
} else {
self.urlInput.addClass('hidden');
self.urlInput.find('input').val(response.data.rsslink);
}
}
});
}
};
// Clipboard!
var clipboard = new Clipboard('#rssurl .icon-clippy');
clipboard.on('success', function(e) {
$input = $(e.trigger);
OC.Notification.show(t('core', 'Copied!'), {type: 'success'});
});
clipboard.on('error', function (e) {
$input = $(e.trigger);
var actionMsg = '';
if (/iPhone|iPad/i.test(navigator.userAgent)) {
actionMsg = t('core', 'Not supported!');
} else if (/Mac/i.test(navigator.userAgent)) {
actionMsg = t('core', 'Press ⌘-C to copy.');
} else {
actionMsg = t('core', 'Press Ctrl-C to copy.');
}
OC.Notification.show(actionMsg, {type: 'error'});
});
OCA.Activity.FeedSettings.init();
});

Просмотреть файл

@ -1,5 +1,28 @@
/**
* @copyright Copyright (c) 2023 Nextcloud GmbH
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* 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/>.
*
*/
import type { RouteConfig } from 'vue-router'
import ActivityFeed from './views/ActivityFeed.vue'
import ActivityAppFeed from './views/ActivityAppFeed.vue'
import ActivityAppNavigation from './views/ActivityAppNavigation.vue'
export const routes = [
{
@ -8,8 +31,13 @@ export const routes = [
redirect: { path: '/all' },
},
{
path: '/:view',
component: ActivityFeed,
props: true,
path: '/:filter',
components: {
default: ActivityAppFeed,
navigation: ActivityAppNavigation,
},
props: {
default: true,
},
},
] as RouteConfig[]

Просмотреть файл

@ -1,9 +1,9 @@
<template>
<NcContent app-name="activity">
<ActivityAppNavigation />
<router-view name="navigation" />
<NcAppContent v-if="hasNoActivity">
<NcEmptyContent style="height: 100%;"
:title="t('activity', 'No activity yet')"
:name="t('activity', 'No activity yet')"
:description="t('activity', 'This stream will show events like additions, changes & shares')">
<template #icon>
<NcIconSvgWrapper :svg="IconLogo" />
@ -15,7 +15,6 @@
</template>
<script setup lang="ts">
import ActivityAppNavigation from '../components/ActivityAppNavigation.vue'
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'

Просмотреть файл

@ -3,8 +3,6 @@
<template #list>
<NcAppNavigationItem v-for="navigationItem in navigationList"
:key="navigationItem.id"
:active="navigationItem.id === currentView"
:aria-current="navigationItem.id === currentView ? 'page' : null"
:data-navigation="navigationItem.id"
:to="navigationItem.id"
:name="navigationItem.name">
@ -18,18 +16,19 @@
</template>
<template #footer>
<NcAppNavigationSettings :name="t('activity', 'Activity settings')">
<NcCheckboxRadioSwitch :checked="hasRSSLink">
<NcCheckboxRadioSwitch type="switch" :checked="hasRSSLink" @update:checked="toggleRSSLink">
{{ t('activity', 'Enable RSS feed') }}
</NcCheckboxRadioSwitch>
<NcInputField v-if="hasRSSLink"
v-model="rssLink"
:label="t('activity', 'RSS feed')"
:show-trailing-button="true"
:trailing-button-label="t('activity', 'Copy RSS feed link')"
readonly="readonly">
readonly="readonly"
@trailing-button-click="copyRSSLink">
<template #trailing-button-icon>
<IconClipboard :size="20" />
<IconContentCopy :size="20" />
</template>
{{ rssLink }}
</NcInputField>
<NcButton class="settings-link"
:href="personalSettingsLink"
@ -43,9 +42,12 @@
</template>
<script setup lang="ts">
import axios from '@nextcloud/axios'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
import { computed } from 'vue'
import { generateUrl } from '@nextcloud/router'
import { computed, ref } from 'vue'
import {
NcAppNavigation,
@ -56,7 +58,8 @@ import {
} from '@nextcloud/vue'
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
import IconClipboard from 'vue-material-design-icons/Clipboard.vue'
import IconContentCopy from 'vue-material-design-icons/ContentCopy.vue'
import logger from '../logger'
// Types
interface INavigationEntry {
@ -74,14 +77,50 @@ interface IActivitySettings {
// Variables and methods
const {
rssLink,
rssLink: initialRSSLink,
personalSettingsLink,
} = loadState<IActivitySettings>(appName, 'settings')
const navigationList = loadState<INavigationEntry[]>(appName, 'navigationList')
const hasRSSLink = computed(() => !!rssLink)
const currentView = computed(() => 'all')
/**
* The current rss link, either a valid URL or an empty string
*/
const rssLink = ref(initialRSSLink)
/**
* True if a RSS link is configures / enabled. False otherwise.
*/
const hasRSSLink = computed(() => !!rssLink.value)
/**
* Toggle the enabled state of the RSS link
*/
async function toggleRSSLink() {
try {
const { data } = await axios.post<{ data: { rsslink: string } }>(generateUrl('/apps/activity/settings/feed'), {
enable: !hasRSSLink.value,
})
rssLink.value = data.data.rsslink
} catch (e) {
showError(t('activity', 'Could not enable RSS link'))
logger.error(e as Error)
}
}
/**
* Copy the RSS link to the clipboard
*/
async function copyRSSLink() {
try {
window.navigator.clipboard.writeText(rssLink.value)
showSuccess(t('activity', 'RSS link copied to clipboard'))
} catch (e) {
logger.debug(e as Error)
// If the user is running Nextcloud in a non secure context (secure = HTTPS or HTTP on localhost) then Clipboard API fail and the user must copy manually
window.prompt(t('activity', 'Could not copy the RSS link, please copy manually:'), rssLink.value)
}
}
</script>
<style lang="scss">