feat: add rss_enabled user setting to toggle RSS functionality

RSS is now off by default. When disabled:
- Scheduler skips RSS feed sync during compilation slot
- Briefing pipeline skips RSS item gathering
- RSS LLM tools (get_rss_items, add_rss_feed) are hidden
- API routes return empty results for feeds/news
- Frontend hides News nav link, RSS Feeds and News Preferences in settings
- Briefing view hides news sidebar section

Toggle in Settings > Briefing > RSS / News.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 13:58:50 -04:00
parent 29ef17f4f3
commit 3ac32dc3bc
9 changed files with 75 additions and 16 deletions
+4 -2
View File
@@ -5,6 +5,7 @@ import { useTheme } from "@/composables/useTheme";
import { useShortcuts } from "@/composables/useShortcuts";
import { useAuthStore } from "@/stores/auth";
import { useChatStore } from "@/stores/chat";
import { useSettingsStore } from "@/stores/settings";
import AppLogo from "@/components/AppLogo.vue";
import NotificationBell from "@/components/NotificationBell.vue";
@@ -12,6 +13,7 @@ const { theme, toggleTheme } = useTheme();
const { toggleShortcuts } = useShortcuts();
const authStore = useAuthStore();
const chatStore = useChatStore();
const settingsStore = useSettingsStore();
const router = useRouter();
const route = useRoute();
@@ -78,7 +80,7 @@ router.afterEach(() => {
<router-link to="/chat" :class="['nav-link', { 'router-link-active': isChatActive }]">Chat</router-link>
<router-link to="/briefing" class="nav-link">Briefing</router-link>
<router-link to="/calendar" class="nav-link">Calendar</router-link>
<router-link to="/news" class="nav-link">News</router-link>
<router-link v-if="settingsStore.rssEnabled" to="/news" class="nav-link">News</router-link>
<router-link to="/projects" class="nav-link">Projects</router-link>
</div>
</div>
@@ -128,7 +130,7 @@ router.afterEach(() => {
<router-link to="/briefing" class="nav-link">Briefing</router-link>
<router-link to="/calendar" class="nav-link">Calendar</router-link>
<router-link to="/projects" class="nav-link">Projects</router-link>
<router-link to="/news" class="nav-link">News</router-link>
<router-link v-if="settingsStore.rssEnabled" to="/news" class="nav-link">News</router-link>
<router-link to="/shared" class="nav-link">Shared</router-link>
<div class="mobile-divider"></div>
<router-link to="/settings" class="nav-link">Settings</router-link>
+5
View File
@@ -16,6 +16,10 @@ export const useSettingsStore = defineStore("settings", () => {
() => settings.value.default_model || ""
);
const rssEnabled = computed(
() => settings.value.rss_enabled === "true"
);
// Voice status — checked once on login, refreshable from Settings
const voiceEnabled = ref(false);
const voiceSttReady = ref(false);
@@ -62,6 +66,7 @@ export const useSettingsStore = defineStore("settings", () => {
loading,
assistantName,
defaultModel,
rssEnabled,
voiceEnabled,
voiceSttReady,
voiceTtsReady,
+3 -1
View File
@@ -2,6 +2,7 @@
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useBackgroundRefresh } from '@/composables/useBackgroundRefresh'
import { useChatStore } from '@/stores/chat'
import { useSettingsStore } from '@/stores/settings'
import ChatPanel from '@/components/ChatPanel.vue'
import WeatherCard from '@/components/WeatherCard.vue'
import BriefingSetupWizard from '@/components/BriefingSetupWizard.vue'
@@ -33,6 +34,7 @@ interface WeatherData {
}
const chatStore = useChatStore()
const settingsStore = useSettingsStore()
// Setup wizard
const showWizard = ref(false)
@@ -293,7 +295,7 @@ onMounted(async () => {
</div>
<!-- News section (scrollable) -->
<div class="news-section">
<div v-if="settingsStore.rssEnabled" class="news-section">
<div class="panel-label-row">
<div class="panel-label">Today's News</div>
<span v-if="newsItems.length" class="news-count">{{ newsItems.length }} items</span>
+22 -2
View File
@@ -387,6 +387,14 @@ async function saveBriefingSettings() {
}
}
async function toggleRss() {
try {
await store.updateSettings({ rss_enabled: store.rssEnabled ? "false" : "true" });
} catch {
toastStore.show("Failed to update RSS setting", "error");
}
}
async function addFeed() {
if (!newFeedUrl.value.trim() || addingFeed.value) return;
addingFeed.value = true;
@@ -2209,8 +2217,20 @@ function formatUserDate(iso: string): string {
</p>
</section>
<!-- RSS Feeds -->
<!-- RSS toggle -->
<section class="settings-section full-width">
<h2>RSS / News</h2>
<div class="checkbox-field">
<label>
<input type="checkbox" :checked="store.rssEnabled" @change="toggleRss" />
Enable RSS feeds
</label>
<p class="field-hint">Subscribe to RSS/Atom feeds and include news in your briefings.</p>
</div>
</section>
<!-- RSS Feeds -->
<section v-if="store.rssEnabled" class="settings-section full-width">
<div class="briefing-feeds-header">
<div>
<h2>RSS Feeds</h2>
@@ -2252,7 +2272,7 @@ function formatUserDate(iso: string): string {
</section>
<!-- News Preferences -->
<section class="settings-section full-width">
<section v-if="store.rssEnabled" class="settings-section full-width">
<h2>News Preferences</h2>
<p class="section-desc">
Tell the briefing what topics you care about. Topics are matched against