### Define Initial Setup Request Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Schema for the initial admin user setup request body. ```typescript InitialSetupRequest { name: string // admin username password: string // admin password email?: string // admin email } ``` -------------------------------- ### client.user.initialSetup Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Performs initial server setup by creating an admin user. ```APIDOC ## initialSetup(req: InitialSetupRequest) ### Description Perform initial server setup (creates admin user). ### Parameters - **req.name** (string) - Required - Admin username - **req.password** (string) - Required - Admin password - **req.email** (string) - Optional - Admin email ### Example ```typescript await client.user.initialSetup({ name: "admin", password: "adminpass", email: "admin@example.com" }) ``` ``` -------------------------------- ### GET /server/get Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves server information and capabilities. ```APIDOC ## GET /server/get ### Description Get server information and capabilities. ### Method GET ### Endpoint /server/get ### Response #### Success Response (200) - **announcement** (string) - Optional - **version** (string) - Required - **gitCommit** (string) - Required - **allowRegistrations** (boolean) - Required - **emailAddressRequired** (boolean) - Required - **smtpEnabled** (boolean) - Required - **demoAccountEnabled** (boolean) - Required - **websocketEnabled** (boolean) - Required - **websocketPingInterval** (number) - Required - **treeReloadInterval** (number) - Required - **forceRefreshCooldownDuration** (number) - Required - **initialSetupRequired** (boolean) - Required - **minimumPasswordLength** (number) - Required - **pushNotificationsEnabled** (boolean) - Required ``` -------------------------------- ### Perform initial server setup Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Creates the initial admin user for the server instance. ```typescript await client.user.initialSetup({ name: "admin", password: "adminpass", email: "admin@example.com" }) ``` -------------------------------- ### POST /user/initialSetup Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Creates the initial admin user account if the system setup is required. ```APIDOC ## POST /user/initialSetup ### Description Create admin user for initial setup. ### Method POST ### Endpoint /rest/user/initialSetup ### Request Body - **name** (string) - Required - admin username - **password** (string) - Required - admin password - **email** (string) - Optional - admin email ### Response #### Success Response (204) - No content #### Error Responses - 400: Setup already completed ``` -------------------------------- ### Initialize CommaFeed Development Environment Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Commands to start the Quarkus backend and the frontend development server. ```bash # Backend cd commafeed-server ./mvnw quarkus:dev # Frontend cd commafeed-client npm install npm run dev ``` -------------------------------- ### Define InitialSetupRequest interface Source: https://github.com/athou/commafeed/blob/master/_autodocs/02-types.md Used for the initial server setup process to create the admin user account. ```typescript interface InitialSetupRequest { name: string password: string email?: string } ``` -------------------------------- ### useAppLoading Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Shows how to use the hook to display a global progress bar during async operations. ```typescript import { useAppLoading } from "@/hooks/useAppLoading" export function AppLayout() { const isLoading = useAppLoading() return (
{isLoading && }
{/* Main content */}
) } ``` -------------------------------- ### Extended Custom CSS Example for CommaFeed Source: https://github.com/athou/commafeed/blob/master/documentation/CUSTOMCSS.md A comprehensive example demonstrating various CSS customizations for CommaFeed, including general styling, header, sidebar, and feed entry modifications. This snippet illustrates direct class styling and complex selector rules. ```css /* GENERAL (changes applied to everything) */ main {font-size: 14px; font-family: sans-serif; line-height: 1.35; padding-top: calc(1rem * 2.5) !important;} /* Don't force font-size on blockquotes and make them italic */ blockquote {font-size: unset !important; font-style: italic;} /* Make all the button icons black */ header svg {stroke: black !important; } main > svg {stroke: black !important; } /* Make links in articles light blue with a hover underline */ article a:not([class]) { color:#428bca; text-decoration:none; } article a:not([class]):hover { text-decoration:underline; } /* Make HTML headers the (same) reasonable size */ h3 {font-size: 16px !important;} h2 {font-size: 16px !important;} h1 {font-size: 16px !important;} /* Make buttons actual size */ main > button {min-width: unset !important; min-height: unset !important;} ``` ```css /* HEADER (tool bar at the top of the page) */ /* Make the header more compact */ header > div > div {padding-bottom: 0 !important; padding-top: 0 !important;} /* Let the toolbar pull to the left */ .cf-toolbar-wrapper {justify-content: unset !important;} /* Minimize height of the toolbar */ header {height: unset !important;} /* Move buttons closer together */ header img {width: calc(1rem) !important;} /* No button labels, even if there's room. */ .cf-toolbar-wrapper .mantine-Button-label {display: none;} ``` ```css /* SIDEBAR (where the feeds are listed) */ /* Specific font and layout changes for the entire sidebar */ .cf-tree {font-size: 14px; font-weight: 700; font-family: sans-serif; line-height: 150%; top: 30px !important;} .cf-treenode {margin-right: 0} /* Make unread category names black */ .cf-treenode-category {color: black !important;} /* Remove the favicons for the feeds in the sidebar */ .cf-treenode-icon {display: none;} /* Make the unread counts lighter, gray and in parens */ .cf-badge {display: flex; font-weight: 300; color: gray; background-color: unset; align-items: unset;} .cf-badge::before {content: "(";} .cf-badge::after {content: ")";} ``` ```css /* FEED ENTRIES */ /* Only changes Detailed and Expanded display */ /* Remove subtitle and details in feed entries, just leaving the title */ .cf-header-subtitle {display: none;} .cf-header-details {display: none;} /* Remove the divider and button bar at the bottom of feed entries */ .cf-footer-divider {display: none;} .cf-footer {display: none;} ``` ```css /* MISCELLANEOUS */ /* An example of changing the content: Add an extra space before the submitted line on Reddit feed entries. */ article span > div::after {content: "\A"; white-space: pre;} ``` -------------------------------- ### Get Server Information Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Retrieves server configuration, versioning, and feature availability. ```typescript const response = await client.server.getServerInfos() const serverInfo = response.data if (serverInfo.allowRegistrations) { // show registration option } ``` -------------------------------- ### Get Settings Async Thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Fetches user settings from the server. ```typescript export const getSettings = createAsyncThunk( 'user/getSettings', async (_, { rejectWithValue }) => Settings ) ``` ```typescript dispatch(getSettings()) ``` -------------------------------- ### MariaDB JDBC URL Configuration Source: https://github.com/athou/commafeed/blob/master/commafeed-server/src/main/docker/README.md Example JDBC URL for configuring CommaFeed to use a MariaDB database. Verify that the connection details match your MariaDB setup. ```text QUARKUS_DATASOURCE_JDBC_URL=jdbc:mariadb://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC ``` -------------------------------- ### Define production-specific properties Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Example configuration for an application-prod.properties file to override default settings. ```properties commafeed.hide-from-web-crawlers=true commafeed.http-client.block-local-addresses=true commafeed.users.allow-registrations=false quarkus.log.level=WARN ``` -------------------------------- ### View configuration validation warnings Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Example of a warning log generated when an invalid configuration option is detected at startup. ```text WARN: Unknown configuration option 'commafeed.invalid-option' ``` -------------------------------- ### Configure Database JDBC URLs Source: https://github.com/athou/commafeed/blob/master/README.md Examples of JDBC connection strings for various supported database systems. ```properties jdbc:h2:./data/db;DEFRAG_ALWAYS=TRUE ``` ```properties jdbc:postgresql://localhost:5432/commafeed ``` ```properties jdbc:mysql://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC ``` ```properties jdbc:mariadb://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC ``` -------------------------------- ### useColorScheme Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Demonstrates applying theme-specific styles based on the current color scheme. ```typescript import { useColorScheme } from "@/hooks/useColorScheme" export function ThemedComponent() { const colorScheme = useColorScheme() return (
Current theme: {colorScheme}
) } ``` -------------------------------- ### Registration Form Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Demonstrates integrating useValidationRules with Mantine form. ```typescript import { useValidationRules } from "@/hooks/useValidationRules" import { useForm } from "@mantine/form" export function RegistrationForm() { const rules = useValidationRules() const form = useForm({ initialValues: { username: "", email: "", password: "", }, validate: { username: rules.username, email: rules.email, password: rules.password, }, }) return (
) } ``` -------------------------------- ### GET /admin/user/getAll Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves a list of all users registered in the system. ```APIDOC ## GET /admin/user/getAll ### Description Get list of all users. ### Method GET ### Endpoint /rest/admin/user/getAll ### Response #### Success Response (200) - **UserModel[]** (array) - Array of users ``` -------------------------------- ### Get all users Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves a list of all users registered in the system. ```typescript UserModel[] // array of users ``` -------------------------------- ### Feed entry filter DSL example Source: https://github.com/athou/commafeed/blob/master/_autodocs/07-backend-services.md Demonstrates the query DSL syntax used for defining entry filtering rules. ```text title contains "tech" AND (author = "John" OR starred = true) ``` -------------------------------- ### GET /user/settings Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves the current user's settings and preferences. ```APIDOC ## GET /user/settings ### Description Retrieve user settings and preferences. ### Method GET ### Endpoint /rest/user/settings ### Response #### Success Response (200) - **settings** (object) - User settings object containing language, reading preferences, and notification settings. ``` -------------------------------- ### useWebSocket Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Basic implementation of the useWebSocket hook within a React component. ```typescript import { useWebSocket } from "@/hooks/useWebSocket" export function App() { useWebSocket() return (
{/* App content */}
) } ``` -------------------------------- ### GET /admin/metrics Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves current server performance metrics. ```APIDOC ## GET /admin/metrics ### Description Get server performance metrics. ### Method GET ### Endpoint /rest/admin/metrics ### Response #### Success Response (200) - **counters** (Record) - Metric counters - **gauges** (Record) - Metric gauges - **meters** (Record) - Metric meters - **timers** (Record) - Metric timers ``` -------------------------------- ### Dispatch getServerInfos thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Usage example for triggering the server info fetch. ```typescript dispatch(getServerInfos()) ``` -------------------------------- ### Implement useMousetrap Hook Usage Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Examples of registering various keyboard shortcuts including single keys, modifiers, and sequences. ```typescript import { useMousetrap } from "@/hooks/useMousetrap" export function AppNavigationShortcuts() { const dispatch = useAppDispatch() // Single key shortcut useMousetrap('j', () => { dispatch(selectNextEntry()) }) // Modifier key combination useMousetrap('shift+u', () => { dispatch(markAllAsRead()) }) // Keyboard sequence useMousetrap('g a', () => { dispatch(navigateToAll()) }) // Save action with Ctrl/Cmd compatibility useMousetrap('ctrl+s cmd+s', () => { dispatch(saveSettings()) }) return null // Shortcut-only component } ``` -------------------------------- ### useBrowserExtension Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Demonstrates how to use the hook to conditionally render a subscription alert based on extension state. ```typescript import { useBrowserExtension } from "@/hooks/useBrowserExtension" import { client } from "@/app/client" export function QuickSubscribe() { const { installed, subscribedFeed } = useBrowserExtension() const dispatch = useAppDispatch() if (!installed || !subscribedFeed) { return null } const handleSubscribe = async () => { await dispatch(subscribe({ url: subscribedFeed.url, title: subscribedFeed.title, })) } return ( Subscribe to {subscribedFeed.title}? ) } ``` -------------------------------- ### Configure CommaFeed via Environment Variables Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Set these variables to define database connections, refresh intervals, security keys, and notification settings. These settings are typically applied in the shell environment before starting the application. ```bash # Database export QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://localhost/commafeed export QUARKUS_DATASOURCE_USERNAME=commafeed export QUARKUS_DATASOURCE_PASSWORD=secretpassword # Feed refresh export COMMAFEED_FEED_REFRESH_INTERVAL=20m export COMMAFEED_FEED_REFRESH_HTTP_THREADS=5 # Security export QUARKUS_HTTP_AUTH_SESSION_ENCRYPTION_KEY=mysecurekey16 # WebSocket export COMMAFEED_WEBSOCKET_ENABLED=true # Push notifications export COMMAFEED_PUSH_NOTIFICATIONS_NTFY_SERVER_URL=https://ntfy.sh ``` -------------------------------- ### Get Profile Async Thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Fetches the user profile from the server. ```typescript export const getProfile = createAsyncThunk( 'user/getProfile', async (_, { rejectWithValue }) => UserModel ) ``` ```typescript dispatch(getProfile()) ``` -------------------------------- ### Get Entries Async Thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Fetches entries from a feed or category. ```typescript export const getEntries = createAsyncThunk( 'entries/getEntries', async ( req: GetEntriesPaginatedRequest, { rejectWithValue } ) => Entries ) ``` ```typescript dispatch(getEntries({ id: "5", offset: 0, limit: 20, readType: "unread", order: "desc" })) ``` -------------------------------- ### WebSocket Message Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/08-architecture.md Format for real-time notifications sent over the WebSocket endpoint. ```text new-feed-entries:42:5 ``` -------------------------------- ### GET /user/profile Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves the profile information for the authenticated user. ```APIDOC ## GET /user/profile ### Description Get user profile information. ### Method GET ### Endpoint /rest/user/profile ### Response #### Success Response (200) - **userModel** (object) - User profile details including ID, name, email, and account status. ``` -------------------------------- ### Implement common selector patterns Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Examples of using useAppSelector to retrieve state slices, including performance optimization with shallowEqual. ```typescript // From component import { useAppSelector } from "@/app/store" // Get user profile const user = useAppSelector(state => state.user.user) // Get entries const entries = useAppSelector(state => state.entries.entries) // Get category tree const root = useAppSelector(state => state.tree.root) // Get server info const serverInfo = useAppSelector(state => state.server.serverInfos) // Get with shallow equality comparison (performance optimization) const localSettings = useAppSelector( state => state.user.localSettings, shallowEqual ) ``` -------------------------------- ### Dispatch setRedirect action Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Usage example for setting a redirect target. ```typescript dispatch(setRedirect("/app")) ``` -------------------------------- ### useActionButton Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Demonstrates how to use the useActionButton hook to manage a delete feed action with loading and error states. ```typescript import { useActionButton } from "@/hooks/useActionButton" import { client } from "@/app/client" export function DeleteFeedButton({ feedId }) { const { loading, error, execute, reset } = useActionButton( () => client.feed.unsubscribe({ id: feedId }) ) return (
{error && ( {error.message} )}
) } ``` -------------------------------- ### useBrowserExtension() Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md A hook that detects and communicates with the CommaFeed browser extension to retrieve installation status and feed information. ```APIDOC ## useBrowserExtension() ### Description Detects and communicates with the CommaFeed browser extension. ### Signature `export const useBrowserExtension = (): BrowserExtensionState` ### Returns - **installed** (boolean) - Whether extension is installed - **version** (string, optional) - Extension version if installed - **subscribedFeed** (object, optional) - Feed URL and title from extension context menu ### Usage Example ```typescript import { useBrowserExtension } from "@/hooks/useBrowserExtension" export function QuickSubscribe() { const { installed, subscribedFeed } = useBrowserExtension(); // ... } ``` ``` -------------------------------- ### Run CommaFeed with H2 Database (Docker) Source: https://github.com/athou/commafeed/blob/master/commafeed-server/src/main/docker/README.md Starts CommaFeed using a Docker container with an embedded H2 database. The application will be accessible at http://localhost:8082/. Ensure the data volume is correctly mapped. ```bash docker run --name commafeed --detach --publish 8082:8082 --restart unless-stopped --volume /path/to/commafeed/data:/commafeed/data --memory 256M athou/commafeed:latest-h2 ``` -------------------------------- ### useNow Usage Example Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Displays a relative time string that updates based on the current timestamp provided by the hook. ```typescript import { useNow } from "@/hooks/useNow" import dayjs from "dayjs" export function RelativeDateDisplay() { const now = useNow() const formatRelativeTime = (timestamp: number) => { return dayjs(timestamp).from(dayjs(now)) } return (
Article published {formatRelativeTime(articleTime)}
) } ``` -------------------------------- ### Dispatch clearRedirect action Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Usage example for clearing the redirect target. ```typescript dispatch(clearRedirect()) ``` -------------------------------- ### Style Feed Entry Headers Source: https://github.com/athou/commafeed/blob/master/documentation/CUSTOMCSS.md Use the .cf-header class to select and style feed entry headers. This example changes the background color. ```css .cf-header { background-color: lightblue; } ``` -------------------------------- ### MySQL JDBC URL Configuration Source: https://github.com/athou/commafeed/blob/master/commafeed-server/src/main/docker/README.md Example JDBC URL for configuring CommaFeed to use a MySQL database. Ensure the connection parameters are correctly set for your MySQL instance. ```text QUARKUS_DATASOURCE_JDBC_URL=jdbc:mysql://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC ``` -------------------------------- ### Get server metrics Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves performance metrics including counters, gauges, meters, and timers. ```typescript Metrics { counters: Record gauges: Record meters: Record timers: Record } ``` -------------------------------- ### FeedRefreshEngine Interface Source: https://github.com/athou/commafeed/blob/master/_autodocs/07-backend-services.md Coordinates the background feed refresh process with start and stop methods. ```java public class FeedRefreshEngine { public void start() // Start refresh background threads public void stop() // Stop threads gracefully } ``` -------------------------------- ### GET /feed/entries Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves entries from a specific feed. ```APIDOC ## GET /feed/entries ### Description Get entries from a feed. ### Method GET ### Endpoint /rest/feed/entries ### Response #### Success Response (200) - **Entries** (object) - Feed entries ``` -------------------------------- ### Implement useMobile Hook Usage Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Example of using the useMobile hook to conditionally render components based on device type. ```typescript import { useMobile } from "@/hooks/useMobile" export function MyComponent() { const isMobile = useMobile() return (
{isMobile ? ( ) : ( )}
) } ``` -------------------------------- ### Server Information Response Structure Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Defines the schema for the GET /server/get endpoint, providing server capabilities and configuration settings. ```typescript ServerInfo { announcement?: string version: string gitCommit: string allowRegistrations: boolean emailAddressRequired: boolean smtpEnabled: boolean demoAccountEnabled: boolean websocketEnabled: boolean websocketPingInterval: number treeReloadInterval: number forceRefreshCooldownDuration: number initialSetupRequired: boolean minimumPasswordLength: number pushNotificationsEnabled: boolean } ``` -------------------------------- ### Handling login errors Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Example usage of errorToStrings within a try-catch block to process and log error messages from the login client method. ```typescript try { await client.user.login(credentials) } catch (error) { const messages = errorToStrings(error) messages.forEach(msg => console.error(msg)) } ``` -------------------------------- ### Build CommaFeed from source Source: https://github.com/athou/commafeed/blob/master/README.md Use the Maven wrapper to compile the project with specific database and native profile configurations. ```bash ./mvnw clean package [-P [-Pnative]] [-DskipTests] ``` -------------------------------- ### Typical Service Usage with Dependency Injection Source: https://github.com/athou/commafeed/blob/master/_autodocs/07-backend-services.md Demonstrates constructor-based dependency injection in a singleton-scoped REST resource. ```java @Path("/rest/user") @Singleton public class UserREST { private final UserService userService; private final UserDAO userDAO; @Inject UserREST(UserService userService, UserDAO userDAO) { this.userService = userService; this.userDAO = userDAO; } public void register(RegistrationRequest req) { User user = userService.findOrCreate(req.getName()); user.setPassword(req.getPassword()); userDAO.save(user); } } ``` -------------------------------- ### GET /feed/refreshAll Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Triggers a refresh of all feeds for the current user. ```APIDOC ## GET /feed/refreshAll ### Description Trigger refresh of all feeds for current user. ### Method GET ### Endpoint /rest/feed/refreshAll ### Response #### Success Response (204) - No content ``` -------------------------------- ### Implement a Custom Service in Java Source: https://github.com/athou/commafeed/blob/master/_autodocs/08-architecture.md Extend domain logic by creating a singleton service with injected dependencies. ```java @Singleton public class MyService { // Injected dependencies private final UserDAO userDAO; private final FeedEntryService feedEntryService; // Custom business logic } ``` -------------------------------- ### GET /entry/tags Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieve all tags associated with the user's entries. ```APIDOC ## GET /entry/tags ### Description Get all tags used in user's entries. ### Method GET ### Endpoint /rest/entry/tags ### Response #### Success Response (200) - **tags** (string[]) - Array of tag strings ``` -------------------------------- ### client.user.register Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Creates a new user account. ```APIDOC ## register(req: RegistrationRequest) ### Description Create a new user account. ### Parameters - **req.name** (string) - Required - Username - **req.password** (string) - Required - Password - **req.email** (string) - Required - Email address ### Example ```typescript await client.user.register({ name: "newuser", password: "secure123", email: "user@example.com" }) ``` ``` -------------------------------- ### getServerInfos() Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Retrieves the server configuration and capabilities. ```APIDOC ## getServerInfos() ### Description Retrieves the server configuration and capabilities. ### Signature `getServerInfos(): Promise>` ### Example ```typescript const response = await client.server.getServerInfos() const serverInfo = response.data if (serverInfo.allowRegistrations) { // show registration option } ``` ``` -------------------------------- ### Select Database Backend via Maven Profiles Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Specify the target database during the build process using Maven profiles. H2 is the default if no profile is specified. ```bash ./mvnw clean package -Ph2 # H2 (default) ./mvnw clean package -Ppostgresql ./mvnw clean package -Pmysql ./mvnw clean package -Pmariadb ``` -------------------------------- ### Configure CommaFeed with .env Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Use a .env file in the working directory to define database credentials and application settings. ```properties # .env file in working directory QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://localhost/commafeed QUARKUS_DATASOURCE_USERNAME=commafeed QUARKUS_DATASOURCE_PASSWORD=secretpassword COMMAFEED_HIDE_FROM_WEB_CRAWLERS=true COMMAFEED_WEBSOCKET_ENABLED=true QUARKUS_HTTP_AUTH_SESSION_ENCRYPTION_KEY=mystrongkey16 ``` -------------------------------- ### Get feed entries Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Retrieves a paginated list of entries from a specific feed. ```typescript const response = await client.feed.getEntries({ id: "42", offset: 0, limit: 20, readType: "unread" }) ``` -------------------------------- ### Configure Database Credentials Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Sets the username and password for database authentication. ```properties quarkus.datasource.username=commafeed ``` ```properties quarkus.datasource.password=secretpassword ``` -------------------------------- ### GET /feed/get/{id} Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves the details of a specific feed subscription by its ID. ```APIDOC ## GET /feed/get/{id} ### Description Get feed subscription details. ### Method GET ### Endpoint /rest/feed/get/{id} ### Parameters #### Path Parameters - **id** (string) - Required - Feed subscription ID ### Response #### Success Response (200) - **Subscription** (object) - Subscription details object ``` -------------------------------- ### client.user.getSettings Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Retrieves the current user's settings and preferences. ```APIDOC ## getSettings() ### Description Retrieve user settings and preferences. ### Example ```typescript const response = await client.user.getSettings() const settings = response.data ``` ``` -------------------------------- ### Dispatch setWebSocketConnected action Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Usage example for updating the WebSocket connection status. ```typescript dispatch(setWebSocketConnected(true)) ``` -------------------------------- ### Register a new user account Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Creates a new user account with the provided credentials and email. ```typescript await client.user.register({ name: "newuser", password: "secure123", email: "user@example.com" }) ``` -------------------------------- ### Get feed subscription details Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Retrieves subscription details for a specific feed ID. ```typescript const response = await client.feed.get("42") const subscription = response.data ``` -------------------------------- ### GET /rest/category/entries Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves entries from a specific category, supporting pagination, filtering, and sorting. ```APIDOC ## GET /rest/category/entries ### Description Get entries from a category. Authentication is required (ROLE_USER). ### Method GET ### Endpoint /rest/category/entries ### Parameters #### Query Parameters - **id** (string) - Required - Category ID, 'all', or 'starred' - **readType** (ReadingMode) - Optional - 'all' or 'unread' (default: unread) - **newerThan** (number) - Optional - Only entries newer than this (ms) - **offset** (number) - Optional - Pagination offset (default: 0) - **limit** (number) - Optional - Pagination limit (max 1000) (default: 20) - **order** (ReadingOrder) - Optional - 'asc' or 'desc' (default: desc) - **keywords** (string) - Optional - Space-separated search terms - **excludedSubscriptionIds** (string) - Optional - Comma-separated feed IDs to exclude - **tag** (string) - Optional - Filter by tag ### Response #### Success Response (200) - **name** (string) - category name - **message** (string) - error message - **errorCount** (number) - fetch error count - **feedLink** (string) - website URL (if category is single feed) - **timestamp** (number) - response time (ms) - **hasMore** (boolean) - more entries available - **offset** (number) - actual offset used - **limit** (number) - actual limit used - **entries** (Entry[]) - array of entries - **ignoredReadStatus** (boolean) - true if read status was ignored ``` -------------------------------- ### Run CommaFeed with a specific profile Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Specify a profile at runtime to load corresponding application properties files. ```bash # Run with 'prod' profile java -Dquarkus.profile=prod -jar quarkus-run.jar # This loads both: # - config/application.properties # - config/application-prod.properties ``` -------------------------------- ### Configure JVM Memory and GC Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md JVM arguments for heap size and garbage collection, along with cache reduction for memory management. ```bash -Xmx512m -XX:+UseG1GC ``` ```properties commafeed.http-client.cache.maximum-memory-size=5M ``` -------------------------------- ### Define Initial Local Settings Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Sets the default values for local browser-specific user settings. ```typescript const initialLocalSettings: LocalSettings = { viewMode: "detailed", sidebarWidth: 320, announcementHash: "", fontSizePercentage: 100, } ``` -------------------------------- ### Configure Redux Store Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Initializes the Redux store with slice reducers and preloaded local settings. ```typescript export const store = configureStore({ reducer: { entries: entriesSlice.reducer, redirect: redirectSlice.reducer, tree: treeSlice.reducer, server: serverSlice.reducer, user: userSlice.reducer, }, preloadedState: { user: { localSettings: loadLocalSettings(), }, }, }) ``` -------------------------------- ### Get all user tags Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Retrieves an array of all tags currently used in the user's entries. ```typescript string[] // array of tag strings ``` -------------------------------- ### Enable WebSocket Support Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Configuration property to enable WebSocket functionality. ```properties commafeed.websocket.enabled=true ``` -------------------------------- ### Configure CommaFeed via Environment Variables Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Map configuration keys to environment variables by converting dots to underscores, using uppercase, and replacing hyphens with underscores. ```bash # Web configuration export COMMAFEED_HIDE_FROM_WEB_CRAWLERS=true export COMMAFEED_IMAGE_PROXY_ENABLED=false # Database export QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://db:5432/commafeed export QUARKUS_DATASOURCE_USERNAME=commafeed export QUARKUS_DATASOURCE_PASSWORD=secretpassword # HTTP client export COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE=10M export COMMAFEED_HTTP_CLIENT_CACHE_ENABLED=true # Feed refresh export COMMAFEED_FEED_REFRESH_INTERVAL=20m export COMMAFEED_FEED_REFRESH_HTTP_THREADS=4 ``` -------------------------------- ### Get current timestamp in TypeScript Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Use this to generate a Unix epoch timestamp in milliseconds for API requests. ```typescript const timestamp = Date.now() // milliseconds ``` -------------------------------- ### Register Async Thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Creates a new user account. ```typescript export const register = createAsyncThunk( 'user/register', async (req: RegistrationRequest, { rejectWithValue }) => void ) ``` ```typescript dispatch(register({ name: "newuser", password: "secure123", email: "user@example.com" })) ``` -------------------------------- ### Define Settings Interface Source: https://github.com/athou/commafeed/blob/master/_autodocs/02-types.md Represents the complete user configuration and preferences object. ```typescript interface Settings { language?: string readingMode: ReadingMode readingOrder: ReadingOrder showRead: boolean scrollMarks: boolean customCss?: string customJs?: string scrollSpeed: number scrollMode: ScrollMode entriesToKeepOnTopWhenScrolling: number starIconDisplayMode: IconDisplayMode externalLinkIconDisplayMode: IconDisplayMode markAllAsReadConfirmation: boolean markAllAsReadNavigateToNextUnread: boolean customContextMenu: boolean mobileFooter: boolean unreadCountTitle: boolean unreadCountFavicon: boolean disablePullToRefresh: boolean primaryColor?: string sharingSettings: SharingSettings pushNotificationSettings: PushNotificationSettings } ``` -------------------------------- ### UserService Methods Source: https://github.com/athou/commafeed/blob/master/_autodocs/07-backend-services.md Methods for managing user accounts, including creation, password updates, and account deletion. ```java public User findOrCreate(String username) ``` ```java public void changePassword(User user, String newPassword) ``` ```java public void deleteAccount(User user) ``` -------------------------------- ### Configure CommaFeed via application.properties Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Use this file to define core application settings including database connections, feed refresh intervals, and security parameters. ```properties # Web configuration commafeed.hide-from-web-crawlers=true commafeed.announcement=Welcome to our CommaFeed instance # HTTP client commafeed.http-client.max-response-size=10M commafeed.http-client.block-local-addresses=true commafeed.http-client.cache.enabled=true commafeed.http-client.cache.maximum-memory-size=20M # Feed refresh commafeed.feed-refresh.interval=15m commafeed.feed-refresh.max-interval=6h commafeed.feed-refresh.http-threads=5 commafeed.feed-refresh.interval-empirical=true # Error handling commafeed.feed-refresh.errors.initial-backoff=2m commafeed.feed-refresh.errors.max-backoff=2h # Push notifications commafeed.push-notifications.ntfy.server-url=https://ntfy.sh # Database (PostgreSQL) quarkus.datasource.jdbc.url=jdbc:postgresql://db.example.com:5432/commafeed quarkus.datasource.username=commafeed quarkus.datasource.password=secretpassword # Users commafeed.users.allow-registrations=false commafeed.users.email-required=true commafeed.users.demo-account-enabled=false # WebSocket commafeed.websocket.enabled=true commafeed.websocket.ping-interval=30s # Session encryption (prevents logout on restart) quarkus.http.auth.session.encryption-key=mystrongencryptionkey16 # Server quarkus.http.port=8082 quarkus.http.host=0.0.0.0 quarkus.log.level=INFO ``` -------------------------------- ### Configure Gotify Server URL Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Sets the base URL for the Gotify push notification service. ```properties commafeed.push-notifications.gotify.server-url=https://gotify.example.com ``` -------------------------------- ### Implement Local Settings Persistence Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Loads settings from localStorage on initialization and subscribes to store updates to persist changes. ```typescript const loadLocalSettings = (): LocalSettings => { const json = localStorage.getItem("commafeed-local-settings") return { ...initialLocalSettings, ...(json ? JSON.parse(json) : {}), } } store.subscribe(() => { const localSettings = store.getState().user.localSettings localStorage.setItem("commafeed-local-settings", JSON.stringify(localSettings)) }) ``` -------------------------------- ### Configure Security Settings Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Application properties for session encryption, user registration, SSRF protection, and web crawler visibility. ```properties quarkus.http.auth.session.encryption-key=... commafeed.users.allow-registrations=false commafeed.http-client.block-local-addresses=true commafeed.hide-from-web-crawlers=true ``` -------------------------------- ### Configure Dynamic JVM Memory Sizing Source: https://github.com/athou/commafeed/blob/master/README.md Parameters to optimize memory release to the operating system for the JVM. ```bash -Xms20m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:-ShrinkHeapInSteps -XX:G1PeriodicGCInterval=10000 -XX:-G1PeriodicGCInvokesConcurrent -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 ``` -------------------------------- ### Configure Google Auth Key Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Provides the API key required for fetching YouTube channel favicons. ```properties commafeed.google-auth-key=AIzaSyD... ``` -------------------------------- ### client.feed.importOpml(req: File) Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Imports feeds into the user's account from an OPML file. ```APIDOC ## client.feed.importOpml(req: File) ### Description Import feeds from OPML file. ### Parameters - **req** (File) - Required - OPML file object ### Example ```typescript const fileInput = document.querySelector('input[type="file"]') await client.feed.importOpml(fileInput.files[0]) ``` ``` -------------------------------- ### Theme Configuration Access Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md Shows how primary color settings are retrieved from the application state. ```typescript const settings = useAppSelector(state => state.user.settings) // settings.primaryColor can be customized ``` -------------------------------- ### client.user.login Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Authenticates a user with a username and password. ```APIDOC ## login(req: LoginRequest) ### Description Authenticate user with username and password. ### Parameters - **req.name** (string) - Required - Username - **req.password** (string) - Required - Password ### Example ```typescript await client.user.login({ name: "john", password: "secret123" }) ``` ``` -------------------------------- ### POST /user/register Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Creates a new user account if registrations are enabled. ```APIDOC ## POST /user/register ### Description Create a new user account. ### Method POST ### Endpoint /rest/user/register ### Request Body - **name** (string) - Required - username - **password** (string) - Required - password - **email** (string) - Required - email ### Response #### Success Response (204) - No content #### Error Responses - 400: Registration disabled or validation failure - 409: Username already exists ``` -------------------------------- ### Configure Quarkus Logging Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Set log levels and enable file-based logging for the application. ```properties # Log level quarkus.log.level=INFO quarkus.log.file.level=DEBUG # File logging quarkus.log.file.enable=true quarkus.log.file.path=logs/commafeed.log ``` -------------------------------- ### useMousetrap(keyPattern, callback, action) Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md A hook to register keyboard shortcuts using the Mousetrap library, with automatic cleanup on unmount. ```APIDOC ## useMousetrap(keyPattern, callback, action) ### Description Registers keyboard shortcuts that trigger a callback function. The hook automatically cleans up bindings when the component unmounts. ### Signature `const useMousetrap = (keyPattern: string, callback: () => void, action?: 'keyup' | 'keydown' | 'keypress'): void` ### Parameters - **keyPattern** (string) - Required - The keyboard shortcut pattern (e.g., 'ctrl+s', 'j', 'g i'). - **callback** (function) - Required - The function to execute when the shortcut is triggered. - **action** (string) - Optional - The keyboard event type ('keyup', 'keydown', or 'keypress'). Defaults to 'keydown'. ``` -------------------------------- ### useAppLoading() Source: https://github.com/athou/commafeed/blob/master/_autodocs/06-react-hooks.md A hook that provides the application-level loading state from the Redux store. ```APIDOC ## useAppLoading() ### Description Provides application-level loading state from Redux. ### Signature `export const useAppLoading = (): boolean` ### Returns - **boolean** - Returns `true` if any critical async operation is in progress. ### Usage Example ```typescript import { useAppLoading } from "@/hooks/useAppLoading" export function AppLayout() { const isLoading = useAppLoading(); // ... } ``` ``` -------------------------------- ### Configure User Agent Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Sets a custom User-Agent string for outgoing HTTP requests. ```properties commafeed.http-client.user-agent=CommaFeed/1.0 ``` -------------------------------- ### Configure Server-Side Performance Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Settings for adjusting thread counts, timeouts, and cache sizes in the application configuration. ```properties commafeed.feed-refresh.http-threads=10 commafeed.feed-refresh.database-threads=2 commafeed.http-client.response-timeout=30s commafeed.http-client.cache.maximum-memory-size=50M ``` -------------------------------- ### Configure robots.txt visibility Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Set to false to allow web crawlers and search engine indexers to access the site. ```properties commafeed.hide-from-web-crawlers=false ``` -------------------------------- ### POST /feed/import Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Imports feeds from an OPML file. ```APIDOC ## POST /feed/import ### Description Import feeds from OPML file. ### Method POST ### Endpoint /rest/feed/import ### Parameters #### Form Parameters - **file** (File) - Required - OPML file ### Response #### Success Response (204) - No content ``` -------------------------------- ### client.user.getSettings / client.user.saveSettings Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md Retrieves or updates the current user's application settings. ```APIDOC ## client.user.getSettings ### Description Fetches the current user's configuration settings. ## client.user.saveSettings ### Description Persists updated user settings to the server. ``` -------------------------------- ### Configure JVM Memory Settings Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Pass JVM arguments to control memory allocation and garbage collection behavior when running the JAR. ```bash # Limit JVM memory java -Xmx256m -Xms128m -jar quarkus-run.jar # Dynamic memory release java -Xms20m -XX:+UseG1GC -XX:+UseStringDeduplication \ -XX:-ShrinkHeapInSteps -XX:G1PeriodicGCInterval=10000 \ -XX:-G1PeriodicGCInvokesConcurrent -XX:MinHeapFreeRatio=5 \ -XX:MaxHeapFreeRatio=10 -jar quarkus-run.jar ``` -------------------------------- ### client.feed.fetchFeed(req: FeedInfoRequest) Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Fetches and previews feed information from a URL before subscribing. ```APIDOC ## client.feed.fetchFeed(req: FeedInfoRequest) ### Description Fetch and preview a feed URL before subscribing. ### Parameters - **req.url** (string) - Required - Feed URL to fetch ### Return Type - **url** (string) - The feed URL - **title** (string) - Feed title extracted from source ### Example ```typescript const response = await client.feed.fetchFeed({ url: "https://example.com/feed" }) const feedInfo = response.data ``` ``` -------------------------------- ### Save Settings Async Thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Persists user settings to the server. ```typescript export const saveSettings = createAsyncThunk( 'user/saveSettings', async (settings: Settings, { rejectWithValue }) => void ) ``` ```typescript const settings = store.getState().user.settings settings.readingMode = "all" dispatch(saveSettings(settings)) ``` -------------------------------- ### POST /user/settings Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Updates the current user's settings and preferences. ```APIDOC ## POST /user/settings ### Description Save user settings and preferences. ### Method POST ### Endpoint /rest/user/settings ### Request Body - **settings** (object) - Complete settings object ### Response #### Success Response (204) - No content ``` -------------------------------- ### Connect to WebSocket Endpoint Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Establishes a connection to the WebSocket server and parses incoming notification messages. ```typescript const ws = new WebSocket('ws://localhost:8082/ws') ws.onmessage = (event) => { const [type, feedId, count] = event.data.split(':') if (type === 'new-feed-entries') { console.log(`${count} new entries in feed ${feedId}`) } } ``` -------------------------------- ### Optimize PostgreSQL Database Indexes Source: https://github.com/athou/commafeed/blob/master/_autodocs/README.md SQL commands to create indexes for improving query performance on feed subscriptions and entry statuses. ```sql CREATE INDEX idx_user_id ON feed_subscription(user_id); CREATE INDEX idx_feed_id ON feed_entry_status(feed_id); CREATE INDEX idx_entry_date ON feed_entry_status(entry_date DESC); ``` -------------------------------- ### client.user.saveSettings Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Saves the provided user settings and preferences. ```APIDOC ## saveSettings(settings: Settings) ### Description Save user settings and preferences. ### Parameters - **settings** (Settings) - Required - Complete settings object ### Example ```typescript const settings = await client.user.getSettings() settings.data.readingMode = "all" settings.data.customCss = "body { font-size: 16px; }" await client.user.saveSettings(settings.data) ``` ``` -------------------------------- ### Enable image proxying Source: https://github.com/athou/commafeed/blob/master/_autodocs/04-configuration.md Proxies feed entry images through the server to bypass restrictive network proxies. ```properties commafeed.image-proxy-enabled=true ``` -------------------------------- ### Find or create a feed Source: https://github.com/athou/commafeed/blob/master/_autodocs/07-backend-services.md Retrieves an existing feed by URL or creates a new one by fetching and parsing. Throws FeedFetchException if the operation fails. ```java public Feed findOrCreate(String url) throws FeedFetchException ``` -------------------------------- ### Configure Axios Instance for CommaFeed Source: https://github.com/athou/commafeed/blob/master/_autodocs/01-client-api.md Sets up the base URL and enables credential support for API requests. This configuration is required for the client to communicate with the REST endpoints. ```typescript const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true }) ``` -------------------------------- ### Define getServerInfos async thunk Source: https://github.com/athou/commafeed/blob/master/_autodocs/05-client-state-management.md Async thunk signature for fetching server configuration and capabilities. ```typescript export const getServerInfos = createAsyncThunk( 'server/getServerInfos', async (_, { rejectWithValue }) => ServerInfo ) ``` -------------------------------- ### POST /admin/user/save Source: https://github.com/athou/commafeed/blob/master/_autodocs/03-rest-endpoints.md Creates a new user or updates an existing user profile. ```APIDOC ## POST /admin/user/save ### Description Create or update a user. ### Method POST ### Endpoint /rest/admin/user/save ### Request Body - **id** (number) - Optional - user ID (omit for new) - **name** (string) - Required - username - **email** (string) - Optional - email - **password** (string) - Optional - password (required for new) - **enabled** (boolean) - Required - enabled flag - **admin** (boolean) - Required - admin flag ### Response #### Success Response (200) - **id** (number) - user ID ```