forked from Archives/Athou_commafeed
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9354fb8e18 | ||
|
|
664ed317a0 | ||
|
|
5bf121782b | ||
|
|
66c361e6a6 | ||
|
|
0946c0248e | ||
|
|
a8be8f2edf | ||
|
|
99db85328b | ||
|
|
5f29838bd2 | ||
|
|
7d2c0e7576 | ||
|
|
b8211e69e9 | ||
|
|
d7b2c5a6e3 | ||
|
|
18358d5991 | ||
|
|
e9b4895b0f | ||
|
|
c4fbf98200 | ||
|
|
b0aa6ae524 | ||
|
|
11dd151a3b |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,9 +1,18 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [4.2.0]
|
||||||
|
|
||||||
|
- add a setting to display the action buttons in the footer instead of in the header on mobile (#1121)
|
||||||
|
- the websocket notification now contains everything needed to update the UI, the client no longer needs to make an API
|
||||||
|
call to get the latest data when receiving the notification
|
||||||
|
- add a workaround to the Fever API for the Unread iOS app (#1188)
|
||||||
|
- fix an issue that caused dates to be saved incorrectly if the database server and the application server were in
|
||||||
|
different timezones (#1187)
|
||||||
|
|
||||||
## [4.1.0]
|
## [4.1.0]
|
||||||
|
|
||||||
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
|
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
|
||||||
- swiping to mark entries as read/unread changed from swipinig right to left because swiping right now opens the sidebar
|
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
|
||||||
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
|
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
|
||||||
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
|
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
|
||||||
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
|
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -109,19 +109,3 @@ two-letters [ISO-639-1 language code](http://en.wikipedia.org/wiki/List_of_ISO_6
|
|||||||
|
|
||||||
The frontend server is now running at http://localhost:8082 and is proxying REST requests to the backend running on
|
The frontend server is now running at http://localhost:8082 and is proxying REST requests to the backend running on
|
||||||
port 8083
|
port 8083
|
||||||
|
|
||||||
## Copyright and license
|
|
||||||
|
|
||||||
Copyright 2013-2023 CommaFeed.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this work except in compliance with the License.
|
|
||||||
You may obtain a copy of the License in the LICENSE file, or at:
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|||||||
8
commafeed-client/package-lock.json
generated
8
commafeed-client/package-lock.json
generated
@@ -70,7 +70,7 @@
|
|||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.1",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.11",
|
"vite": "^5.0.12",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.2.3",
|
"vite-tsconfig-paths": "^4.2.3",
|
||||||
"vitest": "^1.1.3",
|
"vitest": "^1.1.3",
|
||||||
@@ -8570,9 +8570,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.0.11",
|
"version": "5.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
|
||||||
"integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==",
|
"integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.19.3",
|
"esbuild": "^0.19.3",
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.1",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.11",
|
"vite": "^5.0.12",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.2.3",
|
"vite-tsconfig-paths": "^4.2.3",
|
||||||
"vitest": "^1.1.3",
|
"vitest": "^1.1.3",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>4.1.0</version>
|
<version>4.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<name>CommaFeed Client</name>
|
<name>CommaFeed Client</name>
|
||||||
|
|||||||
@@ -89,10 +89,18 @@ export const Constants = {
|
|||||||
mobileBreakpointName: "md",
|
mobileBreakpointName: "md",
|
||||||
headerHeight: 60,
|
headerHeight: 60,
|
||||||
entryMaxWidth: 650,
|
entryMaxWidth: 650,
|
||||||
isTopVisible: (div: HTMLElement) => div.getBoundingClientRect().top >= Constants.layout.headerHeight,
|
isTopVisible: (div: HTMLElement) => {
|
||||||
isBottomVisible: (div: HTMLElement) => div.getBoundingClientRect().bottom <= window.innerHeight,
|
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
|
||||||
|
return div.getBoundingClientRect().top >= (header?.bottom ?? 0)
|
||||||
|
},
|
||||||
|
isBottomVisible: (div: HTMLElement) => {
|
||||||
|
const footer = document.getElementById(Constants.dom.footerId)?.getBoundingClientRect()
|
||||||
|
return div.getBoundingClientRect().bottom <= (footer?.top ?? window.innerHeight)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
dom: {
|
dom: {
|
||||||
|
headerId: "header",
|
||||||
|
footerId: "footer",
|
||||||
entryId: (entry: Entry) => `entry-id-${entry.id}`,
|
entryId: (entry: Entry) => `entry-id-${entry.id}`,
|
||||||
entryContextMenuId: (entry: Entry) => entry.id,
|
entryContextMenuId: (entry: Entry) => entry.id,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -174,10 +174,11 @@ export const selectEntry = createAppAsyncThunk(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
|
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
|
||||||
|
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
|
||||||
|
const offset = (header?.bottom ?? 0) + 3
|
||||||
scrollToWithCallback({
|
scrollToWithCallback({
|
||||||
options: {
|
options: {
|
||||||
// add a small gap between the top of the content and the top of the page
|
top: entryElement.offsetTop - offset,
|
||||||
top: entryElement.offsetTop - Constants.layout.headerHeight - 3,
|
|
||||||
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto",
|
||||||
},
|
},
|
||||||
onScrollEnded,
|
onScrollEnded,
|
||||||
|
|||||||
@@ -26,6 +26,22 @@ export const treeSlice = createSlice({
|
|||||||
toggleSidebar: state => {
|
toggleSidebar: state => {
|
||||||
state.sidebarVisible = !state.sidebarVisible
|
state.sidebarVisible = !state.sidebarVisible
|
||||||
},
|
},
|
||||||
|
incrementUnreadCount: (
|
||||||
|
state,
|
||||||
|
action: PayloadAction<{
|
||||||
|
feedId: number
|
||||||
|
amount: number
|
||||||
|
}>
|
||||||
|
) => {
|
||||||
|
if (!state.rootCategory) return
|
||||||
|
visitCategoryTree(state.rootCategory, c =>
|
||||||
|
c.feeds
|
||||||
|
.filter(f => f.id === action.payload.feedId)
|
||||||
|
.forEach(f => {
|
||||||
|
f.unread += action.payload.amount
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraReducers: builder => {
|
extraReducers: builder => {
|
||||||
builder.addCase(reloadTree.fulfilled, (state, action) => {
|
builder.addCase(reloadTree.fulfilled, (state, action) => {
|
||||||
@@ -53,4 +69,4 @@ export const treeSlice = createSlice({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const { setMobileMenuOpen, toggleSidebar } = treeSlice.actions
|
export const { setMobileMenuOpen, toggleSidebar, incrementUnreadCount } = treeSlice.actions
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ export interface Settings {
|
|||||||
alwaysScrollToEntry: boolean
|
alwaysScrollToEntry: boolean
|
||||||
markAllAsReadConfirmation: boolean
|
markAllAsReadConfirmation: boolean
|
||||||
customContextMenu: boolean
|
customContextMenu: boolean
|
||||||
|
mobileFooter: boolean
|
||||||
sharingSettings: SharingSettings
|
sharingSettings: SharingSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
changeCustomContextMenu,
|
changeCustomContextMenu,
|
||||||
changeLanguage,
|
changeLanguage,
|
||||||
changeMarkAllAsReadConfirmation,
|
changeMarkAllAsReadConfirmation,
|
||||||
|
changeMobileFooter,
|
||||||
changeReadingMode,
|
changeReadingMode,
|
||||||
changeReadingOrder,
|
changeReadingOrder,
|
||||||
changeScrollMarks,
|
changeScrollMarks,
|
||||||
@@ -76,6 +77,10 @@ export const userSlice = createSlice({
|
|||||||
if (!state.settings) return
|
if (!state.settings) return
|
||||||
state.settings.customContextMenu = action.meta.arg
|
state.settings.customContextMenu = action.meta.arg
|
||||||
})
|
})
|
||||||
|
builder.addCase(changeMobileFooter.pending, (state, action) => {
|
||||||
|
if (!state.settings) return
|
||||||
|
state.settings.mobileFooter = action.meta.arg
|
||||||
|
})
|
||||||
builder.addCase(changeSharingSetting.pending, (state, action) => {
|
builder.addCase(changeSharingSetting.pending, (state, action) => {
|
||||||
if (!state.settings) return
|
if (!state.settings) return
|
||||||
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
|
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
|
||||||
@@ -89,6 +94,7 @@ export const userSlice = createSlice({
|
|||||||
changeAlwaysScrollToEntry.fulfilled,
|
changeAlwaysScrollToEntry.fulfilled,
|
||||||
changeMarkAllAsReadConfirmation.fulfilled,
|
changeMarkAllAsReadConfirmation.fulfilled,
|
||||||
changeCustomContextMenu.fulfilled,
|
changeCustomContextMenu.fulfilled,
|
||||||
|
changeMobileFooter.fulfilled,
|
||||||
changeSharingSetting.fulfilled
|
changeSharingSetting.fulfilled
|
||||||
),
|
),
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ export const changeCustomContextMenu = createAppAsyncThunk("settings/customConte
|
|||||||
if (!settings) return
|
if (!settings) return
|
||||||
client.user.saveSettings({ ...settings, customContextMenu })
|
client.user.saveSettings({ ...settings, customContextMenu })
|
||||||
})
|
})
|
||||||
|
export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", (mobileFooter: boolean, thunkApi) => {
|
||||||
|
const { settings } = thunkApi.getState().user
|
||||||
|
if (!settings) return
|
||||||
|
client.user.saveSettings({ ...settings, mobileFooter })
|
||||||
|
})
|
||||||
export const changeSharingSetting = createAppAsyncThunk(
|
export const changeSharingSetting = createAppAsyncThunk(
|
||||||
"settings/sharingSetting",
|
"settings/sharingSetting",
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
changeCustomContextMenu,
|
changeCustomContextMenu,
|
||||||
changeLanguage,
|
changeLanguage,
|
||||||
changeMarkAllAsReadConfirmation,
|
changeMarkAllAsReadConfirmation,
|
||||||
|
changeMobileFooter,
|
||||||
changeScrollMarks,
|
changeScrollMarks,
|
||||||
changeScrollSpeed,
|
changeScrollSpeed,
|
||||||
changeSharingSetting,
|
changeSharingSetting,
|
||||||
@@ -23,6 +24,7 @@ export function DisplaySettings() {
|
|||||||
const alwaysScrollToEntry = useAppSelector(state => state.user.settings?.alwaysScrollToEntry)
|
const alwaysScrollToEntry = useAppSelector(state => state.user.settings?.alwaysScrollToEntry)
|
||||||
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
|
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
|
||||||
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
|
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
|
||||||
|
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
||||||
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
@@ -74,6 +76,12 @@ export function DisplaySettings() {
|
|||||||
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
|
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
label={<Trans>On mobile, show action buttons at the bottom of the screen</Trans>}
|
||||||
|
checked={mobileFooter}
|
||||||
|
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
||||||
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
<SimpleGrid cols={2}>
|
<SimpleGrid cols={2}>
|
||||||
|
|||||||
@@ -78,7 +78,17 @@ export function ProfileSettings() {
|
|||||||
<form onSubmit={form.onSubmit(saveProfile.execute)}>
|
<form onSubmit={form.onSubmit(saveProfile.execute)}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<TextInput label={<Trans>User name</Trans>} readOnly value={profile?.name} />
|
<TextInput label={<Trans>User name</Trans>} readOnly value={profile?.name} />
|
||||||
<TextInput label={<Trans>API key</Trans>} readOnly value={profile?.apiKey} />
|
<TextInput
|
||||||
|
label={<Trans>API key</Trans>}
|
||||||
|
description={
|
||||||
|
<Trans>
|
||||||
|
This is your API key. It can be used for some read-only API operations and grants access to the Fever API.
|
||||||
|
Use the form at the bottom of the page to generate a new API key
|
||||||
|
</Trans>
|
||||||
|
}
|
||||||
|
readOnly
|
||||||
|
value={profile?.apiKey}
|
||||||
|
/>
|
||||||
|
|
||||||
<Input.Wrapper
|
<Input.Wrapper
|
||||||
label={<Trans>OPML export</Trans>}
|
label={<Trans>OPML export</Trans>}
|
||||||
@@ -100,7 +110,7 @@ export function ProfileSettings() {
|
|||||||
description={
|
description={
|
||||||
<Trans>
|
<Trans>
|
||||||
CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client.
|
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.
|
Login with your username and your <u>API key</u>.
|
||||||
</Trans>
|
</Trans>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
import { setWebSocketConnected } from "app/server/slice"
|
import { setWebSocketConnected } from "app/server/slice"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { type AppDispatch, useAppDispatch, useAppSelector } from "app/store"
|
||||||
import { reloadTree } from "app/tree/thunks"
|
import { incrementUnreadCount } from "app/tree/slice"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import WebsocketHeartbeatJs from "websocket-heartbeat-js"
|
import WebsocketHeartbeatJs from "websocket-heartbeat-js"
|
||||||
|
|
||||||
|
const handleMessage = (dispatch: AppDispatch, message: string) => {
|
||||||
|
const parts = message.split(":")
|
||||||
|
const type = parts[0]
|
||||||
|
if (type === "new-feed-entries") {
|
||||||
|
dispatch(
|
||||||
|
incrementUnreadCount({
|
||||||
|
feedId: +parts[1],
|
||||||
|
amount: +parts[2],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const useWebSocket = () => {
|
export const useWebSocket = () => {
|
||||||
const websocketEnabled = useAppSelector(state => state.server.serverInfos?.websocketEnabled)
|
const websocketEnabled = useAppSelector(state => state.server.serverInfos?.websocketEnabled)
|
||||||
const websocketPingInterval = useAppSelector(state => state.server.serverInfos?.websocketPingInterval)
|
const websocketPingInterval = useAppSelector(state => state.server.serverInfos?.websocketPingInterval)
|
||||||
@@ -27,7 +40,7 @@ export const useWebSocket = () => {
|
|||||||
ws.onmessage = event => {
|
ws.onmessage = event => {
|
||||||
const { data } = event
|
const { data } = event
|
||||||
if (typeof data === "string") {
|
if (typeof data === "string") {
|
||||||
if (data.startsWith("new-feed-entries:")) dispatch(reloadTree())
|
handleMessage(dispatch, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "لم يتم العثور على شيء"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "الأقدم أولا"
|
msgstr "الأقدم أولا"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "اوووه!"
|
msgstr "اوووه!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "عنوان URL للتغذية التي تريد الاشتراك فيه
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "الموضوع"
|
msgstr "الموضوع"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "تبديل قراءة حالة الإدخال الحالي"
|
msgstr "تبديل قراءة حالة الإدخال الحالي"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "No s'ha trobat res"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "el més vell primer"
|
msgstr "el més vell primer"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Vaja!"
|
msgstr "Vaja!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "l'URL del canal al qual us voleu subscriure. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Canvia l'estat de lectura de l'entrada actual"
|
msgstr "Canvia l'estat de lectura de l'entrada actual"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nic nebylo nalezeno"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Nejdříve nejstarší"
|
msgstr "Nejdříve nejstarší"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Jejda!"
|
msgstr "Jejda!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Adresa URL kanálu, k jehož odběru se chcete přihlásit. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Téma"
|
msgstr "Téma"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Přepne stav čtení aktuálního záznamu"
|
msgstr "Přepne stav čtení aktuálního záznamu"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Dim wedi'i ddarganfod"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Hynaf yn gyntaf"
|
msgstr "Hynaf yn gyntaf"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Wps!"
|
msgstr "Wps!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Y URL ar gyfer y porthwr rydych chi am danysgrifio iddo. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Thema"
|
msgstr "Thema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Toglo statws darllen y cofnod cyfredol"
|
msgstr "Toglo statws darllen y cofnod cyfredol"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Intet fundet"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Ældst først"
|
msgstr "Ældst først"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Hovsa!"
|
msgstr "Hovsa!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL'en til det feed, du vil abonnere på. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Skift læsestatus for den aktuelle post"
|
msgstr "Skift læsestatus for den aktuelle post"
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
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."
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nichts gefunden"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Älteste zuerst"
|
msgstr "Älteste zuerst"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ups!"
|
msgstr "Ups!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Die URL für den Feed, den Sie abonnieren möchten. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Thema"
|
msgstr "Thema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Lesestatus des aktuellen Eintrags umschalten"
|
msgstr "Lesestatus des aktuellen Eintrags umschalten"
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr "CommaFeed browser extension version {browserExtensionVersion}."
|
msgstr "CommaFeed browser extension 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. Login with your username and your <0>API key</0>."
|
||||||
msgstr "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 "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nothing found"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Oldest first"
|
msgstr "Oldest first"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Oops!"
|
msgstr "Oops!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "The URL for the feed you want to subscribe to. You can also use the webs
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Theme"
|
msgstr "Theme"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Toggle read status of current entry"
|
msgstr "Toggle read status of current entry"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nada encontrado"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "más antigua primero"
|
msgstr "más antigua primero"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "¡Ups!"
|
msgstr "¡Ups!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "La URL de la fuente a la que desea suscribirse. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Alternar estado de lectura de la entrada actual"
|
msgstr "Alternar estado de lectura de la entrada actual"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "چیزی پیدا نشد"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "قدیمی ترین اول"
|
msgstr "قدیمی ترین اول"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "اوه!"
|
msgstr "اوه!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL فیدی که می خواهید در آن مشترک شوید. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "تم"
|
msgstr "تم"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "وضعیت خواندن ورودی فعلی را تغییر دهید"
|
msgstr "وضعیت خواندن ورودی فعلی را تغییر دهید"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Mitään ei löytynyt"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Vanhin ensin"
|
msgstr "Vanhin ensin"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Hups!"
|
msgstr "Hups!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Sen syötteen URL-osoite, jonka haluat tilata. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Teema"
|
msgstr "Teema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Vaihda nykyisen merkinnän lukutila"
|
msgstr "Vaihda nykyisen merkinnän lukutila"
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr "Extension CommaFeed pour navigateur version {browserExtensionVersion}."
|
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. Login with your username and your <0>API key</0>."
|
||||||
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."
|
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 <0>clef API</0> comme mot de passe."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
@@ -574,6 +574,10 @@ msgstr "Aucun résultat"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Du plus ancien au plus récent"
|
msgstr "Du plus ancien au plus récent"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Oups !"
|
msgstr "Oups !"
|
||||||
@@ -847,6 +851,10 @@ msgstr "L'URL du flux auquel vous souhaitez vous abonner. Vous pouvez aussi util
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Thème"
|
msgstr "Thème"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr "Ceci est votre clef API. Elle peut être utilisée pour certaines opérations en lecture seule et donne accès à l'API Fever. Utilisez le formulaire en bas de la page pour générer une nouvelle clef API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Marquer l'entrée actuelle comme lue/non lue"
|
msgstr "Marquer l'entrée actuelle comme lue/non lue"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Non se atopou nada"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "O máis vello primeiro"
|
msgstr "O máis vello primeiro"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Vaia!"
|
msgstr "Vaia!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "O URL do feed ao que quere subscribirse. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "alternar o estado de lectura da entrada actual"
|
msgstr "alternar o estado de lectura da entrada actual"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Semmi sem található"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "A legidősebb első"
|
msgstr "A legidősebb első"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Hoppá!"
|
msgstr "Hoppá!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Az előfizetni kívánt hírcsatorna URL-je. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Téma"
|
msgstr "Téma"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Az aktuális bejegyzés olvasási állapotának váltása"
|
msgstr "Az aktuális bejegyzés olvasási állapotának váltása"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Tidak ada yang ditemukan"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Tertua dulu"
|
msgstr "Tertua dulu"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ups!"
|
msgstr "Ups!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL untuk umpan yang ingin Anda langgani. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Beralih status baca entri saat ini"
|
msgstr "Beralih status baca entri saat ini"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Non è stato trovato nulla"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Il più vecchio prima"
|
msgstr "Il più vecchio prima"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ops!"
|
msgstr "Ops!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "L'URL del feed a cui vuoi iscriverti. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Commuta lo stato di lettura della voce corrente"
|
msgstr "Commuta lo stato di lettura della voce corrente"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "何も見つかりませんでした"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "古い順"
|
msgstr "古い順"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "おっと!"
|
msgstr "おっと!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "購読したいフィードのURL。 "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "テーマ"
|
msgstr "テーマ"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "現在のエントリの読み取りステータスを切り替えます"
|
msgstr "現在のエントリの読み取りステータスを切り替えます"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "아무것도 찾을 수 없습니다"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "가장 오래된 것부터"
|
msgstr "가장 오래된 것부터"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "앗!"
|
msgstr "앗!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "구독하려는 피드의 URL입니다. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "테마"
|
msgstr "테마"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "현재 항목의 읽기 상태 전환"
|
msgstr "현재 항목의 읽기 상태 전환"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Tiada apa-apa dijumpai"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Tertua dahulu"
|
msgstr "Tertua dahulu"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Aduh!"
|
msgstr "Aduh!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL untuk suapan yang anda ingin langgan. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Togol status bacaan entri semasa"
|
msgstr "Togol status bacaan entri semasa"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Ingenting funnet"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Eldste først"
|
msgstr "Eldste først"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Beklager!"
|
msgstr "Beklager!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL-en til feeden du vil abonnere på. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Veksle lesestatus for gjeldende oppføring"
|
msgstr "Veksle lesestatus for gjeldende oppføring"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Niets gevonden"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Oudste eerst"
|
msgstr "Oudste eerst"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Oeps!"
|
msgstr "Oeps!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "De URL voor de feed waarop u zich wilt abonneren. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Thema"
|
msgstr "Thema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Toggle leesstatus van huidige invoer"
|
msgstr "Toggle leesstatus van huidige invoer"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Ingenting funnet"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Eldste først"
|
msgstr "Eldste først"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Beklager!"
|
msgstr "Beklager!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL-en til feeden du vil abonnere på. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Veksle lesestatus for gjeldende oppføring"
|
msgstr "Veksle lesestatus for gjeldende oppføring"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nic nie znaleziono"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Najstarsze jako pierwsze"
|
msgstr "Najstarsze jako pierwsze"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ups!"
|
msgstr "Ups!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL kanału, który chcesz subskrybować. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Motyw"
|
msgstr "Motyw"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Przełącz stan odczytu bieżącego wpisu"
|
msgstr "Przełącz stan odczytu bieżącego wpisu"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nada encontrado"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Mais antigo primeiro"
|
msgstr "Mais antigo primeiro"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Opa!"
|
msgstr "Opa!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "A URL do feed que você deseja assinar. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Alternar o status de leitura da entrada atual"
|
msgstr "Alternar o status de leitura da entrada atual"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Ничего не найдено"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Сначала самые старые"
|
msgstr "Сначала самые старые"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ой!"
|
msgstr "Ой!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL канала, на который вы хотите подписат
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Тема"
|
msgstr "Тема"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Переключить статус чтения текущей записи"
|
msgstr "Переключить статус чтения текущей записи"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Nič sa nenašlo"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Najprv najstarší"
|
msgstr "Najprv najstarší"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Ojoj!"
|
msgstr "Ojoj!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL zdroja, na odber ktorého sa chcete prihlásiť. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Téma"
|
msgstr "Téma"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Prepne stav čítania aktuálneho záznamu"
|
msgstr "Prepne stav čítania aktuálneho záznamu"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Inget hittades"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Äldst först"
|
msgstr "Äldst först"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Hoppsan!"
|
msgstr "Hoppsan!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "URL:en för flödet du vill prenumerera på. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Växla lässtatus för aktuell post"
|
msgstr "Växla lässtatus för aktuell post"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr "CommaFeed tarayıcı eklentisi sürüm {browserExtensionVersion}."
|
msgstr "CommaFeed tarayıcı eklentisi sürüm {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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "Hiçbir şey bulunamadı"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "Önce en eski"
|
msgstr "Önce en eski"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "Hata!"
|
msgstr "Hata!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "Abone olmak istediğiniz beslemenin URL'si. "
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Tema"
|
msgstr "Tema"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "Geçerli girişin okuma durumunu değiştir"
|
msgstr "Geçerli girişin okuma durumunu değiştir"
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgstr ""
|
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. Login with your username and your <0>API key</0>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -574,6 +574,10 @@ msgstr "没有找到"
|
|||||||
msgid "Oldest first"
|
msgid "Oldest first"
|
||||||
msgstr "最早的优先"
|
msgstr "最早的优先"
|
||||||
|
|
||||||
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
|
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/ErrorPage.tsx
|
#: src/pages/ErrorPage.tsx
|
||||||
msgid "Oops!"
|
msgid "Oops!"
|
||||||
msgstr "哎呀!"
|
msgstr "哎呀!"
|
||||||
@@ -847,6 +851,10 @@ msgstr "您要订阅的订阅源的 URL。"
|
|||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "主题"
|
msgstr "主题"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Toggle read status of current entry"
|
msgid "Toggle read status of current entry"
|
||||||
msgstr "切换当前条目的读取状态"
|
msgstr "切换当前条目的读取状态"
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export function FeedEntriesPage(props: FeedEntriesPageProps) {
|
|||||||
if (noSubscriptions) return <NoSubscriptionHelp />
|
if (noSubscriptions) return <NoSubscriptionHelp />
|
||||||
return (
|
return (
|
||||||
// add some room at the bottom of the page in order to be able to scroll the current entry at the top of the page when expanding
|
// add some room at the bottom of the page in order to be able to scroll the current entry at the top of the page when expanding
|
||||||
<Box mb={viewport.height - Constants.layout.headerHeight - 210}>
|
<Box mb={viewport.height * 0.75}>
|
||||||
<Group gap="xl">
|
<Group gap="xl">
|
||||||
{sourceWebsiteUrl && (
|
{sourceWebsiteUrl && (
|
||||||
<a href={sourceWebsiteUrl} target="_blank" rel="noreferrer" className={classes.sourceWebsiteLink}>
|
<a href={sourceWebsiteUrl} target="_blank" rel="noreferrer" className={classes.sourceWebsiteLink}>
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { Logo } from "components/Logo"
|
|||||||
import { OnDesktop } from "components/responsive/OnDesktop"
|
import { OnDesktop } from "components/responsive/OnDesktop"
|
||||||
import { OnMobile } from "components/responsive/OnMobile"
|
import { OnMobile } from "components/responsive/OnMobile"
|
||||||
import { useAppLoading } from "hooks/useAppLoading"
|
import { useAppLoading } from "hooks/useAppLoading"
|
||||||
|
import { useBrowserExtension } from "hooks/useBrowserExtension"
|
||||||
|
import { useMobile } from "hooks/useMobile"
|
||||||
import { useWebSocket } from "hooks/useWebSocket"
|
import { useWebSocket } from "hooks/useWebSocket"
|
||||||
import { LoadingPage } from "pages/LoadingPage"
|
import { LoadingPage } from "pages/LoadingPage"
|
||||||
import { type ReactNode, Suspense, useEffect } from "react"
|
import { type ReactNode, Suspense, useEffect } from "react"
|
||||||
@@ -60,6 +62,8 @@ const useStyles = tss
|
|||||||
|
|
||||||
export default function Layout(props: LayoutProps) {
|
export default function Layout(props: LayoutProps) {
|
||||||
const theme = useMantineTheme()
|
const theme = useMantineTheme()
|
||||||
|
const mobile = useMobile()
|
||||||
|
const { isBrowserExtensionPopup } = useBrowserExtension()
|
||||||
const [sidebarWidth, setSidebarWidth] = useLocalStorage("sidebar-width", 350)
|
const [sidebarWidth, setSidebarWidth] = useLocalStorage("sidebar-width", 350)
|
||||||
const sidebarPadding = theme.spacing.xs
|
const sidebarPadding = theme.spacing.xs
|
||||||
const { classes } = useStyles({
|
const { classes } = useStyles({
|
||||||
@@ -71,6 +75,8 @@ export default function Layout(props: LayoutProps) {
|
|||||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||||
|
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
||||||
|
const headerInFooter = mobile && !isBrowserExtensionPopup && mobileFooter
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
useWebSocket()
|
useWebSocket()
|
||||||
|
|
||||||
@@ -112,6 +118,39 @@ export default function Layout(props: LayoutProps) {
|
|||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const header = (
|
||||||
|
<>
|
||||||
|
<OnMobile>
|
||||||
|
{mobileMenuOpen && (
|
||||||
|
<Group justify="space-between" p="md">
|
||||||
|
<Box>{burger}</Box>
|
||||||
|
<Box>
|
||||||
|
<LogoAndTitle />
|
||||||
|
</Box>
|
||||||
|
<Box>{addButton}</Box>
|
||||||
|
</Group>
|
||||||
|
)}
|
||||||
|
{!mobileMenuOpen && (
|
||||||
|
<Group p="md">
|
||||||
|
<Box>{burger}</Box>
|
||||||
|
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
||||||
|
</Group>
|
||||||
|
)}
|
||||||
|
</OnMobile>
|
||||||
|
<OnDesktop>
|
||||||
|
<Group p="md">
|
||||||
|
<Group justify="space-between" style={{ width: sidebarWidth - 16 }}>
|
||||||
|
<Box>
|
||||||
|
<LogoAndTitle />
|
||||||
|
</Box>
|
||||||
|
<Box>{addButton}</Box>
|
||||||
|
</Group>
|
||||||
|
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
||||||
|
</Group>
|
||||||
|
</OnDesktop>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
const swipeHandlers = useSwipeable({
|
const swipeHandlers = useSwipeable({
|
||||||
onSwiping: e => {
|
onSwiping: e => {
|
||||||
const threshold = document.documentElement.clientWidth / 6
|
const threshold = document.documentElement.clientWidth / 6
|
||||||
@@ -125,7 +164,8 @@ export default function Layout(props: LayoutProps) {
|
|||||||
return (
|
return (
|
||||||
<Box {...swipeHandlers}>
|
<Box {...swipeHandlers}>
|
||||||
<AppShell
|
<AppShell
|
||||||
header={{ height: Constants.layout.headerHeight }}
|
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
||||||
|
footer={{ height: Constants.layout.headerHeight, collapsed: !headerInFooter }}
|
||||||
navbar={{
|
navbar={{
|
||||||
width: sidebarWidth,
|
width: sidebarWidth,
|
||||||
breakpoint: Constants.layout.mobileBreakpoint,
|
breakpoint: Constants.layout.mobileBreakpoint,
|
||||||
@@ -133,36 +173,8 @@ export default function Layout(props: LayoutProps) {
|
|||||||
}}
|
}}
|
||||||
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
|
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
|
||||||
>
|
>
|
||||||
<AppShell.Header id="header">
|
<AppShell.Header id={Constants.dom.headerId}>{!headerInFooter && header}</AppShell.Header>
|
||||||
<OnMobile>
|
<AppShell.Footer id={Constants.dom.footerId}>{headerInFooter && header}</AppShell.Footer>
|
||||||
{mobileMenuOpen && (
|
|
||||||
<Group justify="space-between" p="md">
|
|
||||||
<Box>{burger}</Box>
|
|
||||||
<Box>
|
|
||||||
<LogoAndTitle />
|
|
||||||
</Box>
|
|
||||||
<Box>{addButton}</Box>
|
|
||||||
</Group>
|
|
||||||
)}
|
|
||||||
{!mobileMenuOpen && (
|
|
||||||
<Group p="md">
|
|
||||||
<Box>{burger}</Box>
|
|
||||||
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
|
||||||
</Group>
|
|
||||||
)}
|
|
||||||
</OnMobile>
|
|
||||||
<OnDesktop>
|
|
||||||
<Group p="md">
|
|
||||||
<Group justify="space-between" style={{ width: sidebarWidth - 16 }}>
|
|
||||||
<Box>
|
|
||||||
<LogoAndTitle />
|
|
||||||
</Box>
|
|
||||||
<Box>{addButton}</Box>
|
|
||||||
</Group>
|
|
||||||
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
|
||||||
</Group>
|
|
||||||
</OnDesktop>
|
|
||||||
</AppShell.Header>
|
|
||||||
<AppShell.Navbar id="sidebar" p={sidebarPadding}>
|
<AppShell.Navbar id="sidebar" p={sidebarPadding}>
|
||||||
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
|
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
|
||||||
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
|
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
|
||||||
@@ -173,7 +185,7 @@ export default function Layout(props: LayoutProps) {
|
|||||||
axis="x"
|
axis="x"
|
||||||
defaultPosition={{
|
defaultPosition={{
|
||||||
x: sidebarWidth,
|
x: sidebarWidth,
|
||||||
y: Constants.layout.headerHeight,
|
y: 0,
|
||||||
}}
|
}}
|
||||||
bounds={{
|
bounds={{
|
||||||
left: 120,
|
left: 120,
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ services:
|
|||||||
postgresql:
|
postgresql:
|
||||||
image: postgres
|
image: postgres
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: root
|
- POSTGRES_USER=root
|
||||||
POSTGRES_PASSWORD: root
|
- POSTGRES_PASSWORD=root
|
||||||
POSTGRES_DB: commafeed
|
- POSTGRES_DB=commafeed
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>4.1.0</version>
|
<version>4.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-server</artifactId>
|
<artifactId>commafeed-server</artifactId>
|
||||||
<name>CommaFeed Server</name>
|
<name>CommaFeed Server</name>
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<version>4.1.0</version>
|
<version>4.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -263,16 +263,15 @@
|
|||||||
<groupId>io.dropwizard.metrics</groupId>
|
<groupId>io.dropwizard.metrics</groupId>
|
||||||
<artifactId>metrics-json</artifactId>
|
<artifactId>metrics-json</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>be.tomcools</groupId>
|
|
||||||
<artifactId>dropwizard-websocket-jsr356-bundle</artifactId>
|
|
||||||
<version>4.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.whitfin</groupId>
|
<groupId>io.whitfin</groupId>
|
||||||
<artifactId>dropwizard-environment-substitutor</artifactId>
|
<artifactId>dropwizard-environment-substitutor</artifactId>
|
||||||
<version>1.1.1</version>
|
<version>1.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||||
|
<artifactId>websocket-jakarta-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.swagger.core.v3</groupId>
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
import com.codahale.metrics.json.MetricsModule;
|
import com.codahale.metrics.json.MetricsModule;
|
||||||
@@ -52,7 +53,6 @@ import com.google.inject.Injector;
|
|||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
import be.tomcools.dropwizard.websocket.WebsocketBundle;
|
|
||||||
import io.dropwizard.assets.AssetsBundle;
|
import io.dropwizard.assets.AssetsBundle;
|
||||||
import io.dropwizard.configuration.DefaultConfigurationFactoryFactory;
|
import io.dropwizard.configuration.DefaultConfigurationFactoryFactory;
|
||||||
import io.dropwizard.configuration.EnvironmentVariableSubstitutor;
|
import io.dropwizard.configuration.EnvironmentVariableSubstitutor;
|
||||||
@@ -82,7 +82,6 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
public static final Instant STARTUP_TIME = Instant.now();
|
public static final Instant STARTUP_TIME = Instant.now();
|
||||||
|
|
||||||
private HibernateBundle<CommaFeedConfiguration> hibernateBundle;
|
private HibernateBundle<CommaFeedConfiguration> hibernateBundle;
|
||||||
private WebsocketBundle<CommaFeedConfiguration> websocketBundle;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -94,7 +93,6 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
configureEnvironmentSubstitutor(bootstrap);
|
configureEnvironmentSubstitutor(bootstrap);
|
||||||
configureObjectMapper(bootstrap.getObjectMapper());
|
configureObjectMapper(bootstrap.getObjectMapper());
|
||||||
|
|
||||||
bootstrap.addBundle(websocketBundle = new WebsocketBundle<>());
|
|
||||||
bootstrap.addBundle(hibernateBundle = new HibernateBundle<>(AbstractModel.class, Feed.class, FeedCategory.class, FeedEntry.class,
|
bootstrap.addBundle(hibernateBundle = new HibernateBundle<>(AbstractModel.class, Feed.class, FeedCategory.class, FeedEntry.class,
|
||||||
FeedEntryContent.class, FeedEntryStatus.class, FeedEntryTag.class, FeedSubscription.class, User.class, UserRole.class,
|
FeedEntryContent.class, FeedEntryStatus.class, FeedEntryTag.class, FeedSubscription.class, User.class, UserRole.class,
|
||||||
UserSettings.class) {
|
UserSettings.class) {
|
||||||
@@ -195,10 +193,13 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WebSocket endpoint
|
// WebSocket endpoint
|
||||||
ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(WebSocketEndpoint.class, "/ws")
|
JakartaWebSocketServletContainerInitializer.configure(environment.getApplicationContext(), (context, container) -> {
|
||||||
.configurator(injector.getInstance(WebSocketConfigurator.class))
|
container.setDefaultMaxSessionIdleTimeout(config.getApplicationSettings().getWebsocketPingInterval().toMilliseconds() + 10000);
|
||||||
.build();
|
|
||||||
websocketBundle.addEndpoint(serverEndpointConfig);
|
container.addEndpoint(ServerEndpointConfig.Builder.create(WebSocketEndpoint.class, "/ws")
|
||||||
|
.configurator(injector.getInstance(WebSocketConfigurator.class))
|
||||||
|
.build());
|
||||||
|
});
|
||||||
|
|
||||||
// Scheduled tasks
|
// Scheduled tasks
|
||||||
Set<ScheduledTask> tasks = injector.getInstance(Key.get(new TypeLiteral<>() {
|
Set<ScheduledTask> tasks = injector.getInstance(Key.get(new TypeLiteral<>() {
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import com.commafeed.backend.cache.RedisPoolFactory;
|
|||||||
import com.commafeed.frontend.session.SessionHandlerFactory;
|
import com.commafeed.frontend.session.SessionHandlerFactory;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import be.tomcools.dropwizard.websocket.WebsocketBundleConfiguration;
|
|
||||||
import be.tomcools.dropwizard.websocket.WebsocketConfiguration;
|
|
||||||
import io.dropwizard.core.Configuration;
|
import io.dropwizard.core.Configuration;
|
||||||
import io.dropwizard.db.DataSourceFactory;
|
import io.dropwizard.db.DataSourceFactory;
|
||||||
import io.dropwizard.util.Duration;
|
import io.dropwizard.util.Duration;
|
||||||
@@ -25,7 +23,7 @@ import lombok.Setter;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class CommaFeedConfiguration extends Configuration implements WebsocketBundleConfiguration {
|
public class CommaFeedConfiguration extends Configuration {
|
||||||
|
|
||||||
public enum CacheType {
|
public enum CacheType {
|
||||||
NOOP, REDIS
|
NOOP, REDIS
|
||||||
@@ -68,13 +66,6 @@ public class CommaFeedConfiguration extends Configuration implements WebsocketBu
|
|||||||
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public WebsocketConfiguration getWebsocketConfiguration() {
|
|
||||||
WebsocketConfiguration config = new WebsocketConfiguration();
|
|
||||||
config.setMaxSessionIdleTimeout(getApplicationSettings().getWebsocketPingInterval().toMilliseconds() + 10000);
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public static class ApplicationSettings {
|
public static class ApplicationSettings {
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public class FeedRefreshUpdater {
|
|||||||
|
|
||||||
public boolean update(Feed feed, List<Entry> entries) {
|
public boolean update(Feed feed, List<Entry> entries) {
|
||||||
boolean processed = true;
|
boolean processed = true;
|
||||||
boolean insertedAtLeastOneEntry = false;
|
long inserted = 0;
|
||||||
|
|
||||||
if (!entries.isEmpty()) {
|
if (!entries.isEmpty()) {
|
||||||
Set<String> lastEntries = cache.getLastEntries(feed);
|
Set<String> lastEntries = cache.getLastEntries(feed);
|
||||||
@@ -134,7 +134,7 @@ public class FeedRefreshUpdater {
|
|||||||
}
|
}
|
||||||
AddEntryResult addEntryResult = addEntry(feed, entry, subscriptions);
|
AddEntryResult addEntryResult = addEntry(feed, entry, subscriptions);
|
||||||
processed &= addEntryResult.processed;
|
processed &= addEntryResult.processed;
|
||||||
insertedAtLeastOneEntry |= addEntryResult.inserted;
|
inserted += addEntryResult.inserted ? 1 : 0;
|
||||||
|
|
||||||
entryCacheMiss.mark();
|
entryCacheMiss.mark();
|
||||||
} else {
|
} else {
|
||||||
@@ -148,13 +148,12 @@ public class FeedRefreshUpdater {
|
|||||||
|
|
||||||
if (subscriptions == null) {
|
if (subscriptions == null) {
|
||||||
feed.setMessage("No new entries found");
|
feed.setMessage("No new entries found");
|
||||||
} else if (insertedAtLeastOneEntry) {
|
} else if (inserted > 0) {
|
||||||
List<User> users = subscriptions.stream().map(FeedSubscription::getUser).toList();
|
List<User> users = subscriptions.stream().map(FeedSubscription::getUser).toList();
|
||||||
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
|
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
|
||||||
cache.invalidateUserRootCategory(users.toArray(new User[0]));
|
cache.invalidateUserRootCategory(users.toArray(new User[0]));
|
||||||
|
|
||||||
// notify over websocket
|
notifyOverWebsocket(subscriptions, inserted);
|
||||||
subscriptions.forEach(sub -> webSocketSessions.sendMessage(sub.getUser(), WebSocketMessageBuilder.newFeedEntries(sub)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +162,7 @@ public class FeedRefreshUpdater {
|
|||||||
feed.setDisabledUntil(Instant.EPOCH);
|
feed.setDisabledUntil(Instant.EPOCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insertedAtLeastOneEntry) {
|
if (inserted > 0) {
|
||||||
feedUpdated.mark();
|
feedUpdated.mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +171,10 @@ public class FeedRefreshUpdater {
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyOverWebsocket(List<FeedSubscription> subscriptions, long inserted) {
|
||||||
|
subscriptions.forEach(sub -> webSocketSessions.sendMessage(sub.getUser(), WebSocketMessageBuilder.newFeedEntries(sub, inserted)));
|
||||||
|
}
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
private static class AddEntryResult {
|
private static class AddEntryResult {
|
||||||
private final boolean processed;
|
private final boolean processed;
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public class UserSettings extends AbstractModel {
|
|||||||
private boolean alwaysScrollToEntry;
|
private boolean alwaysScrollToEntry;
|
||||||
private boolean markAllAsReadConfirmation;
|
private boolean markAllAsReadConfirmation;
|
||||||
private boolean customContextMenu;
|
private boolean customContextMenu;
|
||||||
|
private boolean mobileFooter;
|
||||||
|
|
||||||
private boolean email;
|
private boolean email;
|
||||||
private boolean gmail;
|
private boolean gmail;
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public class Settings implements Serializable {
|
|||||||
@Schema(description = "show commafeed's own context menu on right click", requiredMode = RequiredMode.REQUIRED)
|
@Schema(description = "show commafeed's own context menu on right click", requiredMode = RequiredMode.REQUIRED)
|
||||||
private boolean customContextMenu;
|
private boolean customContextMenu;
|
||||||
|
|
||||||
|
@Schema(description = "on mobile, show action buttons at the bottom of the screen", requiredMode = RequiredMode.REQUIRED)
|
||||||
|
private boolean mobileFooter;
|
||||||
|
|
||||||
@Schema(description = "sharing settings", requiredMode = RequiredMode.REQUIRED)
|
@Schema(description = "sharing settings", requiredMode = RequiredMode.REQUIRED)
|
||||||
private SharingSettings sharingSettings = new SharingSettings();
|
private SharingSettings sharingSettings = new SharingSettings();
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ public class UserREST {
|
|||||||
s.setAlwaysScrollToEntry(settings.isAlwaysScrollToEntry());
|
s.setAlwaysScrollToEntry(settings.isAlwaysScrollToEntry());
|
||||||
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
|
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
|
||||||
s.setCustomContextMenu(settings.isCustomContextMenu());
|
s.setCustomContextMenu(settings.isCustomContextMenu());
|
||||||
|
s.setMobileFooter(settings.isMobileFooter());
|
||||||
} else {
|
} else {
|
||||||
s.setReadingMode(ReadingMode.unread.name());
|
s.setReadingMode(ReadingMode.unread.name());
|
||||||
s.setReadingOrder(ReadingOrder.desc.name());
|
s.setReadingOrder(ReadingOrder.desc.name());
|
||||||
@@ -131,6 +132,7 @@ public class UserREST {
|
|||||||
s.setAlwaysScrollToEntry(false);
|
s.setAlwaysScrollToEntry(false);
|
||||||
s.setMarkAllAsReadConfirmation(true);
|
s.setMarkAllAsReadConfirmation(true);
|
||||||
s.setCustomContextMenu(true);
|
s.setCustomContextMenu(true);
|
||||||
|
s.setMobileFooter(false);
|
||||||
}
|
}
|
||||||
return Response.ok(s).build();
|
return Response.ok(s).build();
|
||||||
}
|
}
|
||||||
@@ -159,6 +161,7 @@ public class UserREST {
|
|||||||
s.setAlwaysScrollToEntry(settings.isAlwaysScrollToEntry());
|
s.setAlwaysScrollToEntry(settings.isAlwaysScrollToEntry());
|
||||||
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
|
s.setMarkAllAsReadConfirmation(settings.isMarkAllAsReadConfirmation());
|
||||||
s.setCustomContextMenu(settings.isCustomContextMenu());
|
s.setCustomContextMenu(settings.isCustomContextMenu());
|
||||||
|
s.setMobileFooter(settings.isMobileFooter());
|
||||||
|
|
||||||
s.setEmail(settings.getSharingSettings().isEmail());
|
s.setEmail(settings.getSharingSettings().isEmail());
|
||||||
s.setGmail(settings.getSharingSettings().isGmail());
|
s.setGmail(settings.getSharingSettings().isGmail());
|
||||||
|
|||||||
@@ -84,13 +84,6 @@ public class FeverREST {
|
|||||||
private final FeedCategoryDAO feedCategoryDAO;
|
private final FeedCategoryDAO feedCategoryDAO;
|
||||||
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
||||||
|
|
||||||
@Path(PATH)
|
|
||||||
@GET
|
|
||||||
@Produces(MediaType.TEXT_PLAIN)
|
|
||||||
public String welcome() {
|
|
||||||
return "Welcome to the CommaFeed Fever API. Add this URL to your Fever-compatible reader.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// expected Fever API
|
// expected Fever API
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path(PATH)
|
@Path(PATH)
|
||||||
@@ -116,6 +109,18 @@ public class FeverREST {
|
|||||||
return handle(userId, params);
|
return handle(userId, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for some readers that use GET instead of POST
|
||||||
|
// e.g. Unread
|
||||||
|
@Path(PATH)
|
||||||
|
@GET
|
||||||
|
@UnitOfWork
|
||||||
|
@Timed
|
||||||
|
public FeverResponse get(@Context UriInfo uri, @PathParam("userId") Long userId) {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
uri.getQueryParameters().forEach((k, v) -> params.put(k, v.get(0)));
|
||||||
|
return handle(userId, params);
|
||||||
|
}
|
||||||
|
|
||||||
// workaround for some readers that post data using MultiPart FormData instead of the classic POST
|
// workaround for some readers that post data using MultiPart FormData instead of the classic POST
|
||||||
// e.g. Raven Reader
|
// e.g. Raven Reader
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class FeverResponse {
|
|||||||
private boolean auth;
|
private boolean auth;
|
||||||
|
|
||||||
@JsonProperty("last_refreshed_on_time")
|
@JsonProperty("last_refreshed_on_time")
|
||||||
private long lastRefreshedOnTime;
|
private Long lastRefreshedOnTime;
|
||||||
|
|
||||||
@JsonProperty("groups")
|
@JsonProperty("groups")
|
||||||
private List<FeverGroup> groups;
|
private List<FeverGroup> groups;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import lombok.experimental.UtilityClass;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class WebSocketMessageBuilder {
|
public class WebSocketMessageBuilder {
|
||||||
|
|
||||||
public static String newFeedEntries(FeedSubscription subscription) {
|
public static String newFeedEntries(FeedSubscription subscription, long count) {
|
||||||
return String.format("%s:%s", "new-feed-entries", subscription.getId());
|
return String.format("%s:%s:%s", "new-feed-entries", subscription.getId(), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
|
||||||
|
<changeSet id="use-timestamps" author="athou">
|
||||||
|
<validCheckSum>9:bf66bf7def9ec3dab1f365f7230d92cf</validCheckSum>
|
||||||
|
<modifyDataType tableName="FEEDS" columnName="lastUpdated" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDS" columnName="lastPublishedDate" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDS" columnName="lastEntryDate" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDS" columnName="disabledUntil" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDENTRIES" columnName="inserted" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDENTRIES" columnName="updated" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDENTRYSTATUSES" columnName="entryInserted" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="FEEDENTRYSTATUSES" columnName="entryUpdated" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="USERS" columnName="lastLogin" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="USERS" columnName="created" newDataType="${timestamp_type}" />
|
||||||
|
<modifyDataType tableName="USERS" columnName="recoverPasswordTokenDate" newDataType="${timestamp_type}" />
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="mobile-footer-setting" author="athou">
|
||||||
|
<addColumn tableName="USERSETTINGS">
|
||||||
|
<column name="mobileFooter" type="BOOLEAN" defaultValueBoolean="false">
|
||||||
|
<constraints nullable="false" />
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -4,9 +4,13 @@
|
|||||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
|
||||||
<property name="blob_type" value="bytea" dbms="postgresql" />
|
<property name="blob_type" value="bytea" dbms="postgresql" />
|
||||||
<property name="blob_type" value="blob" dbms="h2" />
|
<property name="blob_type" value="blob" dbms="h2,mysql,mariadb,mssql" />
|
||||||
<property name="blob_type" value="blob" dbms="mysql,mariadb" />
|
|
||||||
<property name="blob_type" value="blob" dbms="mssql" />
|
<!-- liquibase uses the 'TIMESTAMP WITHOUT TIME ZONE' type by default, which is not a UTC timestamp -->
|
||||||
|
<!-- postgresql UTC timestamp is actually 'TIMESTAMP WITH TIME ZONE' -->
|
||||||
|
<!-- see https://stackoverflow.com/a/48069726/1885506 -->
|
||||||
|
<property name="timestamp_type" value="timestamp with time zone" dbms="postgresql" />
|
||||||
|
<property name="timestamp_type" value="timestamp" dbms="h2,mysql,mariadb,mssql" />
|
||||||
|
|
||||||
<include file="changelogs/db.changelog-1.0.xml" />
|
<include file="changelogs/db.changelog-1.0.xml" />
|
||||||
<include file="changelogs/db.changelog-1.1.xml" />
|
<include file="changelogs/db.changelog-1.1.xml" />
|
||||||
@@ -24,5 +28,6 @@
|
|||||||
<include file="changelogs/db.changelog-3.9.xml" />
|
<include file="changelogs/db.changelog-3.9.xml" />
|
||||||
<include file="changelogs/db.changelog-4.0.xml" />
|
<include file="changelogs/db.changelog-4.0.xml" />
|
||||||
<include file="changelogs/db.changelog-4.1.xml" />
|
<include file="changelogs/db.changelog-4.1.xml" />
|
||||||
|
<include file="changelogs/db.changelog-4.2.xml" />
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -66,7 +66,7 @@ class WebSocketIT extends BaseIT {
|
|||||||
Long subscriptionId = subscribe(getFeedUrl());
|
Long subscriptionId = subscribe(getFeedUrl());
|
||||||
|
|
||||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||||
Assertions.assertEquals("new-feed-entries:" + subscriptionId, messageRef.get());
|
Assertions.assertEquals("new-feed-entries:" + subscriptionId + ":2", messageRef.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,15 +32,6 @@ class FeverIT extends BaseIT {
|
|||||||
this.userId = user.getId();
|
this.userId = user.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void get() {
|
|
||||||
String message = getClient().target(getApiBaseUrl() + "fever/user/${userId}")
|
|
||||||
.resolveTemplate("userId", 1)
|
|
||||||
.request()
|
|
||||||
.get(String.class);
|
|
||||||
Assertions.assertEquals("Welcome to the CommaFeed Fever API. Add this URL to your Fever-compatible reader.", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void invalidApiKey() {
|
void invalidApiKey() {
|
||||||
FeverResponse response = fetch("feeds", "invalid-key");
|
FeverResponse response = fetch("feeds", "invalid-key");
|
||||||
|
|||||||
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>4.1.0</version>
|
<version>4.2.0</version>
|
||||||
<name>CommaFeed</name>
|
<name>CommaFeed</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user