forked from Archives/Athou_commafeed
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b51de8e5b | ||
|
|
0ba70d29bd | ||
|
|
197b3b258b | ||
|
|
850f66999c | ||
|
|
d7d3574e36 | ||
|
|
435d612cbf | ||
|
|
3d3a7c6496 | ||
|
|
fba57fe0a7 | ||
|
|
ce7933f320 | ||
|
|
8ac452afc9 | ||
|
|
a11cb3ac7a | ||
|
|
39808bbafc | ||
|
|
aee56e3dbe | ||
|
|
40f451c762 | ||
|
|
d633803ab5 | ||
|
|
d7a3b75687 | ||
|
|
df8c4056b6 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
java: [ "8", "11", "17" ]
|
java: [ "8", "11", "17", "21" ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [3.10.1]
|
||||||
|
|
||||||
|
- swap next and previous buttons (#1159)
|
||||||
|
- unread count for subscriptions will now be shortened starting at 10k instead of 1k
|
||||||
|
- increased websocket ping interval to just under a minute to reduce data and battery usage on mobile
|
||||||
|
- only refresh subscription tree on a timer if websocket connection is unavailable
|
||||||
|
- the Docker image now uses less memory by returning unused memory to the OS
|
||||||
|
- add support for Java 21
|
||||||
|
|
||||||
## [3.10.0]
|
## [3.10.0]
|
||||||
|
|
||||||
- added a Fever-compatible API that is usable with mobile clients that support the Fever API (see instructions in Settings -> Profile)
|
- added a Fever-compatible API that is usable with mobile clients that support the Fever API (see instructions in Settings -> Profile)
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ VOLUME /commafeed/data
|
|||||||
COPY commafeed-server/config.yml.example config.yml
|
COPY commafeed-server/config.yml.example config.yml
|
||||||
COPY commafeed-server/target/commafeed.jar .
|
COPY commafeed-server/target/commafeed.jar .
|
||||||
|
|
||||||
CMD ["java", "-Djava.net.preferIPv4Stack=true", "-jar", "commafeed.jar", "server", "config.yml"]
|
ENV JAVA_TOOL_OPTIONS -Djava.net.preferIPv4Stack=true -Xms20m -XX:+UseG1GC -XX:-ShrinkHeapInSteps -XX:G1PeriodicGCInterval=10000 -XX:-G1PeriodicGCInvokesConcurrent -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10
|
||||||
|
CMD ["java", "-jar", "commafeed.jar", "server", "config.yml"]
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -7,22 +7,32 @@ Google Reader inspired self-hosted RSS reader, based on Dropwizard and React/Typ
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 4 different layouts
|
- 4 different layouts
|
||||||
- Dark theme
|
- Light/Dark theme
|
||||||
- Fully responsive
|
- Fully responsive
|
||||||
- Keyboard shortcuts for almost everything
|
- Keyboard shortcuts for almost everything
|
||||||
- Support for right-to-left feeds
|
- Support for right-to-left feeds
|
||||||
- Translated in 25+ languages
|
- Translated in 25+ languages
|
||||||
- Supports thousands of users and millions of feeds
|
- Supports thousands of users and millions of feeds
|
||||||
- OPML import/export
|
- OPML import/export
|
||||||
- REST API
|
- REST API and a Fever-compatible API for native mobile apps
|
||||||
- [Browser extension](https://github.com/Athou/commafeed-browser-extension)
|
- [Browser extension](https://github.com/Athou/commafeed-browser-extension)
|
||||||
|
|
||||||
## Deployment on your own server
|
## Deployment
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
|
Docker is the easiest way to get started with CommaFeed.
|
||||||
|
|
||||||
Docker images are built automatically and are available at https://hub.docker.com/r/athou/commafeed
|
Docker images are built automatically and are available at https://hub.docker.com/r/athou/commafeed
|
||||||
|
|
||||||
|
### Cloud hosting
|
||||||
|
|
||||||
|
[PikaPods](https://www.pikapods.com) offers 1-click cloud hosting solutions starting at $1/month with a free $5
|
||||||
|
welcome credit and officially supports CommaFeed.
|
||||||
|
PikaPods shares 20% of the revenue back to CommaFeed.
|
||||||
|
|
||||||
|
[](https://www.pikapods.com/pods?run=commafeed)
|
||||||
|
|
||||||
### Download precompiled package
|
### Download precompiled package
|
||||||
|
|
||||||
mkdir commafeed && cd commafeed
|
mkdir commafeed && cd commafeed
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>3.10.0</version>
|
<version>3.10.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<name>CommaFeed Client</name>
|
<name>CommaFeed Client</name>
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"
|
import { PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit"
|
||||||
import { client } from "app/client"
|
import { client } from "app/client"
|
||||||
import { ServerInfo } from "app/types"
|
import { ServerInfo } from "app/types"
|
||||||
|
|
||||||
interface ServerState {
|
interface ServerState {
|
||||||
serverInfos?: ServerInfo
|
serverInfos?: ServerInfo
|
||||||
|
webSocketConnected: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: ServerState = {}
|
const initialState: ServerState = {
|
||||||
|
webSocketConnected: false,
|
||||||
|
}
|
||||||
|
|
||||||
export const reloadServerInfos = createAsyncThunk("server/infos", () => client.server.getServerInfos().then(r => r.data))
|
export const reloadServerInfos = createAsyncThunk("server/infos", () => client.server.getServerInfos().then(r => r.data))
|
||||||
export const serverSlice = createSlice({
|
export const serverSlice = createSlice({
|
||||||
name: "server",
|
name: "server",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {},
|
reducers: {
|
||||||
|
setWebSocketConnected: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.webSocketConnected = action.payload
|
||||||
|
},
|
||||||
|
},
|
||||||
extraReducers: builder => {
|
extraReducers: builder => {
|
||||||
builder.addCase(reloadServerInfos.fulfilled, (state, action) => {
|
builder.addCase(reloadServerInfos.fulfilled, (state, action) => {
|
||||||
state.serverInfos = action.payload
|
state.serverInfos = action.payload
|
||||||
@@ -20,4 +27,5 @@ export const serverSlice = createSlice({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const { setWebSocketConnected } = serverSlice.actions
|
||||||
export default serverSlice.reducer
|
export default serverSlice.reducer
|
||||||
|
|||||||
@@ -77,11 +77,11 @@ export function Header() {
|
|||||||
<Center>
|
<Center>
|
||||||
<HeaderToolbar>
|
<HeaderToolbar>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
icon={<TbArrowDown size={iconSize} />}
|
icon={<TbArrowUp size={iconSize} />}
|
||||||
label={<Trans>Next</Trans>}
|
label={<Trans>Previous</Trans>}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
dispatch(
|
dispatch(
|
||||||
selectNextEntry({
|
selectPreviousEntry({
|
||||||
expand: true,
|
expand: true,
|
||||||
markAsRead: true,
|
markAsRead: true,
|
||||||
scrollToEntry: true,
|
scrollToEntry: true,
|
||||||
@@ -90,11 +90,11 @@ export function Header() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
icon={<TbArrowUp size={iconSize} />}
|
icon={<TbArrowDown size={iconSize} />}
|
||||||
label={<Trans>Previous</Trans>}
|
label={<Trans>Next</Trans>}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
dispatch(
|
dispatch(
|
||||||
selectPreviousEntry({
|
selectNextEntry({
|
||||||
expand: true,
|
expand: true,
|
||||||
markAsRead: true,
|
markAsRead: true,
|
||||||
scrollToEntry: true,
|
scrollToEntry: true,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Badge, createStyles } from "@mantine/core"
|
import { Badge, createStyles, Tooltip } from "@mantine/core"
|
||||||
|
|
||||||
const useStyles = createStyles(() => ({
|
const useStyles = createStyles(() => ({
|
||||||
badge: {
|
badge: {
|
||||||
@@ -13,6 +13,10 @@ export function UnreadCount(props: { unreadCount: number }) {
|
|||||||
|
|
||||||
if (props.unreadCount <= 0) return null
|
if (props.unreadCount <= 0) return null
|
||||||
|
|
||||||
const count = props.unreadCount >= 1000 ? "999+" : props.unreadCount
|
const count = props.unreadCount >= 10000 ? "10k+" : props.unreadCount
|
||||||
return <Badge className={classes.badge}>{count}</Badge>
|
return (
|
||||||
|
<Tooltip label={props.unreadCount} disabled={props.unreadCount === count}>
|
||||||
|
<Badge className={classes.badge}>{count}</Badge>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { setWebSocketConnected } from "app/slices/server"
|
||||||
import { reloadTree } from "app/slices/tree"
|
import { reloadTree } from "app/slices/tree"
|
||||||
import { useAppDispatch } from "app/store"
|
import { useAppDispatch } from "app/store"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
@@ -11,7 +12,14 @@ export const useWebSocket = () => {
|
|||||||
const wsProtocol = currentUrl.protocol === "http:" ? "ws" : "wss"
|
const wsProtocol = currentUrl.protocol === "http:" ? "ws" : "wss"
|
||||||
const wsUrl = `${wsProtocol}://${currentUrl.hostname}:${currentUrl.port}/ws`
|
const wsUrl = `${wsProtocol}://${currentUrl.hostname}:${currentUrl.port}/ws`
|
||||||
|
|
||||||
const ws = new WebsocketHeartbeatJs({ url: wsUrl, pingMsg: "ping" })
|
const ws = new WebsocketHeartbeatJs({
|
||||||
|
url: wsUrl,
|
||||||
|
pingMsg: "ping",
|
||||||
|
// ping interval, just under a minute to prevent firewalls from closing idle connections
|
||||||
|
pingTimeout: 55000,
|
||||||
|
})
|
||||||
|
ws.onopen = () => dispatch(setWebSocketConnected(true))
|
||||||
|
ws.onclose = () => dispatch(setWebSocketConnected(false))
|
||||||
ws.onmessage = event => {
|
ws.onmessage = event => {
|
||||||
const { data } = event
|
const { data } = event
|
||||||
if (typeof data === "string") {
|
if (typeof data === "string") {
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
|
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
|
||||||
msgstr ""
|
msgstr "CommaFeed ist ein Open Source Projekt. Der Quellcode wird auf auf </0><1>GitHub</1> gehostet."
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "<0>Complete syntax is available </0><1>here</1>."
|
msgid "<0>Complete syntax is available </0><1>here</1>."
|
||||||
msgstr ""
|
msgstr "Vollständiger Syntax ist </0><1>hier</1> verfügbar."
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "<0>Have an account?</0><1>Log in!</1>"
|
msgid "<0>Have an account?</0><1>Log in!</1>"
|
||||||
@@ -35,12 +35,12 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "<0>Need an account?</0><1>Sign up!</1>"
|
msgid "<0>Need an account?</0><1>Sign up!</1>"
|
||||||
msgstr "<0>Benötigen Sie ein Konto?</0><1>Melden Sie sich an!</1>"
|
msgstr "<0>Benötigen Sie ein Konto?</0><1>Hier geht's zur Registrierung!</1>"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr "Ungefähr"
|
msgstr "Über"
|
||||||
|
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
@@ -77,11 +77,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "An email has been sent if this address was registered. Check your inbox."
|
msgid "An email has been sent if this address was registered. Check your inbox."
|
||||||
msgstr "Eine E-Mail wurde gesendet, wenn diese Adresse registriert wurde. "
|
msgstr "Eine E-Mail wurde gesendet, wenn diese Adresse registriert wurde. Bitte den Posteingang prüfen."
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "An opml file is an XML file containing feed URLs and categories. You can get an OPML file by exporting your data from other feed reading services."
|
msgid "An opml file is an XML file containing feed URLs and categories. You can get an OPML file by exporting your data from other feed reading services."
|
||||||
msgstr "Eine opml-Datei ist eine XML-Datei, die Feed-URLs und Kategorien enthält. "
|
msgstr "Eine opml-Datei ist eine XML-Datei, die Feed-URLs und Kategorien enthält."
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
msgid "Analyze feed"
|
msgid "Analyze feed"
|
||||||
@@ -89,7 +89,7 @@ msgstr "Feed analysieren"
|
|||||||
|
|
||||||
#: src/components/AnnouncementDialog.tsx
|
#: src/components/AnnouncementDialog.tsx
|
||||||
msgid "Announcement"
|
msgid "Announcement"
|
||||||
msgstr ""
|
msgstr "Ankündigung"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "API key"
|
msgid "API key"
|
||||||
@@ -105,7 +105,7 @@ msgstr "Sind Sie sicher, dass Sie Benutzer <0>{userName}</0> löschen möchten?"
|
|||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Are you sure you want to delete your account? There's no turning back!"
|
msgid "Are you sure you want to delete your account? There's no turning back!"
|
||||||
msgstr "Sind Sie sicher, dass Sie Ihr Konto löschen möchten? "
|
msgstr "Sind Sie sicher, dass Sie Ihr Konto löschen möchten?"
|
||||||
|
|
||||||
#: src/components/header/MarkAllAsReadButton.tsx
|
#: src/components/header/MarkAllAsReadButton.tsx
|
||||||
msgid "Are you sure you want to mark all entries of <0>{sourceLabel}</0> as read?"
|
msgid "Are you sure you want to mark all entries of <0>{sourceLabel}</0> as read?"
|
||||||
@@ -121,7 +121,7 @@ msgstr "Sind Sie sicher, dass Sie <0>{feedName}</0> abbestellen möchten?"
|
|||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
msgid "Asc"
|
msgid "Asc"
|
||||||
msgstr "Asz"
|
msgstr "Aufsteigend"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison."
|
msgid "Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison."
|
||||||
@@ -133,15 +133,15 @@ msgstr "Zurück"
|
|||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Zurück zum Anmelden"
|
msgstr "Zurück zum Login"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Browser extension required for Chrome"
|
msgid "Browser extension required for Chrome"
|
||||||
msgstr ""
|
msgstr "Browser-Erweiterung für Chrome benötigt"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Browser extention"
|
msgid "Browser extention"
|
||||||
msgstr ""
|
msgstr "Browser-Erweiterung"
|
||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
@@ -181,7 +181,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. The username is your user name and the password is your API key."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. The username is your user name and the password is your API key."
|
||||||
msgstr ""
|
msgstr "CommaFeed ist kompatibel zur Fever API. Benutzen Sie folgende URL in Ihrem Fever-kompatiblen Mobilclient. Der Benutzername ist Ihr User Name, das Passwort ist der API-Schlüssel."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
@@ -272,7 +272,7 @@ msgstr "Anzeige"
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
#: src/pages/app/DonatePage.tsx
|
#: src/pages/app/DonatePage.tsx
|
||||||
msgid "Donate"
|
msgid "Donate"
|
||||||
msgstr ""
|
msgstr "Spenden"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
@@ -331,7 +331,7 @@ msgstr "Exportieren Sie Ihre Abonnements und Kategorien als OPML-Datei, die in a
|
|||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Extension options"
|
msgid "Extension options"
|
||||||
msgstr ""
|
msgstr "Erweiterungsoptionen"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
@@ -345,7 +345,7 @@ msgstr "Feed-URL"
|
|||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Fetch all my feeds now"
|
msgid "Fetch all my feeds now"
|
||||||
msgstr ""
|
msgstr "Alle Feeds jetzt abrufen"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Fever API"
|
msgid "Fever API"
|
||||||
@@ -385,7 +385,7 @@ msgstr "Generierte Feed-URL"
|
|||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
msgid "Go to {0}"
|
msgid "Go to {0}"
|
||||||
msgstr ""
|
msgstr "Gehe zu {0}"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Go to the All view"
|
msgid "Go to the All view"
|
||||||
@@ -397,7 +397,7 @@ msgstr "Gehen Sie zur API-Dokumentation."
|
|||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Gutes"
|
msgstr "Goodies"
|
||||||
|
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
@@ -427,7 +427,7 @@ msgstr "Ungelesen lassen"
|
|||||||
#: src/components/content/FeedEntries.tsx
|
#: src/components/content/FeedEntries.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Keyboard shortcuts"
|
msgid "Keyboard shortcuts"
|
||||||
msgstr "Tastenkürzel"
|
msgstr "Tastaturkürzel"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
@@ -479,7 +479,7 @@ msgstr "Abmelden"
|
|||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Long press"
|
msgid "Long press"
|
||||||
msgstr ""
|
msgstr "Langer Tastendruck"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
@@ -511,7 +511,7 @@ msgstr "Metriken"
|
|||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Middle click"
|
msgid "Middle click"
|
||||||
msgstr ""
|
msgstr "Mittelklick"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Move the page down"
|
msgid "Move the page down"
|
||||||
@@ -524,7 +524,7 @@ msgstr "Bewege die Seite nach oben"
|
|||||||
#: src/components/RelativeDate.tsx
|
#: src/components/RelativeDate.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "N/A"
|
msgid "N/A"
|
||||||
msgstr "n. z"
|
msgstr "n.v."
|
||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
@@ -592,11 +592,11 @@ msgstr "Link öffnen"
|
|||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
msgid "Open link in new background tab"
|
msgid "Open link in new background tab"
|
||||||
msgstr ""
|
msgstr "Link in neuem Tab im Hintergrund öffnen"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
msgid "Open link in new tab"
|
msgid "Open link in new tab"
|
||||||
msgstr ""
|
msgstr "Link in neuem Tab öffnen"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Open next entry"
|
msgid "Open next entry"
|
||||||
@@ -629,11 +629,11 @@ msgstr "Bestellung"
|
|||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
msgid "Parent"
|
msgid "Parent"
|
||||||
msgstr "Elternteil"
|
msgstr "Übergeordnet"
|
||||||
|
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
msgid "Parent Category"
|
msgid "Parent Category"
|
||||||
msgstr "Elternkategorie"
|
msgstr "Übergeordnete Kategorie"
|
||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
@@ -654,11 +654,11 @@ msgstr "Passwörter stimmen nicht überein"
|
|||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Position"
|
msgid "Position"
|
||||||
msgstr "Stellung"
|
msgstr "Position"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
msgid "Previous"
|
msgid "Previous"
|
||||||
msgstr ""
|
msgstr "Vorheriges"
|
||||||
|
|
||||||
#: src/pages/app/SettingsPage.tsx
|
#: src/pages/app/SettingsPage.tsx
|
||||||
msgid "Profile"
|
msgid "Profile"
|
||||||
@@ -684,7 +684,7 @@ msgstr "REST-API"
|
|||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr ""
|
msgstr "Rechtsklick"
|
||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
@@ -696,7 +696,7 @@ msgstr "Speichern"
|
|||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Scroll smoothly when navigating between entries"
|
msgid "Scroll smoothly when navigating between entries"
|
||||||
msgstr "Geschwindes Scrollen beim Navigieren zwischen Einträgen"
|
msgstr "Schnelles Scrollen beim Navigieren zwischen Einträgen"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
@@ -741,11 +741,11 @@ msgstr "Verschiebung"
|
|||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Show CommaFeed's own context menu on right click"
|
msgid "Show CommaFeed's own context menu on right click"
|
||||||
msgstr ""
|
msgstr "CommaFeed-Kontextmenü anzeigen bei Rechtsklick"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Show confirmation when marking all entries as read"
|
msgid "Show confirmation when marking all entries as read"
|
||||||
msgstr ""
|
msgstr "Bestätigung beim Markieren von allen Einträgen als gelesen"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Show entry menu (desktop)"
|
msgid "Show entry menu (desktop)"
|
||||||
@@ -817,12 +817,12 @@ msgstr ""
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Switch to dark theme"
|
msgid "Switch to dark theme"
|
||||||
msgstr "Zum dunklen Design wechseln"
|
msgstr "Zum Darkmode wechseln"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Switch to light theme"
|
msgid "Switch to light theme"
|
||||||
msgstr "Wechseln Sie zum Lichtdesign"
|
msgstr "Zum Lightmode wechseln"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
@@ -842,11 +842,11 @@ msgstr "Lesestatus des aktuellen Eintrags umschalten"
|
|||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle sidebar"
|
msgid "Toggle sidebar"
|
||||||
msgstr ""
|
msgstr "Sidebar an- und ausschalten"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle starred status of current entry"
|
msgid "Toggle starred status of current entry"
|
||||||
msgstr ""
|
msgstr "Markierungsstatus des aktuellen Eintrags ändern"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "Try out CommaFeed with the demo account: demo/demo"
|
msgid "Try out CommaFeed with the demo account: demo/demo"
|
||||||
@@ -854,7 +854,7 @@ msgstr "Testen Sie CommaFeed mit dem Demokonto: demo/demo"
|
|||||||
|
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Try the demo!"
|
msgid "Try the demo!"
|
||||||
msgstr ""
|
msgstr "Testen Sie die Demo!"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
msgid "Unread"
|
msgid "Unread"
|
||||||
@@ -893,4 +893,4 @@ msgstr "Sie haben noch keine Abonnements. "
|
|||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr "Ihr Feed wurde für die Aktualisierung eingereiht."
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ msgstr "Extension CommaFeed pour navigateur version {browserExtensionVersion}."
|
|||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. The username is your user name and the password is your API key."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. The username is your user name and the password is your API key."
|
||||||
msgstr ""
|
msgstr "Commafeed est compatible avec l'API Fever, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre clef API comme mot de passe."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
@@ -349,11 +349,11 @@ msgstr "Rafraîchir tous mes flux"
|
|||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Fever API"
|
msgid "Fever API"
|
||||||
msgstr ""
|
msgstr "API Fever"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Fever API URL"
|
msgid "Fever API URL"
|
||||||
msgstr ""
|
msgstr "URL API Fever"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "file is required"
|
msgid "file is required"
|
||||||
@@ -741,7 +741,7 @@ msgstr "Maj"
|
|||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Show CommaFeed's own context menu on right click"
|
msgid "Show CommaFeed's own context menu on right click"
|
||||||
msgstr ""
|
msgstr "Afficher le menu contextuel de Commafeed lors d'un clic droit"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Show confirmation when marking all entries as read"
|
msgid "Show confirmation when marking all entries as read"
|
||||||
@@ -846,7 +846,7 @@ msgstr "Montrer/cacher la barre latérale"
|
|||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle starred status of current entry"
|
msgid "Toggle starred status of current entry"
|
||||||
msgstr ""
|
msgstr "Montrer/cacher le statut favori de l'entrée"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "Try out CommaFeed with the demo account: demo/demo"
|
msgid "Try out CommaFeed with the demo account: demo/demo"
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
const { loading } = useAppLoading()
|
const { loading } = useAppLoading()
|
||||||
const mobile = useMobile()
|
const mobile = useMobile()
|
||||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||||
|
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||||
const sidebarHidden = props.sidebarWidth === 0
|
const sidebarHidden = props.sidebarWidth === 0
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
useWebSocket()
|
useWebSocket()
|
||||||
@@ -101,16 +102,21 @@ export default function Layout(props: LayoutProps) {
|
|||||||
const handleResize = (element: HTMLElement) => dispatch(setSidebarWidth(element.offsetWidth))
|
const handleResize = (element: HTMLElement) => dispatch(setSidebarWidth(element.offsetWidth))
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// load initial data
|
||||||
dispatch(reloadSettings())
|
dispatch(reloadSettings())
|
||||||
dispatch(reloadProfile())
|
dispatch(reloadProfile())
|
||||||
dispatch(reloadTree())
|
dispatch(reloadTree())
|
||||||
dispatch(reloadTags())
|
dispatch(reloadTags())
|
||||||
|
|
||||||
// reload tree periodically
|
|
||||||
const id = setInterval(() => dispatch(reloadTree()), 30000)
|
|
||||||
return () => clearInterval(id)
|
|
||||||
}, [dispatch])
|
}, [dispatch])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// reload tree periodically if not receiving websocket events
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
if (!webSocketConnected) dispatch(reloadTree())
|
||||||
|
}, 30000)
|
||||||
|
return () => clearInterval(timer)
|
||||||
|
}, [dispatch, webSocketConnected])
|
||||||
|
|
||||||
const burger = (
|
const burger = (
|
||||||
<Center>
|
<Center>
|
||||||
<Burger
|
<Burger
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>3.10.0</version>
|
<version>3.10.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-server</artifactId>
|
<artifactId>commafeed-server</artifactId>
|
||||||
<name>CommaFeed Server</name>
|
<name>CommaFeed Server</name>
|
||||||
@@ -232,13 +232,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<version>3.10.0</version>
|
<version>3.10.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.26</version>
|
<version>1.18.30</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class Entries implements Serializable {
|
|||||||
@ApiModelProperty(value = "times the server tried to refresh the feed and failed", required = true)
|
@ApiModelProperty(value = "times the server tried to refresh the feed and failed", required = true)
|
||||||
private int errorCount;
|
private int errorCount;
|
||||||
|
|
||||||
@ApiModelProperty(value = "URL of the website, extracted from the feed", required = true)
|
@ApiModelProperty(value = "URL of the website, extracted from the feed, only filled if querying for feed entries, not category entries")
|
||||||
private String feedLink;
|
private String feedLink;
|
||||||
|
|
||||||
@ApiModelProperty(value = "list generation timestamp", required = true)
|
@ApiModelProperty(value = "list generation timestamp", required = true)
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ public class FeedREST {
|
|||||||
@POST
|
@POST
|
||||||
@Path("/subscribe")
|
@Path("/subscribe")
|
||||||
@UnitOfWork
|
@UnitOfWork
|
||||||
@ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed")
|
@ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed", response = Long.class)
|
||||||
@Timed
|
@Timed
|
||||||
public Response subscribe(@ApiParam(hidden = true) @SecurityCheck User user,
|
public Response subscribe(@ApiParam(hidden = true) @SecurityCheck User user,
|
||||||
@Valid @ApiParam(value = "subscription request", required = true) SubscribeRequest req) {
|
@Valid @ApiParam(value = "subscription request", required = true) SubscribeRequest req) {
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>3.10.0</version>
|
<version>3.10.1</version>
|
||||||
<name>CommaFeed</name>
|
<name>CommaFeed</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user