Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add user settings #2795

Merged
merged 12 commits into from
Oct 17, 2024
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Changed

### Fixed
- First features for user settings after vue migration (#2795)

Check failure on line 12 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'vue'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'vue'?", "location": {"path": "CHANGELOG.md", "range": {"start": {"line": 12, "column": 42}}}, "severity": "ERROR"}

# Releases
## [25.0.0-alpha10] - 2024-10-14
Expand Down
5 changes: 5 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use OCA\News\Search\FolderSearchProvider;
use OCA\News\Search\ItemSearchProvider;
use OCA\News\Listeners\AddMissingIndicesListener;
use OCA\News\Listeners\UserSettingsListener;
use OCA\News\Utility\Cache;

use OCP\AppFramework\Bootstrap\IBootContext;
Expand All @@ -36,6 +37,8 @@
use OCA\News\Fetcher\FeedFetcher;
use OCA\News\Fetcher\Fetcher;
use OCP\User\Events\BeforeUserDeletedEvent;
use OCP\Config\BeforePreferenceDeletedEvent;
use OCP\Config\BeforePreferenceSetEvent;
use OCP\DB\Events\AddMissingIndicesEvent;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -91,6 +94,8 @@ public function register(IRegistrationContext $context): void

$context->registerEventListener(BeforeUserDeletedEvent::class, UserDeleteHook::class);
$context->registerEventListener(AddMissingIndicesEvent::class, AddMissingIndicesListener::class);
$context->registerEventListener(BeforePreferenceDeletedEvent::class, UserSettingsListener::class);
$context->registerEventListener(BeforePreferenceSetEvent::class, UserSettingsListener::class);

// parameters
$context->registerParameter('exploreDir', __DIR__ . '/../Explore/feeds');
Expand Down
21 changes: 20 additions & 1 deletion lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Services\IInitialState;

use OCA\News\Service\StatusService;
use OCA\News\Explore\RecommendedSites;
Expand All @@ -42,7 +43,8 @@
private IURLGenerator $urlGenerator,
private IL10N $l10n,
private RecommendedSites $recommendedSites,
private StatusService $statusService
private StatusService $statusService,
private IInitialState $initialState
) {
parent::__construct($request, $userSession);
}
Expand All @@ -60,7 +62,7 @@
if (class_exists('\OCP\ServerVersion')) {
$version = (new \OCP\ServerVersion())->getMajorVersion();
} else {
$version = Util::getVersion()[0];

Check failure on line 65 in lib/Controller/PageController.php

View workflow job for this annotation

GitHub Actions / phpstan: Nextcloud pre-release with 8.3

Call to deprecated method getVersion() of class OCP\Util: 31.0.0 Use \OCP\ServerVersion::getVersion
}

$response = new TemplateResponse(
Expand All @@ -73,6 +75,23 @@
]
);

$usersettings = [
'compact',
'compactExpand',
'preventReadOnScroll',
'oldestFirst',
'showAll'
];

foreach ($usersettings as $setting) {
$this->initialState->provideInitialState($setting, $this->config->getUserValue(
$this->getUserId(),
$this->appName,
$setting,
'0'
));
}

$csp = new ContentSecurityPolicy();
$csp->addAllowedImageDomain('*')
->addAllowedMediaDomain('*')
Expand Down
31 changes: 31 additions & 0 deletions lib/Listeners/UserSettingsListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\News\Listeners;

use OCP\Config\BeforePreferenceDeletedEvent;
use OCP\Config\BeforePreferenceSetEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;

/** @template-implements IEventListener<BeforePreferenceSetEvent|BeforePreferenceDeletedEvent> */
class UserSettingsListener implements IEventListener
{

public function handle(Event $event): void
{
if (!($event instanceof BeforePreferenceSetEvent || $event instanceof BeforePreferenceDeletedEvent)) {
return;
}

if ($event->getAppId() !== 'news') {
return;
}

$event->setValid(true);
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@nextcloud/auth": "^2.4.0",
"@nextcloud/axios": "^2.5.0",
"@nextcloud/dialogs": "^4.2.7",
"@nextcloud/event-bus": "^3.3.1",
"@nextcloud/initial-state": "^2.2.0",
"@nextcloud/l10n": "^3.1.0",
"@nextcloud/moment": "^1.3.1",
Expand Down
135 changes: 134 additions & 1 deletion src/components/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
</NcCounterBubble>
</template>
</NcAppNavigationItem>
<NcAppNavigationItem :name="t('news', 'All articles')" icon="icon-rss" :to="{ name: ROUTES.ALL }">
<NcAppNavigationItem v-if="showAll"
:name="t('news', 'All articles')"
icon="icon-rss"
:to="{ name: ROUTES.ALL }">
<template #icon>
<RssIcon />
</template>
Expand Down Expand Up @@ -111,20 +114,63 @@
</template>
</NcAppNavigationItem>
</template>
<template #footer>
<NcAppNavigationSettings :name="t('news', 'Settings')">
<NcButton @click="showHelp = true">
{{ t('news', 'Keyboard shortcuts') }}
</NcButton>
<HelpModal v-if="showHelp" @close="showHelp=false" />
<div>
<div>
<input id="toggle-preventreadonscroll"
v-model="preventReadOnScroll"
type="checkbox"
class="checkbox">
<label for="toggle-preventreadonscroll">
{{ t('news', 'Disable mark read through scrolling') }}
</label>
</div>
<div>
<input id="toggle-showall"
v-model="showAll"
type="checkbox"
class="checkbox">
<label for="toggle-showall">
{{ t('news', 'Show all articles') }}
</label>
</div>
<div>
<input id="toggle-oldestfirst"
v-model="oldestFirst"
type="checkbox"
class="checkbox">
<label for="toggle-oldestfirst">
{{ t('news', 'Reverse ordering (oldest on top)') }}
</label>
</div>
</div>
</NcAppNavigationSettings>
</template>
</NcAppNavigation>
</template>

<script lang="ts">

import { mapState } from 'vuex'
import Vue from 'vue'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { subscribe } from '@nextcloud/event-bus'

import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
import NcAppNavigationNew from '@nextcloud/vue/dist/Components/NcAppNavigationNew.js'
import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
import NcAppNavigationNewItem from '@nextcloud/vue/dist/Components/NcAppNavigationNewItem.js'
import NcAppNavigationSettings from '@nextcloud/vue/dist/Components/NcAppNavigationSettings.js'
import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'

import RssIcon from 'vue-material-design-icons/Rss.vue'
import FolderIcon from 'vue-material-design-icons/Folder.vue'
Expand All @@ -139,6 +185,7 @@ import { ACTIONS, AppState } from '../store'
import AddFeed from './AddFeed.vue'
import SidebarFeedLinkActions from './SidebarFeedLinkActions.vue'

import HelpModal from './modals/HelpModal.vue'
import { Folder } from '../types/Folder'
import { Feed } from '../types/Feed'

Expand Down Expand Up @@ -168,8 +215,10 @@ export default Vue.extend({
NcAppNavigationNew,
NcAppNavigationItem,
NcAppNavigationNewItem,
NcAppNavigationSettings,
NcCounterBubble,
NcActionButton,
NcButton,
AddFeed,
RssIcon,
FolderIcon,
Expand All @@ -178,23 +227,106 @@ export default Vue.extend({
FolderPlusIcon,
PlusIcon,
SidebarFeedLinkActions,
HelpModal,
},
data: () => {
return {
showAddFeed: false,
ROUTES,
showHelp: false,
}
},
computed: {
...mapState(['feeds', 'folders', 'items']),
...mapState(SideBarState),
compact: {
get() {
return this.$store.getters.compact
},
set(newValue) {
this.saveSetting('compact', newValue)
},
},
compactExpand: {
get() {
return this.$store.getters.compactExpand
},
set(newValue) {
this.saveSetting('compactExpand', newValue)
},
},
oldestFirst: {
get() {
return this.$store.getters.oldestFirst

},
set(newValue) {
this.saveSetting('oldestFirst', newValue)
this.$store.dispatch(ACTIONS.RESET_ITEMS)
},
},
preventReadOnScroll: {
get() {
return this.$store.getters.preventReadOnScroll

},
set(newValue) {
this.saveSetting('preventReadOnScroll', newValue)
},
},
showAll: {
get() {
return this.$store.getters.showAll

},
set(newValue) {
this.saveSetting('showAll', newValue)
},
},
},
created() {
if (this.$route.query.subscribe_to) {
this.showAddFeed = true
}
},
mounted() {
subscribe('news:global:toggle-help-dialog', () => {
this.showHelp = !this.showHelp
})
},
methods: {
async saveSetting(key, value) {
this.$store.commit(key, { value })
const url = generateOcsUrl(
'/apps/provisioning_api/api/v1/config/users/{appId}/{key}',
{
appId: 'news',
key,
},
)
value = value ? '1' : '0'
try {
const { data } = await axios.post(url, {
configValue: value,
})
this.handleResponse({
status: data.ocs?.meta?.status,
})
} catch (e) {
this.handleResponse({
errorMessage: t('news', 'Unable to update news config'),
error: e,
})
}
},
handleResponse({ status, errorMessage, error }) {
if (status !== 'ok') {
showError(errorMessage)
console.error(errorMessage, error)
} else {
showSuccess(t('news', 'Successfully updated news configuration'))
}
},
newFolder(value: string) {
const folderName = value.trim()
const folder = { name: folderName }
Expand Down Expand Up @@ -241,6 +373,7 @@ export default Vue.extend({
isFolder(item: Feed | Folder) {
return (item as Folder).name !== undefined
},

},
})

Expand Down
24 changes: 18 additions & 6 deletions src/components/feed-display/FeedItemDisplayList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,24 @@
</template>
</NcActionButton>
</NcActions>
<button v-shortkey="['arrowleft']" class="hidden" @shortkey="jumpToPreviousItem">
Prev
</button>
<button v-shortkey="['k']" class="hidden" @shortkey="jumpToPreviousItem">
Prev
</button>
<button v-shortkey="['p']" class="hidden" @shortkey="jumpToPreviousItem">
Prev
</button>
<button v-shortkey="['arrowright']" class="hidden" @shortkey="jumpToNextItem">
Next
</button>
<button v-shortkey="['j']" class="hidden" @shortkey="jumpToNextItem">
Next
</button>
<button v-shortkey="['n']" class="hidden" @shortkey="jumpToNextItem">
Next
</button>
</div>
<div class="feed-item-display-container">
<VirtualScroll ref="virtualScroll"
Expand Down Expand Up @@ -116,12 +128,12 @@ export default Vue.extend({
// Show unread items at start
filter: () => { return this.unreadFilter },

// Always want to sort by date (most recent first)
// Always want to sort by id
sort: (a: FeedItem, b: FeedItem) => {
if (a.pubDate > b.pubDate) {
return -1
if (this.$store.getters.oldestFirst) {
return a.id < b.id ? -1 : 1
} else {
return 1
return a.id > b.id ? -1 : 1
}
},
cache: [] as FeedItem[] | undefined,
Expand Down Expand Up @@ -189,8 +201,8 @@ export default Vue.extend({
fetchMore() {
this.$emit('load-more')
},
noFilter(): boolean {
return true
noFilter(item: FeedItem): boolean {
return this.$store.getters.showAll ? true : item.unread
},
starFilter(item: FeedItem): boolean {
return item.starred
Expand Down
Loading
Loading