forked from Archives/Athou_commafeed
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
141a863079 | ||
|
|
6fa8d4be34 | ||
|
|
984e8a44d5 | ||
|
|
bdb296bce2 | ||
|
|
955a9084c3 | ||
|
|
70f486b0eb | ||
|
|
0bc383c6a8 | ||
|
|
0bb2b36585 | ||
|
|
9e3a24753a | ||
|
|
f2c400799e | ||
|
|
25a8c8a7e3 | ||
|
|
8f95d89fc6 | ||
|
|
39b0cdb9d5 | ||
|
|
42e06b848e | ||
|
|
7c3a13b1c4 | ||
|
|
151248fce2 | ||
|
|
6e8d6fe063 | ||
|
|
ca2da5e631 | ||
|
|
6cd3b70201 | ||
|
|
2dcfba75b5 | ||
|
|
44a51b03d3 | ||
|
|
6ee9e9831e | ||
|
|
68c717cee8 | ||
|
|
b15fc02c34 | ||
|
|
033ebfb497 | ||
|
|
4cceaa7650 | ||
|
|
5df47f1396 | ||
|
|
903f35c01b | ||
|
|
6a34f94277 | ||
|
|
dcc143eb7d | ||
|
|
fb47bf27e8 | ||
|
|
dcf969ff2e | ||
|
|
32c1318355 | ||
|
|
8ca6b89da4 | ||
|
|
b46c3a15f3 | ||
|
|
cbc5e014f7 | ||
|
|
8925b248e4 | ||
|
|
cc6aa2bbc5 | ||
|
|
1989aaf8b4 | ||
|
|
c90c91b748 | ||
|
|
bca23db213 | ||
|
|
c9a92d2043 | ||
|
|
c48e06fa46 | ||
|
|
5529eced91 | ||
|
|
2a0d935471 | ||
|
|
6c68fda572 | ||
|
|
861c1fc3dc | ||
|
|
5971bb4255 | ||
|
|
76ba360631 | ||
|
|
89d3ff3c90 | ||
|
|
34024a913d | ||
|
|
a858380121 | ||
|
|
e1dc870005 | ||
|
|
2fc1cac869 | ||
|
|
f627ff4958 | ||
|
|
5ff8e51948 | ||
|
|
538f25c6bb | ||
|
|
65100ba279 | ||
|
|
79fd470bbf | ||
|
|
866d74665b | ||
|
|
29da74f038 | ||
|
|
3c8ac35a46 | ||
|
|
afe957ba59 | ||
|
|
7e50e99351 | ||
|
|
62ce462cc8 | ||
|
|
108cb06f43 | ||
|
|
95a38675bc | ||
|
|
714681bc50 | ||
|
|
0f8d91d997 | ||
|
|
562297a82f | ||
|
|
b108bf06e5 | ||
|
|
3c819066fd | ||
|
|
5f30cb7e2e | ||
|
|
5a95b95801 | ||
|
|
eb573fdc8b | ||
|
|
238ea54e98 | ||
|
|
e4dfc47fb8 | ||
|
|
a1491c779a | ||
|
|
dabd7552be | ||
|
|
0a4c56af1f | ||
|
|
c3dae5b92c | ||
|
|
2c3105b526 | ||
|
|
20f5081ac8 | ||
|
|
3091eb9d14 | ||
|
|
5bdda42239 | ||
|
|
7eda8b7662 | ||
|
|
fc94ce5d2b | ||
|
|
e5d7161ab7 | ||
|
|
f725cb7fa4 | ||
|
|
830e689fe8 |
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Checkout
|
# Checkout
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -48,19 +48,19 @@ jobs:
|
|||||||
run: mkdir -p target/pages/documentation/custom-css
|
run: mkdir -p target/pages/documentation/custom-css
|
||||||
|
|
||||||
- name: Convert readme file to html
|
- name: Convert readme file to html
|
||||||
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
|
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
|
||||||
with:
|
with:
|
||||||
source: README.md
|
source: README.md
|
||||||
output: target/pages/index.html
|
output: target/pages/index.html
|
||||||
|
|
||||||
- name: Convert config documentation to html
|
- name: Convert config documentation to html
|
||||||
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
|
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
|
||||||
with:
|
with:
|
||||||
source: commafeed-server/target/quarkus-generated-doc/config/commafeed-server.md
|
source: commafeed-server/target/quarkus-generated-doc/config/commafeed-server.md
|
||||||
output: target/pages/documentation/index.html
|
output: target/pages/documentation/index.html
|
||||||
|
|
||||||
- name: Convert custom css documentation to html
|
- name: Convert custom css documentation to html
|
||||||
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
|
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
|
||||||
with:
|
with:
|
||||||
source: documentation/CUSTOMCSS.md
|
source: documentation/CUSTOMCSS.md
|
||||||
output: target/pages/documentation/custom-css/index.html
|
output: target/pages/documentation/custom-css/index.html
|
||||||
@@ -98,7 +98,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Checkout
|
# Checkout
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ jobs:
|
|||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
- name: Login to Container Registry
|
- name: Login to Container Registry
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||||
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
@@ -215,7 +215,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [6.2.0]
|
||||||
|
|
||||||
|
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new `commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want to keep deleting starred entries during normal entries cleanup (#1581)
|
||||||
|
|
||||||
|
## [6.1.1]
|
||||||
|
|
||||||
|
- Fix old starred entries not loading if they were marked as read (#2031)
|
||||||
|
|
||||||
|
## [6.1.0]
|
||||||
|
|
||||||
|
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now redirected to a page where they can set their own password (#2023)
|
||||||
|
- Use browser preferred language instead of English when using CommaFeed for the first time (#2018)
|
||||||
|
- The profile menu is now closed when scrolling the page (#2019)
|
||||||
|
- The "disable pull to refresh" feature is now disabled by default (#2030)
|
||||||
|
|
||||||
## [6.0.0]
|
## [6.0.0]
|
||||||
|
|
||||||
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup wizard will guide you through the creation of an admin account
|
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup wizard will guide you through the creation of an admin account
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 4,
|
"indentWidth": 4,
|
||||||
|
|||||||
1547
commafeed-client/package-lock.json
generated
1547
commafeed-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,31 +17,31 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@fontsource/open-sans": "^5.2.7",
|
"@fontsource/open-sans": "^5.2.7",
|
||||||
"@lingui/core": "^5.7.0",
|
"@lingui/core": "^5.9.0",
|
||||||
"@lingui/react": "^5.7.0",
|
"@lingui/react": "^5.9.0",
|
||||||
"@mantine/core": "^8.3.11",
|
"@mantine/core": "^8.3.14",
|
||||||
"@mantine/form": "^8.3.11",
|
"@mantine/form": "^8.3.14",
|
||||||
"@mantine/hooks": "^8.3.11",
|
"@mantine/hooks": "^8.3.14",
|
||||||
"@mantine/modals": "^8.3.11",
|
"@mantine/modals": "^8.3.14",
|
||||||
"@mantine/notifications": "^8.3.11",
|
"@mantine/notifications": "^8.3.14",
|
||||||
"@mantine/spotlight": "^8.3.11",
|
"@mantine/spotlight": "^8.3.14",
|
||||||
"@monaco-editor/react": "^4.7.0",
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@reduxjs/toolkit": "^2.11.2",
|
"@reduxjs/toolkit": "^2.11.2",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.4",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"escape-string-regexp": "^5.0.0",
|
"escape-string-regexp": "^5.0.0",
|
||||||
"interweave": "^13.1.1",
|
"interweave": "^13.1.1",
|
||||||
"monaco-editor": "^0.55.1",
|
"monaco-editor": "^0.55.1",
|
||||||
"mousetrap": "^1.6.5",
|
"mousetrap": "^1.6.5",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.4",
|
||||||
"react-async-hook": "^4.0.0",
|
"react-async-hook": "^4.0.0",
|
||||||
"react-contexify": "^6.0.0",
|
"react-contexify": "^6.0.0",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.4",
|
||||||
"react-draggable": "^4.5.0",
|
"react-draggable": "^4.5.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-infinite-scroller": "^1.2.6",
|
"react-infinite-scroller": "^1.2.6",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.11.0",
|
"react-router-dom": "^7.13.0",
|
||||||
"react-swipeable": "^7.0.2",
|
"react-swipeable": "^7.0.2",
|
||||||
"style-to-object": "^1.0.14",
|
"style-to-object": "^1.0.14",
|
||||||
"throttle-debounce": "^5.0.2",
|
"throttle-debounce": "^5.0.2",
|
||||||
@@ -50,32 +50,32 @@
|
|||||||
"websocket-heartbeat-js": "^1.1.3"
|
"websocket-heartbeat-js": "^1.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.3.11",
|
"@biomejs/biome": "^2.3.14",
|
||||||
"@lingui/babel-plugin-lingui-macro": "^5.7.0",
|
"@lingui/babel-plugin-lingui-macro": "^5.9.0",
|
||||||
"@lingui/cli": "^5.7.0",
|
"@lingui/cli": "^5.9.0",
|
||||||
"@lingui/vite-plugin": "^5.7.0",
|
"@lingui/vite-plugin": "^5.9.0",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
"@testing-library/react": "^16.3.1",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/mousetrap": "^1.6.15",
|
"@types/mousetrap": "^1.6.15",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.13",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/react-infinite-scroller": "^1.2.5",
|
"@types/react-infinite-scroller": "^1.2.5",
|
||||||
"@types/throttle-debounce": "^5.0.2",
|
"@types/throttle-debounce": "^5.0.2",
|
||||||
"@types/tinycon": "^0.6.7",
|
"@types/tinycon": "^0.6.7",
|
||||||
"@vitejs/plugin-react": "^5.1.2",
|
"@vitejs/plugin-react": "^5.1.3",
|
||||||
"babel-plugin-react-compiler": "1.0.0",
|
"babel-plugin-react-compiler": "1.0.0",
|
||||||
"jsdom": "^27.4.0",
|
"jsdom": "^28.0.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-checker": "^0.12.0",
|
"vite-plugin-checker": "^0.12.0",
|
||||||
"vite-tsconfig-paths": "^6.0.3",
|
"vite-tsconfig-paths": "^6.0.5",
|
||||||
"vitest": "^4.0.16",
|
"vitest": "^4.0.18",
|
||||||
"yaml": "^2.8.2"
|
"yaml": "^2.8.2"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"react-infinite-scroller": {
|
"react-infinite-scroller": {
|
||||||
"react": "^19.2.3"
|
"react": "^19.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>6.0.0</version>
|
<version>6.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<name>CommaFeed Client</name>
|
<name>CommaFeed Client</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- renovate: datasource=node-version depName=node -->
|
<!-- renovate: datasource=node-version depName=node -->
|
||||||
<node.version>v24.12.0</node.version>
|
<node.version>v24.13.0</node.version>
|
||||||
<!-- renovate: datasource=npm depName=npm -->
|
<!-- renovate: datasource=npm depName=npm -->
|
||||||
<npm.version>11.7.0</npm.version>
|
<npm.version>11.9.0</npm.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import { TagDetailsPage } from "@/pages/app/TagDetailsPage"
|
|||||||
import { InitialSetupPage } from "@/pages/auth/InitialSetupPage"
|
import { InitialSetupPage } from "@/pages/auth/InitialSetupPage"
|
||||||
import { LoginPage } from "@/pages/auth/LoginPage"
|
import { LoginPage } from "@/pages/auth/LoginPage"
|
||||||
import { PasswordRecoveryPage } from "@/pages/auth/PasswordRecoveryPage"
|
import { PasswordRecoveryPage } from "@/pages/auth/PasswordRecoveryPage"
|
||||||
|
import { PasswordResetPage } from "@/pages/auth/PasswordResetPage"
|
||||||
import { RegistrationPage } from "@/pages/auth/RegistrationPage"
|
import { RegistrationPage } from "@/pages/auth/RegistrationPage"
|
||||||
import { WelcomePage } from "@/pages/WelcomePage"
|
import { WelcomePage } from "@/pages/WelcomePage"
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ function AppRoutes() {
|
|||||||
<Route path="login" element={<LoginPage />} />
|
<Route path="login" element={<LoginPage />} />
|
||||||
<Route path="register" element={<RegistrationPage />} />
|
<Route path="register" element={<RegistrationPage />} />
|
||||||
<Route path="passwordRecovery" element={<PasswordRecoveryPage />} />
|
<Route path="passwordRecovery" element={<PasswordRecoveryPage />} />
|
||||||
|
<Route path="passwordReset" element={<PasswordResetPage />} />
|
||||||
<Route path="app" element={<Layout header={<Header />} sidebar={<Tree />} sidebarVisible={sidebarVisible} />}>
|
<Route path="app" element={<Layout header={<Header />} sidebar={<Tree />} sidebarVisible={sidebarVisible} />}>
|
||||||
<Route path="category">
|
<Route path="category">
|
||||||
<Route path=":id" element={<FeedEntriesPage sourceType="category" />} />
|
<Route path=":id" element={<FeedEntriesPage sourceType="category" />} />
|
||||||
@@ -193,6 +195,8 @@ function CustomJsHandler() {
|
|||||||
document.body.appendChild(script)
|
document.body.appendChild(script)
|
||||||
|
|
||||||
setScriptLoaded(true)
|
setScriptLoaded(true)
|
||||||
|
|
||||||
|
return () => script.remove()
|
||||||
}, [scriptLoaded, loading])
|
}, [scriptLoaded, loading])
|
||||||
|
|
||||||
return null
|
return null
|
||||||
@@ -205,6 +209,8 @@ function CustomCssHandler() {
|
|||||||
link.type = "text/css"
|
link.type = "text/css"
|
||||||
link.href = "custom_css.css"
|
link.href = "custom_css.css"
|
||||||
document.head.appendChild(link)
|
document.head.appendChild(link)
|
||||||
|
|
||||||
|
return () => link.remove()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import type {
|
|||||||
MarkRequest,
|
MarkRequest,
|
||||||
Metrics,
|
Metrics,
|
||||||
MultipleMarkRequest,
|
MultipleMarkRequest,
|
||||||
|
PasswordResetConfirmationRequest,
|
||||||
PasswordResetRequest,
|
PasswordResetRequest,
|
||||||
ProfileModificationRequest,
|
ProfileModificationRequest,
|
||||||
RegistrationRequest,
|
RegistrationRequest,
|
||||||
@@ -97,6 +98,7 @@ export const client = {
|
|||||||
register: async (req: RegistrationRequest) => await axiosInstance.post("user/register", req),
|
register: async (req: RegistrationRequest) => await axiosInstance.post("user/register", req),
|
||||||
initialSetup: async (req: InitialSetupRequest) => await axiosInstance.post("user/initialSetup", req),
|
initialSetup: async (req: InitialSetupRequest) => await axiosInstance.post("user/initialSetup", req),
|
||||||
passwordReset: async (req: PasswordResetRequest) => await axiosInstance.post("user/passwordReset", req),
|
passwordReset: async (req: PasswordResetRequest) => await axiosInstance.post("user/passwordReset", req),
|
||||||
|
passwordResetCallback: async (req: PasswordResetConfirmationRequest) => await axiosInstance.post("user/passwordResetCallback", req),
|
||||||
getSettings: async () => await axiosInstance.get<Settings>("user/settings"),
|
getSettings: async () => await axiosInstance.get<Settings>("user/settings"),
|
||||||
saveSettings: async (settings: Settings) => await axiosInstance.post("user/settings", settings),
|
saveSettings: async (settings: Settings) => await axiosInstance.post("user/settings", settings),
|
||||||
getProfile: async () => await axiosInstance.get<UserModel>("user/profile"),
|
getProfile: async () => await axiosInstance.get<UserModel>("user/profile"),
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ export const loadMoreEntries = createAppAsyncThunk("entries/loadMore", async (_,
|
|||||||
const state = thunkApi.getState()
|
const state = thunkApi.getState()
|
||||||
const { source } = state.entries
|
const { source } = state.entries
|
||||||
const offset =
|
const offset =
|
||||||
state.user.settings?.readingMode === "all" ? state.entries.entries.length : state.entries.entries.filter(e => !e.read).length
|
state.user.settings?.readingMode === "all" || (source.type === "category" && source.id === "starred")
|
||||||
|
? state.entries.entries.length
|
||||||
|
: state.entries.entries.filter(e => !e.read).length
|
||||||
const endpoint = getEndpoint(state.entries.source.type)
|
const endpoint = getEndpoint(state.entries.source.type)
|
||||||
const result = await endpoint(buildGetEntriesPaginatedRequest(state, source, offset))
|
const result = await endpoint(buildGetEntriesPaginatedRequest(state, source, offset))
|
||||||
return result.data
|
return result.data
|
||||||
|
|||||||
@@ -196,6 +196,12 @@ export interface PasswordResetRequest {
|
|||||||
email: string
|
email: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PasswordResetConfirmationRequest {
|
||||||
|
email: string
|
||||||
|
token: string
|
||||||
|
password: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ProfileModificationRequest {
|
export interface ProfileModificationRequest {
|
||||||
currentPassword: string
|
currentPassword: string
|
||||||
email: string
|
email: string
|
||||||
@@ -228,6 +234,7 @@ export interface ServerInfo {
|
|||||||
treeReloadInterval: number
|
treeReloadInterval: number
|
||||||
forceRefreshCooldownDuration: number
|
forceRefreshCooldownDuration: number
|
||||||
initialSetupRequired: boolean
|
initialSetupRequired: boolean
|
||||||
|
minimumPasswordLength: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SharingSettings {
|
export interface SharingSettings {
|
||||||
@@ -242,7 +249,7 @@ export interface SharingSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Settings {
|
export interface Settings {
|
||||||
language: string
|
language?: string
|
||||||
readingMode: ReadingMode
|
readingMode: ReadingMode
|
||||||
readingOrder: ReadingOrder
|
readingOrder: ReadingOrder
|
||||||
showRead: boolean
|
showRead: boolean
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
} from "@mantine/core"
|
} from "@mantine/core"
|
||||||
import { showNotification } from "@mantine/notifications"
|
import { showNotification } from "@mantine/notifications"
|
||||||
import dayjs from "dayjs"
|
import dayjs from "dayjs"
|
||||||
import { type ReactNode, useState } from "react"
|
import { type ReactNode, useEffect, useState } from "react"
|
||||||
import {
|
import {
|
||||||
TbChartLine,
|
TbChartLine,
|
||||||
TbHeartFilled,
|
TbHeartFilled,
|
||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
TbUsers,
|
TbUsers,
|
||||||
TbWorldDownload,
|
TbWorldDownload,
|
||||||
} from "react-icons/tb"
|
} from "react-icons/tb"
|
||||||
|
import { throttle } from "throttle-debounce"
|
||||||
import { client } from "@/app/client"
|
import { client } from "@/app/client"
|
||||||
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "@/app/redirect/thunks"
|
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "@/app/redirect/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
@@ -96,6 +97,14 @@ const viewModeData: ViewModeControlItem[] = [
|
|||||||
|
|
||||||
export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
|
export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
|
||||||
const [opened, setOpened] = useState(false)
|
const [opened, setOpened] = useState(false)
|
||||||
|
|
||||||
|
// close profile menu on scroll
|
||||||
|
useEffect(() => {
|
||||||
|
const listener = throttle(100, () => setOpened(false))
|
||||||
|
window.addEventListener("scroll", listener)
|
||||||
|
return () => window.removeEventListener("scroll", listener)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const now = useNow()
|
const now = useNow()
|
||||||
const profile = useAppSelector(state => state.user.profile)
|
const profile = useAppSelector(state => state.user.profile)
|
||||||
const admin = useAppSelector(state => state.user.profile?.admin)
|
const admin = useAppSelector(state => state.user.profile?.admin)
|
||||||
|
|||||||
@@ -143,6 +143,47 @@ export function DisplaySettings() {
|
|||||||
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
|
||||||
|
description={<Trans>This setting can cause scrolling issues on some browsers (e.g. Safari)</Trans>}
|
||||||
|
checked={disablePullToRefresh}
|
||||||
|
onChange={async e => await dispatch(changeDisablePullToRefresh(e.currentTarget.checked))}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Radio.Group
|
||||||
|
label={<Trans>Scroll selected entry to the top of the page</Trans>}
|
||||||
|
value={scrollMode}
|
||||||
|
onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))}
|
||||||
|
>
|
||||||
|
<Group mt="xs">
|
||||||
|
{Object.entries(scrollModeOptions).map(e => (
|
||||||
|
<Radio key={e[0]} value={e[0]} label={e[1]} />
|
||||||
|
))}
|
||||||
|
</Group>
|
||||||
|
</Radio.Group>
|
||||||
|
|
||||||
|
<NumberInput
|
||||||
|
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
|
||||||
|
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
|
||||||
|
min={0}
|
||||||
|
value={entriesToKeepOnTop}
|
||||||
|
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
|
||||||
|
checked={scrollSpeed ? scrollSpeed > 0 : false}
|
||||||
|
onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
|
||||||
|
checked={scrollMarks}
|
||||||
|
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
|
||||||
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
@@ -179,47 +220,6 @@ export function DisplaySettings() {
|
|||||||
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
|
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
|
|
||||||
|
|
||||||
<Radio.Group
|
|
||||||
label={<Trans>Scroll selected entry to the top of the page</Trans>}
|
|
||||||
value={scrollMode}
|
|
||||||
onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))}
|
|
||||||
>
|
|
||||||
<Group mt="xs">
|
|
||||||
{Object.entries(scrollModeOptions).map(e => (
|
|
||||||
<Radio key={e[0]} value={e[0]} label={e[1]} />
|
|
||||||
))}
|
|
||||||
</Group>
|
|
||||||
</Radio.Group>
|
|
||||||
|
|
||||||
<NumberInput
|
|
||||||
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
|
|
||||||
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
|
|
||||||
min={0}
|
|
||||||
value={entriesToKeepOnTop}
|
|
||||||
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
|
|
||||||
checked={scrollSpeed ? scrollSpeed > 0 : false}
|
|
||||||
onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
|
|
||||||
checked={scrollMarks}
|
|
||||||
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
|
|
||||||
description={<Trans>This setting can cause scrolling issues on some browsers (e.g. Safari)</Trans>}
|
|
||||||
checked={disablePullToRefresh}
|
|
||||||
onChange={async e => await dispatch(changeDisablePullToRefresh(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}>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { msg } from "@lingui/core/macro"
|
|
||||||
import { useLingui } from "@lingui/react"
|
import { useLingui } from "@lingui/react"
|
||||||
import { Trans } from "@lingui/react/macro"
|
import { Trans } from "@lingui/react/macro"
|
||||||
import { Anchor, Box, Button, Checkbox, Divider, Group, Input, PasswordInput, Stack, Text, TextInput } from "@mantine/core"
|
import { Anchor, Box, Button, Checkbox, Divider, Group, Input, PasswordInput, Stack, Text, TextInput } from "@mantine/core"
|
||||||
@@ -13,6 +12,7 @@ import { useAppDispatch, useAppSelector } from "@/app/store"
|
|||||||
import type { ProfileModificationRequest } from "@/app/types"
|
import type { ProfileModificationRequest } from "@/app/types"
|
||||||
import { reloadProfile } from "@/app/user/thunks"
|
import { reloadProfile } from "@/app/user/thunks"
|
||||||
import { Alert } from "@/components/Alert"
|
import { Alert } from "@/components/Alert"
|
||||||
|
import { useValidationRules } from "@/hooks/useValidationRules"
|
||||||
|
|
||||||
interface FormData extends ProfileModificationRequest {
|
interface FormData extends ProfileModificationRequest {
|
||||||
newPasswordConfirmation?: string
|
newPasswordConfirmation?: string
|
||||||
@@ -23,11 +23,14 @@ export function ProfileSettings() {
|
|||||||
const serverInfos = useAppSelector(state => state.server.serverInfos)
|
const serverInfos = useAppSelector(state => state.server.serverInfos)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { _ } = useLingui()
|
const { _ } = useLingui()
|
||||||
|
const validationRules = useValidationRules()
|
||||||
|
|
||||||
const form = useForm<FormData>({
|
const form = useForm<FormData>({
|
||||||
validate: {
|
validate: {
|
||||||
newPasswordConfirmation: (value, values) => (value !== values.newPassword ? _(msg`Passwords do not match`) : null),
|
newPassword: validationRules.password,
|
||||||
|
newPasswordConfirmation: (value, values) => validationRules.passwordConfirmation(value, values.newPassword),
|
||||||
},
|
},
|
||||||
|
validateInputOnChange: true,
|
||||||
})
|
})
|
||||||
const { setValues } = form
|
const { setValues } = form
|
||||||
|
|
||||||
|
|||||||
17
commafeed-client/src/hooks/useValidationRules.ts
Normal file
17
commafeed-client/src/hooks/useValidationRules.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { msg } from "@lingui/core/macro"
|
||||||
|
import { useLingui } from "@lingui/react"
|
||||||
|
import { useAppSelector } from "@/app/store"
|
||||||
|
|
||||||
|
export function useValidationRules() {
|
||||||
|
const minimumPasswordLength = useAppSelector(state => state.server.serverInfos?.minimumPasswordLength)
|
||||||
|
const { _ } = useLingui()
|
||||||
|
|
||||||
|
return {
|
||||||
|
password: (value: string | undefined) =>
|
||||||
|
value && minimumPasswordLength && value.length < minimumPasswordLength
|
||||||
|
? _(msg`Password must be at least ${minimumPasswordLength} characters`)
|
||||||
|
: null,
|
||||||
|
passwordConfirmation: (newPasswordConfirmation: string | undefined, newPassword: string | undefined) =>
|
||||||
|
newPasswordConfirmation && newPasswordConfirmation !== newPassword ? _(msg`Passwords do not match`) : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "العودة"
|
msgstr "العودة"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "العودة لتسجيل الدخول"
|
msgstr "العودة لتسجيل الدخول"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "تأكيد"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "تأكيد كلمة المرور"
|
msgstr "تأكيد كلمة المرور"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "دافئ"
|
msgstr "دافئ"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "كلمة مرور جديدة"
|
msgstr "كلمة مرور جديدة"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "الأحدث أولاً"
|
msgstr "الأحدث أولاً"
|
||||||
@@ -771,11 +786,15 @@ msgstr "الفئة الأصل"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "كلمة المرور"
|
msgstr "كلمة المرور"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "استعادة كلمة المرور"
|
msgstr "استعادة كلمة المرور"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "كلمات المرور غير متطابقة"
|
msgstr "كلمات المرور غير متطابقة"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "تحديث"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "تم إغلاق التسجيلات في مثيل CommaFeed هذا"
|
msgstr "تم إغلاق التسجيلات في مثيل CommaFeed هذا"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "إلغاء النجم"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "إلغاء الاشتراك"
|
msgstr "إلغاء الاشتراك"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "اسم المستخدم"
|
msgstr "اسم المستخدم"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "ليس لديك أي اشتراكات حتى الآن. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Enrere"
|
msgstr "Enrere"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Torna a iniciar sessió"
|
msgstr "Torna a iniciar sessió"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Confirma"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmeu la contrasenya"
|
msgstr "Confirmeu la contrasenya"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Acollidor"
|
msgstr "Acollidor"
|
||||||
@@ -491,6 +497,10 @@ msgstr "Indi"
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "Mai"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Contrasenya nova"
|
msgstr "Contrasenya nova"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "El més nou primer"
|
msgstr "El més nou primer"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Categoria pare"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contrasenya"
|
msgstr "Contrasenya"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Recuperació de contrasenya"
|
msgstr "Recuperació de contrasenya"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Les contrasenyes no coincideixen"
|
msgstr "Les contrasenyes no coincideixen"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Actualitzar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Els registres estan tancats en aquesta instància de CommaFeed"
|
msgstr "Els registres estan tancats en aquesta instància de CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Desestrellar"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Donar-se de baixa"
|
msgstr "Donar-se de baixa"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nom d'usuari"
|
msgstr "Nom d'usuari"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Encara no teniu cap subscripció. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Els vostres feeds s'han posat a la cua per actualitzar-los."
|
msgstr "Els vostres feeds s'han posat a la cua per actualitzar-los."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Zpět"
|
msgstr "Zpět"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Zpět k přihlášení"
|
msgstr "Zpět k přihlášení"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Potvrdit"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potvrďte heslo"
|
msgstr "Potvrďte heslo"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Útulný"
|
msgstr "Útulný"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nejnovější jako první"
|
msgstr "Nejnovější jako první"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Rodičovská kategorie"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Heslo"
|
msgstr "Heslo"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Obnovení hesla"
|
msgstr "Obnovení hesla"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Hesla se neshodují"
|
msgstr "Hesla se neshodují"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Obnovit"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "V této instanci CommaFeed jsou registrace uzavřeny"
|
msgstr "V této instanci CommaFeed jsou registrace uzavřeny"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Odstranit hvězdu"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Odhlásit odběr"
|
msgstr "Odhlásit odběr"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Uživatelské jméno"
|
msgstr "Uživatelské jméno"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Zatím nemáte žádné předplatné. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Yn ôl"
|
msgstr "Yn ôl"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Yn ôl i fewngofnodi"
|
msgstr "Yn ôl i fewngofnodi"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Cadarnhau"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Cadarnhau'r cyfrinair"
|
msgstr "Cadarnhau'r cyfrinair"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "clyd"
|
msgstr "clyd"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Cyfrinair newydd"
|
msgstr "Cyfrinair newydd"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Y diweddaraf yn gyntaf"
|
msgstr "Y diweddaraf yn gyntaf"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Categori Rhiant"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "cyfrinair"
|
msgstr "cyfrinair"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Adfer Cyfrinair"
|
msgstr "Adfer Cyfrinair"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Nid yw cyfrineiriau yn cyfateb"
|
msgstr "Nid yw cyfrineiriau yn cyfateb"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Adnewyddu"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Mae cofrestriadau ar gau ar yr achos CommaFeed hwn"
|
msgstr "Mae cofrestriadau ar gau ar yr achos CommaFeed hwn"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "dad-seren"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Dad-danysgrifio"
|
msgstr "Dad-danysgrifio"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Enw defnyddiwr"
|
msgstr "Enw defnyddiwr"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Nid oes gennych unrhyw danysgrifiadau eto. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Tilbage"
|
msgstr "Tilbage"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Tilbage for at logge ind"
|
msgstr "Tilbage for at logge ind"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bekræft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekræft adgangskode"
|
msgstr "Bekræft adgangskode"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Hyggeligt"
|
msgstr "Hyggeligt"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Ny adgangskode"
|
msgstr "Ny adgangskode"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nyeste først"
|
msgstr "Nyeste først"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Forældrekategori"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Adgangskode"
|
msgstr "Adgangskode"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Gendannelse af adgangskode"
|
msgstr "Gendannelse af adgangskode"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Adgangskoder stemmer ikke overens"
|
msgstr "Adgangskoder stemmer ikke overens"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Opdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er lukket på denne CommaFeed-instans"
|
msgstr "Registreringer er lukket på denne CommaFeed-instans"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr ""
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Afmeld"
|
msgstr "Afmeld"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brugernavn"
|
msgstr "Brugernavn"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Du har ingen abonnementer endnu. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Zurück zum Login"
|
msgstr "Zurück zum Login"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bestätigen"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Passwort bestätigen"
|
msgstr "Passwort bestätigen"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Gemütlich"
|
msgstr "Gemütlich"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "Niemals"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Neues Passwort"
|
msgstr "Neues Passwort"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Neueste zuerst"
|
msgstr "Neueste zuerst"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Übergeordnete Kategorie"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passwort"
|
msgstr "Passwort"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Passwortwiederherstellung"
|
msgstr "Passwortwiederherstellung"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Passwörter stimmen nicht überein"
|
msgstr "Passwörter stimmen nicht überein"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Aktualisieren"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registrierungen sind für diese CommaFeed-Instanz geschlossen"
|
msgstr "Registrierungen sind für diese CommaFeed-Instanz geschlossen"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST-API"
|
msgstr "REST-API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Stern entfernen"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Abbestellen"
|
msgstr "Abbestellen"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Benutzername"
|
msgstr "Benutzername"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Sie haben noch keine Abonnements."
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Ihr Feed wurde für die Aktualisierung eingereiht."
|
msgstr "Ihr Feed wurde für die Aktualisierung eingereiht."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Back"
|
msgstr "Back"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Back to log in"
|
msgstr "Back to log in"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Confirm"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirm password"
|
msgstr "Confirm password"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr "Confirm Password"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Cozy"
|
msgstr "Cozy"
|
||||||
@@ -491,6 +497,10 @@ msgstr "Indigo"
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr "Initial Setup"
|
msgstr "Initial Setup"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr "Invalid password reset link. Please request a new one."
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "Never"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "New password"
|
msgstr "New password"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr "New Password"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Newest first"
|
msgstr "Newest first"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Parent Category"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Password"
|
msgstr "Password"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Password Recovery"
|
msgstr "Password Recovery"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Passwords do not match"
|
msgstr "Passwords do not match"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Refresh"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registrations are closed on this CommaFeed instance"
|
msgstr "Registrations are closed on this CommaFeed instance"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr "Reset Password"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Unstar"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Unsubscribe"
|
msgstr "Unsubscribe"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr "User created."
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "User name"
|
msgstr "User name"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "You don't have any subscriptions yet. Why not try adding one by clicking
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Your feeds have been queued for refresh."
|
msgstr "Your feeds have been queued for refresh."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr "Your password has been changed. You can now log in with your new password."
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ msgid "Back"
|
|||||||
msgstr "Atrás"
|
msgstr "Atrás"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Volver a iniciar sesión"
|
msgstr "Volver a iniciar sesión"
|
||||||
|
|
||||||
@@ -227,6 +228,11 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar contraseña"
|
msgstr "Confirmar contraseña"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Acogedor"
|
msgstr "Acogedor"
|
||||||
@@ -492,6 +498,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -635,6 +645,11 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nueva contraseña"
|
msgstr "Nueva contraseña"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Las más recientes primero"
|
msgstr "Las más recientes primero"
|
||||||
@@ -772,11 +787,15 @@ msgstr "Categoría principal"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contraseña"
|
msgstr "Contraseña"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Recuperación de contraseña"
|
msgstr "Recuperación de contraseña"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Las contraseñas no coinciden"
|
msgstr "Las contraseñas no coinciden"
|
||||||
|
|
||||||
@@ -818,6 +837,11 @@ msgstr "Actualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Los registros están cerrados en esta instancia de CommaFeed"
|
msgstr "Los registros están cerrados en esta instancia de CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1057,10 +1081,6 @@ msgstr "Desmarcar"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar suscripción"
|
msgstr "Cancelar suscripción"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nombre de usuario"
|
msgstr "Nombre de usuario"
|
||||||
@@ -1097,3 +1117,7 @@ msgstr "Aún no tienes ninguna suscripción. ¿Por qué no intentas agregar una
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Tus feeds se han puesto en cola para actualizarse."
|
msgstr "Tus feeds se han puesto en cola para actualizarse."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "برگشت"
|
msgstr "برگشت"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "بازگشت برای ورود به سیستم"
|
msgstr "بازگشت برای ورود به سیستم"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "تأیید کنید"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "رمز عبور را تأیید کنید"
|
msgstr "رمز عبور را تأیید کنید"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "دنج"
|
msgstr "دنج"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "رمز عبور جدید"
|
msgstr "رمز عبور جدید"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "ابتدا جدیدترین"
|
msgstr "ابتدا جدیدترین"
|
||||||
@@ -771,11 +786,15 @@ msgstr "دسته والد"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "رمز عبور"
|
msgstr "رمز عبور"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "بازیابی رمز عبور"
|
msgstr "بازیابی رمز عبور"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "گذرواژه ها مطابقت ندارند"
|
msgstr "گذرواژه ها مطابقت ندارند"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "تازه کردن"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "ثبت نام در این نمونه CommaFeed بسته شده است"
|
msgstr "ثبت نام در این نمونه CommaFeed بسته شده است"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr ""
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "لغو اشتراک"
|
msgstr "لغو اشتراک"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "نام کاربری"
|
msgstr "نام کاربری"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "شما هنوز هیچ اشتراکی ندارید. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Takaisin"
|
msgstr "Takaisin"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Takaisin sisäänkirjautumiseen"
|
msgstr "Takaisin sisäänkirjautumiseen"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Vahvista"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Vahvista salasana"
|
msgstr "Vahvista salasana"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Viihtyisä"
|
msgstr "Viihtyisä"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Uusi salasana"
|
msgstr "Uusi salasana"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Uusin ensin"
|
msgstr "Uusin ensin"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Pääluokka"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Salasana"
|
msgstr "Salasana"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Salasanan palautus"
|
msgstr "Salasanan palautus"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Salasanat eivät täsmää"
|
msgstr "Salasanat eivät täsmää"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Päivitä"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Tämän CommaFeed-esiintymän rekisteröinnit on suljettu"
|
msgstr "Tämän CommaFeed-esiintymän rekisteröinnit on suljettu"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Poista tähti"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Peruuta tilaus"
|
msgstr "Peruuta tilaus"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Käyttäjänimi"
|
msgstr "Käyttäjänimi"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Sinulla ei ole vielä tilauksia. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ msgstr "Administrateur"
|
|||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr ""
|
msgstr "Nom de l'administrateur"
|
||||||
|
|
||||||
#: src/components/content/add/CategorySelect.tsx
|
#: src/components/content/add/CategorySelect.tsx
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Retour"
|
msgstr "Retour"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Retour à la connexion"
|
msgstr "Retour à la connexion"
|
||||||
|
|
||||||
@@ -226,13 +227,18 @@ msgstr "Confirmer"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmer le mot de passe"
|
msgstr "Confirmer le mot de passe"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr "Confirmer le mot de passe"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Cozy"
|
msgstr "Cozy"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Create Admin Account"
|
msgid "Create Admin Account"
|
||||||
msgstr ""
|
msgstr "Créer un compte adminstrateur"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Ctrl"
|
msgid "Ctrl"
|
||||||
@@ -489,7 +495,11 @@ msgstr "Indigo"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr "Configuration initiale"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr "Lien de réinitialisation de mot de passse invalide. Recommencez la procédure."
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
@@ -634,6 +644,11 @@ msgstr "Jamais"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nouveau mot de passe"
|
msgstr "Nouveau mot de passe"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr "Nouveau mot de passe"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Plus récent en premier"
|
msgstr "Plus récent en premier"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Catégorie parente"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Mot de passe"
|
msgstr "Mot de passe"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr "Le mot de passe doit mesurer au moins {minimumPasswordLength} caractères"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Récupération de mot de passe"
|
msgstr "Récupération de mot de passe"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Les mots de passe ne correspondent pas"
|
msgstr "Les mots de passe ne correspondent pas"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Rafraîchir"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Les inscriptions sont fermées sur cette instance de CommaFeed"
|
msgstr "Les inscriptions sont fermées sur cette instance de CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr "Réinitialiser le mot de passe"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Retirer des favoris"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Se désabonner"
|
msgstr "Se désabonner"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
@@ -1083,7 +1103,7 @@ msgstr "Site web"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr ""
|
msgstr "Bienvenue ! Il semble que ce soit le premier démarrage de Commafeed. Avant tout, vous devez créer un compte administrateur."
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Vous n'avez pas encore d'abonnements. Pourquoi ne pas essayer d'en ajout
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Vos flux sont en cours de rafraîchissement"
|
msgstr "Vos flux sont en cours de rafraîchissement"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr "Votre mot de passe a été modifié. Vous pouvez vous connecter avec votre nouveau mot de passe."
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ msgstr ""
|
|||||||
"Language: gl\n"
|
"Language: gl\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-12-27 15:30+0200\n"
|
"PO-Revision-Date: 2026-02-04 05:30+0200\n"
|
||||||
"Last-Translator: José M. <correoxm@disroot.org>\n"
|
"Last-Translator: José M. <correoxm@disroot.org>\n"
|
||||||
"Language-Team: gl\n"
|
"Language-Team: gl\n"
|
||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
@@ -64,7 +64,7 @@ msgstr "Administración"
|
|||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr ""
|
msgstr "Identificador de admin"
|
||||||
|
|
||||||
#: src/components/content/add/CategorySelect.tsx
|
#: src/components/content/add/CategorySelect.tsx
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
@@ -136,6 +136,7 @@ msgid "Back"
|
|||||||
msgstr "Volver"
|
msgstr "Volver"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Volver para iniciar sesión"
|
msgstr "Volver para iniciar sesión"
|
||||||
|
|
||||||
@@ -227,13 +228,18 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar contrasinal"
|
msgstr "Confirmar contrasinal"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr "Confirmar contrasinal"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Acolledor"
|
msgstr "Acolledor"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Create Admin Account"
|
msgid "Create Admin Account"
|
||||||
msgstr ""
|
msgstr "Crear conta Admin"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Ctrl"
|
msgid "Ctrl"
|
||||||
@@ -490,7 +496,11 @@ msgstr "Índigo"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr "Configuración inicial"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr "A ligazón de restablecemento non é válida. Solicita unha nova."
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
@@ -635,6 +645,11 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Novo contrasinal"
|
msgstr "Novo contrasinal"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr "Novo contrasinal"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Primeiro o máis recente"
|
msgstr "Primeiro o máis recente"
|
||||||
@@ -772,11 +787,15 @@ msgstr "Categoría superior"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contrasinal"
|
msgstr "Contrasinal"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr "O contrasinal ten que ter {minimumPasswordLength} caracteres polo menos"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Recuperación do contrasinal"
|
msgstr "Recuperación do contrasinal"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Os contrasinais non coinciden"
|
msgstr "Os contrasinais non coinciden"
|
||||||
|
|
||||||
@@ -818,6 +837,11 @@ msgstr "Actualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Non se admiten novas contas nesta instancia de CommaFeed"
|
msgstr "Non se admiten novas contas nesta instancia de CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr "Restablecer contrasinal"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1057,10 +1081,6 @@ msgstr "Retirar estrela"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar a subscrición"
|
msgstr "Cancelar a subscrición"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
@@ -1084,7 +1104,7 @@ msgstr "Páxina web"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr ""
|
msgstr "Benvida! Semella que é a primeira vez que executas CommaFeed. Para comezar, crea unha conta de administración."
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
@@ -1097,3 +1117,7 @@ msgstr "Aínda non tes ningunha subscrición. Por que non engades unha premendo
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "As túas canles están na cola para ser actualizadas."
|
msgstr "As túas canles están na cola para ser actualizadas."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr "O teu contrasinal cambiou. Xa podes acceder coas novas credenciais."
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Vissza"
|
msgstr "Vissza"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Vissza a bejelentkezéshez"
|
msgstr "Vissza a bejelentkezéshez"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Erősítse meg"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Erősítse meg a jelszót"
|
msgstr "Erősítse meg a jelszót"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Hangulatos"
|
msgstr "Hangulatos"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Új jelszó"
|
msgstr "Új jelszó"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "A legújabbak először"
|
msgstr "A legújabbak először"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Szülő kategória"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Jelszó"
|
msgstr "Jelszó"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Jelszó helyreállítás"
|
msgstr "Jelszó helyreállítás"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "A jelszavak nem egyeznek"
|
msgstr "A jelszavak nem egyeznek"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Frissítés"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "A regisztrációk le vannak zárva ezen a CommaFeed példányon"
|
msgstr "A regisztrációk le vannak zárva ezen a CommaFeed példányon"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr ""
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Leiratkozás"
|
msgstr "Leiratkozás"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Felhasználónév"
|
msgstr "Felhasználónév"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Még nincs előfizetése. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Kembali"
|
msgstr "Kembali"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Kembali untuk masuk"
|
msgstr "Kembali untuk masuk"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Konfirmasi"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Konfirmasi kata sandi"
|
msgstr "Konfirmasi kata sandi"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Nyaman"
|
msgstr "Nyaman"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Kata sandi baru"
|
msgstr "Kata sandi baru"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Terbaru dulu"
|
msgstr "Terbaru dulu"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Kategori Induk"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Kata Sandi"
|
msgstr "Kata Sandi"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Pemulihan Kata Sandi"
|
msgstr "Pemulihan Kata Sandi"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Kata sandi tidak cocok"
|
msgstr "Kata sandi tidak cocok"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Segarkan"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Pendaftaran ditutup pada instans CommaFeed ini"
|
msgstr "Pendaftaran ditutup pada instans CommaFeed ini"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Hapus bintang"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Berhenti berlangganan"
|
msgstr "Berhenti berlangganan"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nama pengguna"
|
msgstr "Nama pengguna"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Anda belum memiliki langganan. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Indietro"
|
msgstr "Indietro"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Torna per accedere"
|
msgstr "Torna per accedere"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Conferma"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Conferma password"
|
msgstr "Conferma password"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Accogliente"
|
msgstr "Accogliente"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nuova password"
|
msgstr "Nuova password"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Il più recente prima"
|
msgstr "Il più recente prima"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Categoria padre"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Recupero password"
|
msgstr "Recupero password"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Le password non corrispondono"
|
msgstr "Le password non corrispondono"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Aggiorna"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Le registrazioni sono chiuse su questa istanza CommaFeed"
|
msgstr "Le registrazioni sono chiuse su questa istanza CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Elimina le stelle"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Annulla iscrizione"
|
msgstr "Annulla iscrizione"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nome utente"
|
msgstr "Nome utente"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Non hai ancora abbonamenti. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "戻る"
|
msgstr "戻る"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "ログインに戻る"
|
msgstr "ログインに戻る"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "確認"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "パスワード確認"
|
msgstr "パスワード確認"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Cozy"
|
msgstr "Cozy"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "しない"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "新しいパスワード"
|
msgstr "新しいパスワード"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "最新順"
|
msgstr "最新順"
|
||||||
@@ -771,11 +786,15 @@ msgstr "親カテゴリ"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "パスワード"
|
msgstr "パスワード"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "パスワード回復"
|
msgstr "パスワード回復"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "パスワードが一致しません"
|
msgstr "パスワードが一致しません"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "リフレッシュ"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "このCommaFeedインスタンスの登録は終了しています"
|
msgstr "このCommaFeedインスタンスの登録は終了しています"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "スターを外す"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "退会"
|
msgstr "退会"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "ユーザー名"
|
msgstr "ユーザー名"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "まだサブスクリプションがありません。上部の + 記号
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "フィードの更新がキューに登録されました。"
|
msgstr "フィードの更新がキューに登録されました。"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "뒤로"
|
msgstr "뒤로"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "로그인으로 돌아가기"
|
msgstr "로그인으로 돌아가기"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "확인"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "비밀번호 확인"
|
msgstr "비밀번호 확인"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "코지"
|
msgstr "코지"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "새 비밀번호"
|
msgstr "새 비밀번호"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "최신순"
|
msgstr "최신순"
|
||||||
@@ -771,11 +786,15 @@ msgstr "부모 카테고리"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "비밀번호"
|
msgstr "비밀번호"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "비밀번호 복구"
|
msgstr "비밀번호 복구"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "비밀번호가 일치하지 않습니다"
|
msgstr "비밀번호가 일치하지 않습니다"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "새로 고침"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "이 CommaFeed 인스턴스에 대한 등록이 마감되었습니다."
|
msgstr "이 CommaFeed 인스턴스에 대한 등록이 마감되었습니다."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "별표 제거"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "구독 취소"
|
msgstr "구독 취소"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "사용자 이름"
|
msgstr "사용자 이름"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "아직 구독이 없습니다. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Kembali"
|
msgstr "Kembali"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Kembali untuk log masuk"
|
msgstr "Kembali untuk log masuk"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Sahkan"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Sahkan kata laluan"
|
msgstr "Sahkan kata laluan"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Nyaman"
|
msgstr "Nyaman"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Kata laluan baharu"
|
msgstr "Kata laluan baharu"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Terbaharu dahulu"
|
msgstr "Terbaharu dahulu"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Kategori Induk"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Kata Laluan"
|
msgstr "Kata Laluan"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Pemulihan Kata Laluan"
|
msgstr "Pemulihan Kata Laluan"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Kata laluan tidak sepadan"
|
msgstr "Kata laluan tidak sepadan"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Muat semula"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Pendaftaran ditutup pada contoh CommaFeed ini"
|
msgstr "Pendaftaran ditutup pada contoh CommaFeed ini"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REHAT API"
|
msgstr "REHAT API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Nyahbintang"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Nyahlanggan"
|
msgstr "Nyahlanggan"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nama pengguna"
|
msgstr "Nama pengguna"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Anda belum mempunyai sebarang langganan lagi. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Tilbake"
|
msgstr "Tilbake"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Tilbake for å logge inn"
|
msgstr "Tilbake for å logge inn"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bekreft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekreft passord"
|
msgstr "Bekreft passord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Koselig"
|
msgstr "Koselig"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nyeste først"
|
msgstr "Nyeste først"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Overordnet kategori"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passord"
|
msgstr "Passord"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Passordgjenoppretting"
|
msgstr "Passordgjenoppretting"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Passordene samsvarer ikke"
|
msgstr "Passordene samsvarer ikke"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Oppdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Fjern stjerne"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avslutt abonnementet"
|
msgstr "Avslutt abonnementet"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brukernavn"
|
msgstr "Brukernavn"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Du har ingen abonnementer ennå. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Terug"
|
msgstr "Terug"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Terug naar inloggen"
|
msgstr "Terug naar inloggen"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bevestigen"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bevestig wachtwoord"
|
msgstr "Bevestig wachtwoord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Gezellig"
|
msgstr "Gezellig"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nieuw wachtwoord"
|
msgstr "Nieuw wachtwoord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nieuwste eerst"
|
msgstr "Nieuwste eerst"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Oudercategorie"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Wachtwoord"
|
msgstr "Wachtwoord"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Wachtwoordherstel"
|
msgstr "Wachtwoordherstel"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Wachtwoorden komen niet overeen"
|
msgstr "Wachtwoorden komen niet overeen"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Vernieuwen"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registraties zijn gesloten op deze CommaFeed-instantie"
|
msgstr "Registraties zijn gesloten op deze CommaFeed-instantie"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST-API"
|
msgstr "REST-API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Sterren uit"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Afmelden"
|
msgstr "Afmelden"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Gebruikersnaam"
|
msgstr "Gebruikersnaam"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Je hebt nog geen abonnementen. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Tilbake"
|
msgstr "Tilbake"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Tilbake for å logge inn"
|
msgstr "Tilbake for å logge inn"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bekreft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekreft passord"
|
msgstr "Bekreft passord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Koselig"
|
msgstr "Koselig"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nyeste først"
|
msgstr "Nyeste først"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Overordnet kategori"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passord"
|
msgstr "Passord"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Passordgjenoppretting"
|
msgstr "Passordgjenoppretting"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Passordene samsvarer ikke"
|
msgstr "Passordene samsvarer ikke"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Oppdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Fjern stjerne"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avslutt abonnementet"
|
msgstr "Avslutt abonnementet"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brukernavn"
|
msgstr "Brukernavn"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Du har ingen abonnementer ennå. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Powrót"
|
msgstr "Powrót"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Powrót do logowania"
|
msgstr "Powrót do logowania"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Potwierdź"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potwierdź hasło"
|
msgstr "Potwierdź hasło"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Przytulny"
|
msgstr "Przytulny"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nowe hasło"
|
msgstr "Nowe hasło"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Najnowsze jako pierwsze"
|
msgstr "Najnowsze jako pierwsze"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Kategoria nadrzędna"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Hasło"
|
msgstr "Hasło"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Odzyskiwanie hasła"
|
msgstr "Odzyskiwanie hasła"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Hasła nie pasują"
|
msgstr "Hasła nie pasują"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Odśwież"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Rejestracje są zamknięte w tej instancji CommaFeed"
|
msgstr "Rejestracje są zamknięte w tej instancji CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr ""
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Anuluj subskrypcję"
|
msgstr "Anuluj subskrypcję"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nazwa użytkownika"
|
msgstr "Nazwa użytkownika"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Nie masz jeszcze żadnych subskrypcji. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Voltar"
|
msgstr "Voltar"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Voltar para logar"
|
msgstr "Voltar para logar"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar senha"
|
msgstr "Confirmar senha"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Aconchegante"
|
msgstr "Aconchegante"
|
||||||
@@ -491,6 +497,10 @@ msgstr "Índigo"
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nova senha"
|
msgstr "Nova senha"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Mais novo primeiro"
|
msgstr "Mais novo primeiro"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Categoria Pai"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Senha"
|
msgstr "Senha"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Recuperação de Senha"
|
msgstr "Recuperação de Senha"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Senhas não coincidem"
|
msgstr "Senhas não coincidem"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Atualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Os registros estão fechados nesta instância do CommaFeed"
|
msgstr "Os registros estão fechados nesta instância do CommaFeed"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Desestrelar"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar inscrição"
|
msgstr "Cancelar inscrição"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nome de usuário"
|
msgstr "Nome de usuário"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Você ainda não tem nenhuma assinatura. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Seus feed foram enfileirados para atualização"
|
msgstr "Seus feed foram enfileirados para atualização"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Назад"
|
msgstr "Назад"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Вернуться к входу"
|
msgstr "Вернуться к входу"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Подтвердить"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Подтвердить пароль"
|
msgstr "Подтвердить пароль"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Уютно"
|
msgstr "Уютно"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr "Никогда"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Новый пароль"
|
msgstr "Новый пароль"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Сначала новые"
|
msgstr "Сначала новые"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Родительская категория"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Пароль"
|
msgstr "Пароль"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Восстановление пароля"
|
msgstr "Восстановление пароля"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Пароли не совпадают"
|
msgstr "Пароли не совпадают"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Обновить"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Регистрация закрыта для этого экземпляра CommaFeed."
|
msgstr "Регистрация закрыта для этого экземпляра CommaFeed."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Удалить из избранного"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Отписаться"
|
msgstr "Отписаться"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Имя пользователя"
|
msgstr "Имя пользователя"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "У вас еще нет подписок. Почему бы не поп
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Ваши каналы были поставлены в очередь на обновление."
|
msgstr "Ваши каналы были поставлены в очередь на обновление."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Späť"
|
msgstr "Späť"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Späť na prihlásenie"
|
msgstr "Späť na prihlásenie"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Potvrdiť"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potvrďte heslo"
|
msgstr "Potvrďte heslo"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Útulný"
|
msgstr "Útulný"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Najnovšie ako prvé"
|
msgstr "Najnovšie ako prvé"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Rodičovská kategória"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Heslo"
|
msgstr "Heslo"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Obnovenie hesla"
|
msgstr "Obnovenie hesla"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Heslá sa nezhodujú"
|
msgstr "Heslá sa nezhodujú"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Obnoviť"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "V tejto inštancii CommaFeed sú registrácie uzavreté"
|
msgstr "V tejto inštancii CommaFeed sú registrácie uzavreté"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Odobrať hviezdičku"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Zrušte odber"
|
msgstr "Zrušte odber"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Meno používateľa"
|
msgstr "Meno používateľa"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Zatiaľ nemáte žiadne odbery. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Tillbaka"
|
msgstr "Tillbaka"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Tillbaka för att logga in"
|
msgstr "Tillbaka för att logga in"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Bekräfta"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekräfta lösenord"
|
msgstr "Bekräfta lösenord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Mysigt"
|
msgstr "Mysigt"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt lösenord"
|
msgstr "Nytt lösenord"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Nyast först"
|
msgstr "Nyast först"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Föräldrakategori"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Lösenord"
|
msgstr "Lösenord"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Lösenordsåterställning"
|
msgstr "Lösenordsåterställning"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Lösenorden matchar inte"
|
msgstr "Lösenorden matchar inte"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Uppdatera"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringar är stängda på denna CommaFeed-instans"
|
msgstr "Registreringar är stängda på denna CommaFeed-instans"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1056,10 +1080,6 @@ msgstr ""
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avregistrera"
|
msgstr "Avregistrera"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Användarnamn"
|
msgstr "Användarnamn"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Du har inga prenumerationer än. "
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "Geri"
|
msgstr "Geri"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "Giriş yapmak için geri dön"
|
msgstr "Giriş yapmak için geri dön"
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ msgstr "Onayla"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Şifreyi onayla"
|
msgstr "Şifreyi onayla"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "Rahat"
|
msgstr "Rahat"
|
||||||
@@ -491,6 +497,10 @@ msgstr ""
|
|||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Keep unread"
|
msgid "Keep unread"
|
||||||
@@ -634,6 +644,11 @@ msgstr ""
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Yeni şifre"
|
msgstr "Yeni şifre"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "Önce en yenisi"
|
msgstr "Önce en yenisi"
|
||||||
@@ -771,11 +786,15 @@ msgstr "Üst Kategori"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Şifre"
|
msgstr "Şifre"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "Parola Kurtarma"
|
msgstr "Parola Kurtarma"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "Parolalar eşleşmiyor"
|
msgstr "Parolalar eşleşmiyor"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "Yenile"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Bu CommaFeed örneğinde kayıtlar kapalı"
|
msgstr "Bu CommaFeed örneğinde kayıtlar kapalı"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "Yıldızı kaldır"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Aboneliği iptal et"
|
msgstr "Aboneliği iptal et"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Kullanıcı adı"
|
msgstr "Kullanıcı adı"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "Henüz aboneliğiniz yok. Sayfanın üstündeki + işaretiyle feed ekley
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "Feed'leriniz yenileme için sıraya alındı."
|
msgstr "Feed'leriniz yenileme için sıraya alındı."
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ msgstr "管理员"
|
|||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr ""
|
msgstr "管理员用户名"
|
||||||
|
|
||||||
#: src/components/content/add/CategorySelect.tsx
|
#: src/components/content/add/CategorySelect.tsx
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
@@ -135,6 +135,7 @@ msgid "Back"
|
|||||||
msgstr "返回"
|
msgstr "返回"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Back to log in"
|
msgid "Back to log in"
|
||||||
msgstr "返回登录"
|
msgstr "返回登录"
|
||||||
|
|
||||||
@@ -226,13 +227,18 @@ msgstr "确认"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "确认密码"
|
msgstr "确认密码"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Confirm Password"
|
||||||
|
msgstr "确认密码"
|
||||||
|
|
||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Cozy"
|
msgid "Cozy"
|
||||||
msgstr "宽松"
|
msgstr "宽松"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Create Admin Account"
|
msgid "Create Admin Account"
|
||||||
msgstr ""
|
msgstr "创建管理员帐号"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Ctrl"
|
msgid "Ctrl"
|
||||||
@@ -489,7 +495,11 @@ msgstr "靛蓝"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Initial Setup"
|
msgid "Initial Setup"
|
||||||
msgstr ""
|
msgstr "初始化设置"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Invalid password reset link. Please request a new one."
|
||||||
|
msgstr "密码重置链接无效,请重新申请。"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryContextMenu.tsx
|
#: src/components/content/FeedEntryContextMenu.tsx
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
@@ -634,6 +644,11 @@ msgstr "从不"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "新密码"
|
msgstr "新密码"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "New Password"
|
||||||
|
msgstr "新密码"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "Newest first"
|
msgid "Newest first"
|
||||||
msgstr "最新的优先"
|
msgstr "最新的优先"
|
||||||
@@ -771,11 +786,15 @@ msgstr "父类别"
|
|||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "密码"
|
msgstr "密码"
|
||||||
|
|
||||||
|
#: src/hooks/useValidationRules.ts
|
||||||
|
msgid "Password must be at least {minimumPasswordLength} characters"
|
||||||
|
msgstr "密码最少需要 {minimumPasswordLength} 个字符"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "Password Recovery"
|
msgid "Password Recovery"
|
||||||
msgstr "密码恢复"
|
msgstr "密码恢复"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/hooks/useValidationRules.ts
|
||||||
msgid "Passwords do not match"
|
msgid "Passwords do not match"
|
||||||
msgstr "密码不匹配"
|
msgstr "密码不匹配"
|
||||||
|
|
||||||
@@ -817,6 +836,11 @@ msgstr "刷新"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "此 CommaFeed 实例上的注册已关闭"
|
msgstr "此 CommaFeed 实例上的注册已关闭"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Reset Password"
|
||||||
|
msgstr "重置密码"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
@@ -1056,10 +1080,6 @@ msgstr "取消星标"
|
|||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "取消订阅"
|
msgstr "取消订阅"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
msgid "User created."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "用户名"
|
msgstr "用户名"
|
||||||
@@ -1083,7 +1103,7 @@ msgstr "网站"
|
|||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr ""
|
msgstr "欢迎!当前页仅当您第一次使用CommaFeed时出现,请创建一个管理员帐号以开始使用。"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
@@ -1096,3 +1116,7 @@ msgstr "您还没有任何订阅。"
|
|||||||
#: src/components/header/ProfileMenu.tsx
|
#: src/components/header/ProfileMenu.tsx
|
||||||
msgid "Your feeds have been queued for refresh."
|
msgid "Your feeds have been queued for refresh."
|
||||||
msgstr "您的订阅已经进入刷新队列。"
|
msgstr "您的订阅已经进入刷新队列。"
|
||||||
|
|
||||||
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
|
msgid "Your password has been changed. You can now log in with your new password."
|
||||||
|
msgstr "您的密码已更改。您现在可以使用新密码登录。"
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import { redirectToRootCategory } from "@/app/redirect/thunks"
|
|||||||
import { useAppDispatch } from "@/app/store"
|
import { useAppDispatch } from "@/app/store"
|
||||||
import type { InitialSetupRequest } from "@/app/types"
|
import type { InitialSetupRequest } from "@/app/types"
|
||||||
import { Alert } from "@/components/Alert"
|
import { Alert } from "@/components/Alert"
|
||||||
|
import { useValidationRules } from "@/hooks/useValidationRules"
|
||||||
import { PageTitle } from "@/pages/PageTitle"
|
import { PageTitle } from "@/pages/PageTitle"
|
||||||
|
|
||||||
export function InitialSetupPage() {
|
export function InitialSetupPage() {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { _ } = useLingui()
|
const { _ } = useLingui()
|
||||||
|
const validationRules = useValidationRules()
|
||||||
|
|
||||||
const form = useForm<InitialSetupRequest>({
|
const form = useForm<InitialSetupRequest>({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
@@ -21,6 +23,10 @@ export function InitialSetupPage() {
|
|||||||
password: "",
|
password: "",
|
||||||
email: "",
|
email: "",
|
||||||
},
|
},
|
||||||
|
validate: {
|
||||||
|
password: validationRules.password,
|
||||||
|
},
|
||||||
|
validateInputOnChange: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const login = useAsyncCallback(client.user.login, {
|
const login = useAsyncCallback(client.user.login, {
|
||||||
|
|||||||
119
commafeed-client/src/pages/auth/PasswordResetPage.tsx
Normal file
119
commafeed-client/src/pages/auth/PasswordResetPage.tsx
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import { msg } from "@lingui/core/macro"
|
||||||
|
import { useLingui } from "@lingui/react"
|
||||||
|
import { Trans } from "@lingui/react/macro"
|
||||||
|
import { Anchor, Box, Button, Center, Container, Group, Paper, PasswordInput, Stack, Title } from "@mantine/core"
|
||||||
|
import { useForm } from "@mantine/form"
|
||||||
|
import { useState } from "react"
|
||||||
|
import { useAsyncCallback } from "react-async-hook"
|
||||||
|
import { Link, useSearchParams } from "react-router-dom"
|
||||||
|
import { client, errorToStrings } from "@/app/client"
|
||||||
|
import { Alert } from "@/components/Alert"
|
||||||
|
import { useValidationRules } from "@/hooks/useValidationRules"
|
||||||
|
import { PageTitle } from "@/pages/PageTitle"
|
||||||
|
|
||||||
|
interface PasswordResetFormValues {
|
||||||
|
password: string
|
||||||
|
passwordConfirmation: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PasswordResetPage() {
|
||||||
|
const [message, setMessage] = useState("")
|
||||||
|
const [searchParams] = useSearchParams()
|
||||||
|
const { _ } = useLingui()
|
||||||
|
const validationRules = useValidationRules()
|
||||||
|
|
||||||
|
const email = searchParams.get("email") ?? ""
|
||||||
|
const token = searchParams.get("token") ?? ""
|
||||||
|
|
||||||
|
const form = useForm<PasswordResetFormValues>({
|
||||||
|
initialValues: {
|
||||||
|
password: "",
|
||||||
|
passwordConfirmation: "",
|
||||||
|
},
|
||||||
|
validate: {
|
||||||
|
password: validationRules.password,
|
||||||
|
passwordConfirmation: (value, values) => validationRules.passwordConfirmation(value, values.password),
|
||||||
|
},
|
||||||
|
validateInputOnChange: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const resetPassword = useAsyncCallback(client.user.passwordResetCallback, {
|
||||||
|
onSuccess: () => {
|
||||||
|
setMessage(_(msg`Your password has been changed. You can now log in with your new password.`))
|
||||||
|
form.reset()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const isMissingParams = !email || !token
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container size="xs">
|
||||||
|
<PageTitle />
|
||||||
|
<Paper>
|
||||||
|
<Title order={2} mb="md">
|
||||||
|
<Trans>Reset Password</Trans>
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
{resetPassword.error && (
|
||||||
|
<Box mb="md">
|
||||||
|
<Alert messages={errorToStrings(resetPassword.error)} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isMissingParams && (
|
||||||
|
<Box mb="md">
|
||||||
|
<Alert messages={[_(msg`Invalid password reset link. Please request a new one.`)]} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{message && (
|
||||||
|
<Box mb="md">
|
||||||
|
<Alert level="success" messages={[message]} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isMissingParams && !message && (
|
||||||
|
<form
|
||||||
|
onSubmit={form.onSubmit(values => {
|
||||||
|
resetPassword.execute({
|
||||||
|
email,
|
||||||
|
token,
|
||||||
|
password: values.password,
|
||||||
|
})
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Stack>
|
||||||
|
<PasswordInput
|
||||||
|
label={<Trans>New Password</Trans>}
|
||||||
|
placeholder={_(msg`New Password`)}
|
||||||
|
{...form.getInputProps("password")}
|
||||||
|
size="md"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PasswordInput
|
||||||
|
label={<Trans>Confirm Password</Trans>}
|
||||||
|
placeholder={_(msg`Confirm Password`)}
|
||||||
|
{...form.getInputProps("passwordConfirmation")}
|
||||||
|
size="md"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button type="submit" loading={resetPassword.loading}>
|
||||||
|
<Trans>Reset Password</Trans>
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Center mt="md">
|
||||||
|
<Group>
|
||||||
|
<Anchor component={Link} to="/login">
|
||||||
|
<Trans>Back to log in</Trans>
|
||||||
|
</Anchor>
|
||||||
|
</Group>
|
||||||
|
</Center>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -10,12 +10,14 @@ import { redirectToRootCategory } from "@/app/redirect/thunks"
|
|||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
import type { RegistrationRequest } from "@/app/types"
|
import type { RegistrationRequest } from "@/app/types"
|
||||||
import { Alert } from "@/components/Alert"
|
import { Alert } from "@/components/Alert"
|
||||||
|
import { useValidationRules } from "@/hooks/useValidationRules"
|
||||||
import { PageTitle } from "@/pages/PageTitle"
|
import { PageTitle } from "@/pages/PageTitle"
|
||||||
|
|
||||||
export function RegistrationPage() {
|
export function RegistrationPage() {
|
||||||
const serverInfos = useAppSelector(state => state.server.serverInfos)
|
const serverInfos = useAppSelector(state => state.server.serverInfos)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { _ } = useLingui()
|
const { _ } = useLingui()
|
||||||
|
const validationRules = useValidationRules()
|
||||||
|
|
||||||
const form = useForm<RegistrationRequest>({
|
const form = useForm<RegistrationRequest>({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
@@ -23,6 +25,10 @@ export function RegistrationPage() {
|
|||||||
password: "",
|
password: "",
|
||||||
email: "",
|
email: "",
|
||||||
},
|
},
|
||||||
|
validate: {
|
||||||
|
password: validationRules.password,
|
||||||
|
},
|
||||||
|
validateInputOnChange: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const login = useAsyncCallback(client.user.login, {
|
const login = useAsyncCallback(client.user.login, {
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>6.0.0</version>
|
<version>6.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-server</artifactId>
|
<artifactId>commafeed-server</artifactId>
|
||||||
<name>CommaFeed Server</name>
|
<name>CommaFeed Server</name>
|
||||||
|
<packaging>quarkus</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<quarkus.version>3.30.6</quarkus.version>
|
<quarkus.version>3.31.2</quarkus.version>
|
||||||
<querydsl.version>7.1</querydsl.version>
|
<querydsl.version>7.1</querydsl.version>
|
||||||
<rome.version>2.1.0</rome.version>
|
<rome.version>2.1.0</rome.version>
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>properties-maven-plugin</artifactId>
|
<artifactId>properties-maven-plugin</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>1.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
@@ -77,24 +78,14 @@
|
|||||||
<artifactId>quarkus-maven-plugin</artifactId>
|
<artifactId>quarkus-maven-plugin</artifactId>
|
||||||
<version>${quarkus.version}</version>
|
<version>${quarkus.version}</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<executions>
|
<configuration>
|
||||||
<execution>
|
<properties>
|
||||||
<goals>
|
<quarkus.package.output-name>commafeed-${project.version}</quarkus.package.output-name>
|
||||||
<goal>build</goal>
|
<quarkus.package.runner-suffix>
|
||||||
<goal>generate-code</goal>
|
-${build.database}-${os.detected.name}-${os.detected.arch}-runner
|
||||||
<goal>generate-code-tests</goal>
|
</quarkus.package.runner-suffix>
|
||||||
<goal>native-image-agent</goal>
|
</properties>
|
||||||
</goals>
|
</configuration>
|
||||||
<configuration>
|
|
||||||
<properties>
|
|
||||||
<quarkus.package.output-name>commafeed-${project.version}</quarkus.package.output-name>
|
|
||||||
<quarkus.package.runner-suffix>
|
|
||||||
-${build.database}-${os.detected.name}-${os.detected.arch}-runner
|
|
||||||
</quarkus.package.runner-suffix>
|
|
||||||
</properties>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
@@ -167,6 +158,7 @@
|
|||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.4</version>
|
<version>3.5.4</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<argLine>@{argLine}</argLine>
|
||||||
<systemPropertyVariables>
|
<systemPropertyVariables>
|
||||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||||
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
||||||
@@ -186,14 +178,13 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<argLine>@{argLine}</argLine>
|
||||||
<systemPropertyVariables>
|
<systemPropertyVariables>
|
||||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
|
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
|
||||||
</native.image.path>
|
</native.image.path>
|
||||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||||
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
<!-- fix for java.lang.NoClassDefFoundError: Could not initialize class org.jboss.threads.JDKSpecific$ThreadAccess (#1938) -->
|
|
||||||
<argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<!-- failsafe plugin does not seem to be able to pick up dependencies declared in profiles -->
|
<!-- failsafe plugin does not seem to be able to pick up dependencies declared in profiles -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -219,61 +210,6 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>0.8.14</version>
|
|
||||||
<configuration>
|
|
||||||
<!-- excluding SACParserCSS21TokenManager because it causes a "Method too large" exception -->
|
|
||||||
<excludes>
|
|
||||||
<exclude>com/steadystate/css/parser/SACParserCSS21TokenManager</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unit-tests-agent</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<destFile>${project.build.directory}/jacoco-output/jacoco-unit-tests.exec</destFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>integration-tests-agent</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent-integration</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<destFile>${project.build.directory}/jacoco-output/jacoco-integration-tests.exec</destFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>merge</id>
|
|
||||||
<phase>post-integration-test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>merge</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<fileSets>
|
|
||||||
<fileSet>
|
|
||||||
<directory>${project.build.directory}/jacoco-output</directory>
|
|
||||||
<includes>
|
|
||||||
<include>*.exec</include>
|
|
||||||
</includes>
|
|
||||||
</fileSet>
|
|
||||||
</fileSets>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>generate-code-coverage-report</id>
|
|
||||||
<phase>post-integration-test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.github.git-commit-id</groupId>
|
<groupId>io.github.git-commit-id</groupId>
|
||||||
<artifactId>git-commit-id-maven-plugin</artifactId>
|
<artifactId>git-commit-id-maven-plugin</artifactId>
|
||||||
@@ -301,7 +237,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>13.0.0</version>
|
<version>13.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
@@ -330,7 +266,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.diffplug.spotless</groupId>
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
<artifactId>spotless-maven-plugin</artifactId>
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.2.1</version>
|
||||||
<?m2e ignore?>
|
<?m2e ignore?>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
@@ -359,7 +295,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<version>6.0.0</version>
|
<version>6.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- compile-time processors -->
|
<!-- compile-time processors -->
|
||||||
@@ -427,7 +363,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.dropwizard.metrics</groupId>
|
<groupId>io.dropwizard.metrics</groupId>
|
||||||
<artifactId>metrics-json</artifactId>
|
<artifactId>metrics-json</artifactId>
|
||||||
<version>4.2.37</version>
|
<version>4.2.38</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.openfeign.querydsl</groupId>
|
<groupId>io.github.openfeign.querydsl</groupId>
|
||||||
@@ -530,18 +466,13 @@
|
|||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-junit5-mockito</artifactId>
|
<artifactId>quarkus-junit-mockito</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.quarkus</groupId>
|
|
||||||
<artifactId>quarkus-jacoco</artifactId>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkiverse.playwright</groupId>
|
<groupId>io.quarkiverse.playwright</groupId>
|
||||||
<artifactId>quarkus-playwright</artifactId>
|
<artifactId>quarkus-playwright</artifactId>
|
||||||
<version>2.3.1</version>
|
<version>2.3.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM ibm-semeru-runtimes:open-jdk-25.0.1_8-jre@sha256:d88c854ca5506a04dd2cdaedb98dcf23d6b1b077aebaf738d5c3c5d8c94fff20
|
FROM ibm-semeru-runtimes:open-jdk-25.0.1_8-jre@sha256:e12d5f2461606d625e4d1e22dd0db89e4ae18f58a7f96332811554209ef9028a
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|
||||||
RUN mkdir -p /commafeed/data
|
RUN mkdir -p /commafeed/data
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM debian:13.2@sha256:c71b05eac0b20adb4cdcc9f7b052227efd7da381ad10bb92f972e8eae7c6cdc9
|
FROM debian:13.3@sha256:2c91e484d93f0830a7e05a2b9d92a7b102be7cab562198b984a84fdbc7806d91
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|||||||
@@ -312,6 +312,12 @@ public interface CommaFeedConfiguration {
|
|||||||
@WithDefault("100")
|
@WithDefault("100")
|
||||||
int batchSize();
|
int batchSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to keep starred entries when cleaning up old entries.
|
||||||
|
*/
|
||||||
|
@WithDefault("true")
|
||||||
|
boolean keepStarredEntries();
|
||||||
|
|
||||||
default Instant statusesInstantThreshold() {
|
default Instant statusesInstantThreshold() {
|
||||||
return statusesMaxAge().toMillis() > 0 ? Instant.now().minus(statusesMaxAge()) : null;
|
return statusesMaxAge().toMillis() > 0 ? Instant.now().minus(statusesMaxAge()) : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.commafeed.backend.model.FeedEntry;
|
|||||||
import com.commafeed.backend.model.QFeedEntry;
|
import com.commafeed.backend.model.QFeedEntry;
|
||||||
import com.querydsl.core.Tuple;
|
import com.querydsl.core.Tuple;
|
||||||
import com.querydsl.core.types.dsl.NumberExpression;
|
import com.querydsl.core.types.dsl.NumberExpression;
|
||||||
|
import com.querydsl.jpa.impl.JPAQuery;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
||||||
@@ -25,15 +26,21 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
return query().select(ENTRY).from(ENTRY).where(ENTRY.guidHash.eq(guidHash), ENTRY.feed.eq(feed)).limit(1).fetchOne();
|
return query().select(ENTRY).from(ENTRY).where(ENTRY.guidHash.eq(guidHash), ENTRY.feed.eq(feed)).limit(1).fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max) {
|
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max, boolean keepStarredEntries) {
|
||||||
NumberExpression<Long> count = ENTRY.id.count();
|
NumberExpression<Long> count = ENTRY.id.count();
|
||||||
List<Tuple> tuples = query().select(ENTRY.feed.id, count)
|
JPAQuery<Tuple> query = query().select(ENTRY.feed.id, count).from(ENTRY);
|
||||||
.from(ENTRY)
|
|
||||||
.groupBy(ENTRY.feed)
|
if (keepStarredEntries) {
|
||||||
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.groupBy(ENTRY.feed)
|
||||||
.having(count.gt(maxCapacity))
|
.having(count.gt(maxCapacity))
|
||||||
.limit(max)
|
.limit(max)
|
||||||
.fetch();
|
.fetch()
|
||||||
return tuples.stream().map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count))).toList();
|
.stream()
|
||||||
|
.map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count)))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int delete(Long feedId, long max) {
|
public int delete(Long feedId, long max) {
|
||||||
@@ -44,21 +51,30 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
/**
|
/**
|
||||||
* Delete entries older than a certain date
|
* Delete entries older than a certain date
|
||||||
*/
|
*/
|
||||||
public int deleteEntriesOlderThan(Instant olderThan, long max) {
|
public int deleteEntriesOlderThan(Instant olderThan, long max, boolean keepStarredEntries) {
|
||||||
List<FeedEntry> list = query().selectFrom(ENTRY)
|
JPAQuery<FeedEntry> query = query().selectFrom(ENTRY)
|
||||||
.where(ENTRY.published.lt(olderThan))
|
.where(ENTRY.published.lt(olderThan))
|
||||||
.orderBy(ENTRY.published.asc())
|
.orderBy(ENTRY.published.asc())
|
||||||
.limit(max)
|
.limit(max);
|
||||||
.fetch();
|
|
||||||
return delete(list);
|
if (keepStarredEntries) {
|
||||||
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
|
}
|
||||||
|
|
||||||
|
return delete(query.fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the oldest entries of a feed
|
* Delete the oldest entries of a feed
|
||||||
*/
|
*/
|
||||||
public int deleteOldEntries(Long feedId, long max) {
|
public int deleteOldEntries(Long feedId, long max, boolean keepStarredEntries) {
|
||||||
List<FeedEntry> list = query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).orderBy(ENTRY.published.asc()).limit(max).fetch();
|
JPAQuery<FeedEntry> query = query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).orderBy(ENTRY.published.asc()).limit(max);
|
||||||
return delete(list);
|
|
||||||
|
if (keepStarredEntries) {
|
||||||
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
|
}
|
||||||
|
|
||||||
|
return delete(query.fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
public record FeedCapacity(Long id, Long capacity) {
|
public record FeedCapacity(Long id, Long capacity) {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import com.commafeed.backend.model.QFeedEntry;
|
||||||
|
import com.commafeed.backend.model.QFeedEntryStatus;
|
||||||
|
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||||
|
import com.querydsl.jpa.JPAExpressions;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class Predicates {
|
||||||
|
|
||||||
|
private static final QFeedEntryStatus STATUS = QFeedEntryStatus.feedEntryStatus;
|
||||||
|
|
||||||
|
public static BooleanExpression isNotStarred(QFeedEntry entry) {
|
||||||
|
return JPAExpressions.selectOne().from(STATUS).where(STATUS.entry.eq(entry).and(STATUS.starred.isTrue())).notExists();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.commafeed.backend.service;
|
package com.commafeed.backend.service;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@@ -18,11 +17,10 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
// taken from http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
|
// taken from http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
|
||||||
@SuppressWarnings("serial")
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Singleton
|
@Singleton
|
||||||
public class PasswordEncryptionService implements Serializable {
|
public class PasswordEncryptionService {
|
||||||
|
|
||||||
public boolean authenticate(String attemptedPassword, byte[] encryptedPassword, byte[] salt) {
|
public boolean authenticate(String attemptedPassword, byte[] encryptedPassword, byte[] salt) {
|
||||||
if (StringUtils.isBlank(attemptedPassword)) {
|
if (StringUtils.isBlank(attemptedPassword)) {
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class DatabaseCleaningService {
|
public class DatabaseCleaningService {
|
||||||
|
|
||||||
private final int batchSize;
|
|
||||||
|
|
||||||
private final UnitOfWork unitOfWork;
|
private final UnitOfWork unitOfWork;
|
||||||
private final FeedDAO feedDAO;
|
private final FeedDAO feedDAO;
|
||||||
private final FeedEntryDAO feedEntryDAO;
|
private final FeedEntryDAO feedEntryDAO;
|
||||||
private final FeedEntryContentDAO feedEntryContentDAO;
|
private final FeedEntryContentDAO feedEntryContentDAO;
|
||||||
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
||||||
|
private final int batchSize;
|
||||||
|
private final boolean keepStarredEntries;
|
||||||
private final Meter entriesDeletedMeter;
|
private final Meter entriesDeletedMeter;
|
||||||
|
|
||||||
public DatabaseCleaningService(CommaFeedConfiguration config, UnitOfWork unitOfWork, FeedDAO feedDAO, FeedEntryDAO feedEntryDAO,
|
public DatabaseCleaningService(CommaFeedConfiguration config, UnitOfWork unitOfWork, FeedDAO feedDAO, FeedEntryDAO feedEntryDAO,
|
||||||
@@ -44,6 +44,7 @@ public class DatabaseCleaningService {
|
|||||||
this.feedEntryContentDAO = feedEntryContentDAO;
|
this.feedEntryContentDAO = feedEntryContentDAO;
|
||||||
this.feedEntryStatusDAO = feedEntryStatusDAO;
|
this.feedEntryStatusDAO = feedEntryStatusDAO;
|
||||||
this.batchSize = config.database().cleanup().batchSize();
|
this.batchSize = config.database().cleanup().batchSize();
|
||||||
|
this.keepStarredEntries = config.database().cleanup().keepStarredEntries();
|
||||||
this.entriesDeletedMeter = metrics.meter(MetricRegistry.name(getClass(), "entriesDeleted"));
|
this.entriesDeletedMeter = metrics.meter(MetricRegistry.name(getClass(), "entriesDeleted"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,21 +87,23 @@ public class DatabaseCleaningService {
|
|||||||
log.info("cleaning entries exceeding feed capacity");
|
log.info("cleaning entries exceeding feed capacity");
|
||||||
long total = 0;
|
long total = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
List<FeedCapacity> feeds = unitOfWork.call(() -> feedEntryDAO.findFeedsExceedingCapacity(maxFeedCapacity, batchSize));
|
List<FeedCapacity> feeds = unitOfWork
|
||||||
|
.call(() -> feedEntryDAO.findFeedsExceedingCapacity(maxFeedCapacity, batchSize, keepStarredEntries));
|
||||||
if (feeds.isEmpty()) {
|
if (feeds.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final FeedCapacity feed : feeds) {
|
for (final FeedCapacity feed : feeds) {
|
||||||
long remaining = feed.capacity() - maxFeedCapacity;
|
long remaining = feed.capacity() - maxFeedCapacity;
|
||||||
|
int deleted;
|
||||||
do {
|
do {
|
||||||
final long rem = remaining;
|
final long rem = remaining;
|
||||||
int deleted = unitOfWork.call(() -> feedEntryDAO.deleteOldEntries(feed.id(), Math.min(batchSize, rem)));
|
deleted = unitOfWork.call(() -> feedEntryDAO.deleteOldEntries(feed.id(), Math.min(batchSize, rem), keepStarredEntries));
|
||||||
entriesDeletedMeter.mark(deleted);
|
entriesDeletedMeter.mark(deleted);
|
||||||
total += deleted;
|
total += deleted;
|
||||||
remaining -= deleted;
|
remaining -= deleted;
|
||||||
log.debug("removed {} entries for feeds exceeding capacity", total);
|
log.debug("removed {} entries for feeds exceeding capacity", total);
|
||||||
} while (remaining > 0);
|
} while (deleted > 0 && remaining > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("cleanup done: {} entries for feeds exceeding capacity deleted", total);
|
log.info("cleanup done: {} entries for feeds exceeding capacity deleted", total);
|
||||||
@@ -111,7 +114,7 @@ public class DatabaseCleaningService {
|
|||||||
long total = 0;
|
long total = 0;
|
||||||
long deleted;
|
long deleted;
|
||||||
do {
|
do {
|
||||||
deleted = unitOfWork.call(() -> feedEntryDAO.deleteEntriesOlderThan(olderThan, batchSize));
|
deleted = unitOfWork.call(() -> feedEntryDAO.deleteEntriesOlderThan(olderThan, batchSize, keepStarredEntries));
|
||||||
entriesDeletedMeter.mark(deleted);
|
entriesDeletedMeter.mark(deleted);
|
||||||
total += deleted;
|
total += deleted;
|
||||||
log.debug("removed {} old entries", total);
|
log.debug("removed {} old entries", total);
|
||||||
|
|||||||
@@ -49,4 +49,7 @@ public class ServerInfo implements Serializable {
|
|||||||
@Schema(required = true)
|
@Schema(required = true)
|
||||||
private boolean initialSetupRequired;
|
private boolean initialSetupRequired;
|
||||||
|
|
||||||
|
@Schema(required = true)
|
||||||
|
private int minimumPasswordLength;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import lombok.Data;
|
|||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public class Settings implements Serializable {
|
public class Settings implements Serializable {
|
||||||
|
|
||||||
@Schema(description = "user's preferred language, english if none", required = true)
|
@Schema(description = "user's preferred language, english if none")
|
||||||
private String language;
|
private String language;
|
||||||
|
|
||||||
@Schema(description = "user reads all entries or unread entries only", required = true)
|
@Schema(description = "user reads all entries or unread entries only", required = true)
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.commafeed.frontend.model.request;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import com.commafeed.security.password.ValidPassword;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Data
|
||||||
|
@Schema
|
||||||
|
public class PasswordResetConfirmationRequest implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "email address for password recovery", required = true)
|
||||||
|
@Email
|
||||||
|
@NotEmpty
|
||||||
|
@Size(max = 255)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Schema(description = "password recovery token", required = true)
|
||||||
|
@NotEmpty
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Schema(description = "new password", required = true)
|
||||||
|
@NotEmpty
|
||||||
|
@ValidPassword
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -61,6 +61,7 @@ public class ServerREST {
|
|||||||
infos.setTreeReloadInterval(config.websocket().treeReloadInterval().toMillis());
|
infos.setTreeReloadInterval(config.websocket().treeReloadInterval().toMillis());
|
||||||
infos.setForceRefreshCooldownDuration(config.feedRefresh().forceRefreshCooldownDuration().toMillis());
|
infos.setForceRefreshCooldownDuration(config.feedRefresh().forceRefreshCooldownDuration().toMillis());
|
||||||
infos.setInitialSetupRequired(databaseStartupService.isInitialSetupRequired());
|
infos.setInitialSetupRequired(databaseStartupService.isInitialSetupRequired());
|
||||||
|
infos.setMinimumPasswordLength(config.users().minimumPasswordLength());
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.commafeed.frontend.resource;
|
package com.commafeed.frontend.resource;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@@ -21,13 +20,11 @@ import jakarta.ws.rs.GET;
|
|||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.QueryParam;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
@@ -38,7 +35,6 @@ import com.commafeed.CommaFeedConfiguration;
|
|||||||
import com.commafeed.CommaFeedConstants;
|
import com.commafeed.CommaFeedConstants;
|
||||||
import com.commafeed.backend.Digests;
|
import com.commafeed.backend.Digests;
|
||||||
import com.commafeed.backend.Urls;
|
import com.commafeed.backend.Urls;
|
||||||
import com.commafeed.backend.dao.UnitOfWork;
|
|
||||||
import com.commafeed.backend.dao.UserDAO;
|
import com.commafeed.backend.dao.UserDAO;
|
||||||
import com.commafeed.backend.dao.UserRoleDAO;
|
import com.commafeed.backend.dao.UserRoleDAO;
|
||||||
import com.commafeed.backend.dao.UserSettingsDAO;
|
import com.commafeed.backend.dao.UserSettingsDAO;
|
||||||
@@ -57,6 +53,7 @@ import com.commafeed.backend.service.db.DatabaseStartupService;
|
|||||||
import com.commafeed.frontend.model.Settings;
|
import com.commafeed.frontend.model.Settings;
|
||||||
import com.commafeed.frontend.model.UserModel;
|
import com.commafeed.frontend.model.UserModel;
|
||||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||||
|
import com.commafeed.frontend.model.request.PasswordResetConfirmationRequest;
|
||||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||||
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
||||||
import com.commafeed.frontend.model.request.RegistrationRequest;
|
import com.commafeed.frontend.model.request.RegistrationRequest;
|
||||||
@@ -87,7 +84,6 @@ public class UserREST {
|
|||||||
private final MailService mailService;
|
private final MailService mailService;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
private final UriInfo uri;
|
private final UriInfo uri;
|
||||||
private final UnitOfWork unitOfWork;
|
|
||||||
|
|
||||||
@Path("/settings")
|
@Path("/settings")
|
||||||
@GET
|
@GET
|
||||||
@@ -144,7 +140,6 @@ public class UserREST {
|
|||||||
s.getSharingSettings().setBuffer(true);
|
s.getSharingSettings().setBuffer(true);
|
||||||
|
|
||||||
s.setScrollMarks(true);
|
s.setScrollMarks(true);
|
||||||
s.setLanguage("en");
|
|
||||||
s.setScrollSpeed(400);
|
s.setScrollSpeed(400);
|
||||||
s.setScrollMode(ScrollMode.IF_NEEDED);
|
s.setScrollMode(ScrollMode.IF_NEEDED);
|
||||||
s.setEntriesToKeepOnTopWhenScrolling(1);
|
s.setEntriesToKeepOnTopWhenScrolling(1);
|
||||||
@@ -156,7 +151,7 @@ public class UserREST {
|
|||||||
s.setMobileFooter(false);
|
s.setMobileFooter(false);
|
||||||
s.setUnreadCountTitle(false);
|
s.setUnreadCountTitle(false);
|
||||||
s.setUnreadCountFavicon(true);
|
s.setUnreadCountFavicon(true);
|
||||||
s.setDisablePullToRefresh(true);
|
s.setDisablePullToRefresh(false);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -335,45 +330,44 @@ public class UserREST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildEmailContent(User user) throws URISyntaxException, MalformedURLException {
|
private String buildEmailContent(User user) throws URISyntaxException {
|
||||||
String publicUrl = Urls.removeTrailingSlash(uri.getBaseUri().toString());
|
String publicUrl = Urls.removeTrailingSlash(uri.getBaseUri().toString());
|
||||||
publicUrl += "/rest/user/passwordResetCallback";
|
|
||||||
return String.format(
|
return String.format(
|
||||||
"You asked for password recovery for account '%s', <a href='%s'>follow this link</a> to change your password. Ignore this if you didn't request a password recovery.",
|
"You asked for password recovery for account '%s', <a href='%s'>follow this link</a> to change your password. Ignore this if you didn't request a password recovery.",
|
||||||
user.getName(), callbackUrl(user, publicUrl));
|
user.getName(), callbackUrl(user, publicUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String callbackUrl(User user, String publicUrl) throws URISyntaxException, MalformedURLException {
|
private String callbackUrl(User user, String publicUrl) throws URISyntaxException {
|
||||||
return new URIBuilder(publicUrl).addParameter("email", user.getEmail())
|
URIBuilder queryBuilder = new URIBuilder();
|
||||||
.addParameter("token", user.getRecoverPasswordToken())
|
queryBuilder.addParameter("email", user.getEmail());
|
||||||
.build()
|
queryBuilder.addParameter("token", user.getRecoverPasswordToken());
|
||||||
.toURL()
|
String queryString = queryBuilder.build().getRawQuery();
|
||||||
.toString();
|
return publicUrl + "/#/passwordReset?" + queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("/passwordResetCallback")
|
@Path("/passwordResetCallback")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
@GET
|
@POST
|
||||||
@Transactional
|
@Transactional
|
||||||
@Produces(MediaType.TEXT_HTML)
|
@Operation(summary = "confirm password reset with new password")
|
||||||
public Response passwordRecoveryCallback(@Parameter(required = true) @QueryParam("email") String email,
|
public Response passwordRecoveryCallback(@Valid @Parameter(required = true) PasswordResetConfirmationRequest req) {
|
||||||
@Parameter(required = true) @QueryParam("token") String token) {
|
String email = req.getEmail();
|
||||||
|
String token = req.getToken();
|
||||||
|
String password = req.getPassword();
|
||||||
|
|
||||||
Preconditions.checkNotNull(email);
|
Preconditions.checkNotNull(email);
|
||||||
Preconditions.checkNotNull(token);
|
Preconditions.checkNotNull(token);
|
||||||
|
Preconditions.checkNotNull(password);
|
||||||
|
|
||||||
User user = userDAO.findByEmail(email);
|
User user = userDAO.findByEmail(email);
|
||||||
if (user == null) {
|
if (user == null || user.getRecoverPasswordToken() == null || !user.getRecoverPasswordToken().equals(token)) {
|
||||||
return Response.status(Status.UNAUTHORIZED).entity("Email not found.").build();
|
return Response.status(Status.UNAUTHORIZED).entity("Email not found or invalid token.").build();
|
||||||
}
|
}
|
||||||
if (user.getRecoverPasswordToken() == null || !user.getRecoverPasswordToken().equals(token)) {
|
if (ChronoUnit.MINUTES.between(user.getRecoverPasswordTokenDate(), Instant.now()) >= 30) {
|
||||||
return Response.status(Status.UNAUTHORIZED).entity("Invalid token.").build();
|
return Response.status(Status.UNAUTHORIZED).entity("Token expired.").build();
|
||||||
}
|
|
||||||
if (ChronoUnit.DAYS.between(user.getRecoverPasswordTokenDate(), Instant.now()) >= 2) {
|
|
||||||
return Response.status(Status.UNAUTHORIZED).entity("token expired.").build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String passwd = RandomStringUtils.secure().nextAlphanumeric(10);
|
byte[] encryptedPassword = encryptionService.getEncryptedPassword(password, user.getSalt());
|
||||||
byte[] encryptedPassword = encryptionService.getEncryptedPassword(passwd, user.getSalt());
|
|
||||||
user.setPassword(encryptedPassword);
|
user.setPassword(encryptedPassword);
|
||||||
if (StringUtils.isNotBlank(user.getApiKey())) {
|
if (StringUtils.isNotBlank(user.getApiKey())) {
|
||||||
user.setApiKey(userService.generateApiKey(user));
|
user.setApiKey(userService.generateApiKey(user));
|
||||||
@@ -381,10 +375,7 @@ public class UserREST {
|
|||||||
user.setRecoverPasswordToken(null);
|
user.setRecoverPasswordToken(null);
|
||||||
user.setRecoverPasswordTokenDate(null);
|
user.setRecoverPasswordTokenDate(null);
|
||||||
|
|
||||||
String message = "Your new password is: " + passwd;
|
return Response.ok().build();
|
||||||
message += "<br />";
|
|
||||||
message += String.format("<a href=\"%s\">Back to Homepage</a>", uri.getBaseUri());
|
|
||||||
return Response.ok(message).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("/profile/deleteAccount")
|
@Path("/profile/deleteAccount")
|
||||||
|
|||||||
@@ -115,13 +115,13 @@ class DatabaseCleaningServiceTest {
|
|||||||
Mockito.when(feed2.id()).thenReturn(2L);
|
Mockito.when(feed2.id()).thenReturn(2L);
|
||||||
Mockito.when(feed2.capacity()).thenReturn(120L);
|
Mockito.when(feed2.capacity()).thenReturn(120L);
|
||||||
|
|
||||||
Mockito.when(feedEntryDAO.findFeedsExceedingCapacity(50, BATCH_SIZE))
|
Mockito.when(feedEntryDAO.findFeedsExceedingCapacity(50, BATCH_SIZE, false))
|
||||||
.thenReturn(Arrays.asList(feed1, feed2))
|
.thenReturn(Arrays.asList(feed1, feed2))
|
||||||
.thenReturn(Collections.emptyList());
|
.thenReturn(Collections.emptyList());
|
||||||
|
|
||||||
Mockito.when(feedEntryDAO.deleteOldEntries(1L, 100)).thenReturn(80);
|
Mockito.when(feedEntryDAO.deleteOldEntries(1L, 100, false)).thenReturn(80);
|
||||||
Mockito.when(feedEntryDAO.deleteOldEntries(1L, 50)).thenReturn(50);
|
Mockito.when(feedEntryDAO.deleteOldEntries(1L, 50, false)).thenReturn(50);
|
||||||
Mockito.when(feedEntryDAO.deleteOldEntries(2L, 70)).thenReturn(70);
|
Mockito.when(feedEntryDAO.deleteOldEntries(2L, 70, false)).thenReturn(70);
|
||||||
|
|
||||||
service.cleanEntriesForFeedsExceedingCapacity(50);
|
service.cleanEntriesForFeedsExceedingCapacity(50);
|
||||||
|
|
||||||
@@ -132,11 +132,11 @@ class DatabaseCleaningServiceTest {
|
|||||||
void cleanEntriesOlderThanDeletesOldEntries() {
|
void cleanEntriesOlderThanDeletesOldEntries() {
|
||||||
Instant cutoff = LocalDate.now().minusDays(30).atStartOfDay().toInstant(ZoneOffset.UTC);
|
Instant cutoff = LocalDate.now().minusDays(30).atStartOfDay().toInstant(ZoneOffset.UTC);
|
||||||
|
|
||||||
Mockito.when(feedEntryDAO.deleteEntriesOlderThan(cutoff, BATCH_SIZE)).thenReturn(100, 50, 0);
|
Mockito.when(feedEntryDAO.deleteEntriesOlderThan(cutoff, BATCH_SIZE, false)).thenReturn(100, 50, 0);
|
||||||
|
|
||||||
service.cleanEntriesOlderThan(cutoff);
|
service.cleanEntriesOlderThan(cutoff);
|
||||||
|
|
||||||
Mockito.verify(feedEntryDAO, Mockito.times(3)).deleteEntriesOlderThan(cutoff, BATCH_SIZE);
|
Mockito.verify(feedEntryDAO, Mockito.times(3)).deleteEntriesOlderThan(cutoff, BATCH_SIZE, false);
|
||||||
Mockito.verify(entriesDeletedMeter, Mockito.times(3)).mark(Mockito.anyLong());
|
Mockito.verify(entriesDeletedMeter, Mockito.times(3)).mark(Mockito.anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import com.commafeed.TestConstants;
|
import com.commafeed.TestConstants;
|
||||||
import com.microsoft.playwright.BrowserContext;
|
import com.microsoft.playwright.BrowserContext;
|
||||||
import com.microsoft.playwright.Locator;
|
|
||||||
import com.microsoft.playwright.Page;
|
import com.microsoft.playwright.Page;
|
||||||
import com.microsoft.playwright.assertions.PlaywrightAssertions;
|
import com.microsoft.playwright.assertions.PlaywrightAssertions;
|
||||||
import com.microsoft.playwright.options.AriaRole;
|
import com.microsoft.playwright.options.AriaRole;
|
||||||
@@ -48,17 +47,6 @@ class AuthentificationIT {
|
|||||||
PlaywrightAssertions.assertThat(page).hasURL("http://localhost:8085/#/app/category/all");
|
PlaywrightAssertions.assertThat(page).hasURL("http://localhost:8085/#/app/category/all");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerFailPasswordTooSimple() {
|
|
||||||
Page page = context.newPage();
|
|
||||||
page.navigate(getLoginPageUrl());
|
|
||||||
page.getByText("Sign up!").click();
|
|
||||||
PlaywrightTestUtils.register(page, "user", "user@domain.com", "p");
|
|
||||||
|
|
||||||
Locator alert = page.getByRole(AriaRole.ALERT);
|
|
||||||
PlaywrightAssertions.assertThat(alert).containsText("Password must be 4 or more characters in length.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerSuccess() {
|
void registerSuccess() {
|
||||||
Page page = context.newPage();
|
Page page = context.newPage();
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
package com.commafeed.integration.cleanup;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.commafeed.TestConstants;
|
||||||
|
import com.commafeed.backend.service.db.DatabaseCleaningService;
|
||||||
|
import com.commafeed.frontend.model.Entries;
|
||||||
|
import com.commafeed.frontend.model.Entry;
|
||||||
|
import com.commafeed.frontend.model.request.StarRequest;
|
||||||
|
import com.commafeed.frontend.resource.CategoryREST;
|
||||||
|
import com.commafeed.integration.BaseIT;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
|
||||||
|
@QuarkusTest
|
||||||
|
class DatabaseCleaningIT extends BaseIT {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DatabaseCleaningService databaseCleaningService;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||||
|
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void cleanup() {
|
||||||
|
RestAssured.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void starEntry(String entryId, Long subscriptionId) {
|
||||||
|
StarRequest starRequest = new StarRequest();
|
||||||
|
starRequest.setId(entryId);
|
||||||
|
starRequest.setFeedId(subscriptionId);
|
||||||
|
starRequest.setStarred(true);
|
||||||
|
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star").then().statusCode(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unstarEntry(String entryId, Long subscriptionId) {
|
||||||
|
StarRequest starRequest = new StarRequest();
|
||||||
|
starRequest.setId(entryId);
|
||||||
|
starRequest.setFeedId(subscriptionId);
|
||||||
|
starRequest.setStarred(false);
|
||||||
|
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star").then().statusCode(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class KeepStarredEntries {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void starredEntriesAreKeptWhenCleaningFeedsExceedingCapacity() {
|
||||||
|
// Subscribe to feed and wait for entries
|
||||||
|
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||||
|
|
||||||
|
// Verify we have 2 entries
|
||||||
|
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||||
|
|
||||||
|
// Star the first entry
|
||||||
|
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||||
|
starEntry(entryToStar.getId(), subscriptionId);
|
||||||
|
|
||||||
|
// Verify the entry is starred
|
||||||
|
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||||
|
Assertions.assertEquals(entryToStar.getId(), starredEntries.getEntries().getFirst().getId());
|
||||||
|
|
||||||
|
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||||
|
// With keepStarredEntries=true (default), only non-starred entries are counted for capacity.
|
||||||
|
// We have 2 entries, 1 starred and 1 non-starred. With capacity=0, the 1 non-starred entry exceeds capacity.
|
||||||
|
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||||
|
|
||||||
|
// Verify starred entry is still present
|
||||||
|
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||||
|
Assertions.assertEquals(entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||||
|
|
||||||
|
// Verify the non-starred entry was deleted (only starred entry should remain)
|
||||||
|
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||||
|
Assertions.assertEquals(entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void starredEntriesAreKeptWhenCleaningOldEntries() {
|
||||||
|
// Subscribe to feed and wait for entries
|
||||||
|
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||||
|
|
||||||
|
// Verify we have 2 entries
|
||||||
|
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||||
|
|
||||||
|
// Star the first entry (oldest one based on published date in rss.xml)
|
||||||
|
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||||
|
starEntry(entryToStar.getId(), subscriptionId);
|
||||||
|
|
||||||
|
// Verify the entry is starred
|
||||||
|
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||||
|
|
||||||
|
// Run cleanup for entries older than now (should try to delete all entries)
|
||||||
|
// With keepStarredEntries=true (default), the starred entry should be preserved
|
||||||
|
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||||
|
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||||
|
|
||||||
|
// Verify starred entry is still present
|
||||||
|
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||||
|
Assertions.assertEquals(entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||||
|
|
||||||
|
// Verify the non-starred entry was deleted
|
||||||
|
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||||
|
Assertions.assertEquals(entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipleStarredEntriesAreAllKept() {
|
||||||
|
// Subscribe to feed and wait for entries
|
||||||
|
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||||
|
|
||||||
|
// Verify we have 2 entries
|
||||||
|
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||||
|
|
||||||
|
// Star both entries
|
||||||
|
entriesBefore.getEntries().forEach(entry -> starEntry(entry.getId(), subscriptionId));
|
||||||
|
|
||||||
|
// Verify both entries are starred
|
||||||
|
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(2, starredEntries.getEntries().size());
|
||||||
|
|
||||||
|
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||||
|
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||||
|
|
||||||
|
// Verify both starred entries are still present
|
||||||
|
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||||
|
Assertions.assertEquals(2, starredEntriesAfter.getEntries().size());
|
||||||
|
|
||||||
|
// Verify all entries are preserved (since all are starred)
|
||||||
|
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(2, entriesAfter.getEntries().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unstarringEntryMakesItEligibleForCleanup() {
|
||||||
|
// Subscribe to feed and wait for entries
|
||||||
|
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||||
|
|
||||||
|
// Star the first entry
|
||||||
|
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||||
|
Entry entry = entriesBefore.getEntries().getFirst();
|
||||||
|
starEntry(entry.getId(), subscriptionId);
|
||||||
|
|
||||||
|
// Verify entry is starred
|
||||||
|
Assertions.assertEquals(1, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||||
|
|
||||||
|
// Unstar the entry
|
||||||
|
unstarEntry(entry.getId(), subscriptionId);
|
||||||
|
|
||||||
|
// Verify entry is no longer starred
|
||||||
|
Assertions.assertEquals(0, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||||
|
|
||||||
|
// Run cleanup for entries older than now
|
||||||
|
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||||
|
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||||
|
|
||||||
|
// Verify both entries were deleted (neither is starred)
|
||||||
|
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||||
|
Assertions.assertEquals(0, entriesAfter.getEntries().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ class ServerIT extends BaseIT {
|
|||||||
Assertions.assertEquals(900000, serverInfos.getWebsocketPingInterval());
|
Assertions.assertEquals(900000, serverInfos.getWebsocketPingInterval());
|
||||||
Assertions.assertEquals(30000, serverInfos.getTreeReloadInterval());
|
Assertions.assertEquals(30000, serverInfos.getTreeReloadInterval());
|
||||||
Assertions.assertEquals(60000, serverInfos.getForceRefreshCooldownDuration());
|
Assertions.assertEquals(60000, serverInfos.getForceRefreshCooldownDuration());
|
||||||
|
Assertions.assertEquals(4, serverInfos.getMinimumPasswordLength());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.commafeed.integration.rest;
|
package com.commafeed.integration.rest;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
@@ -13,6 +15,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import com.commafeed.TestConstants;
|
import com.commafeed.TestConstants;
|
||||||
import com.commafeed.frontend.model.Settings;
|
import com.commafeed.frontend.model.Settings;
|
||||||
|
import com.commafeed.frontend.model.request.PasswordResetConfirmationRequest;
|
||||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||||
import com.commafeed.integration.BaseIT;
|
import com.commafeed.integration.BaseIT;
|
||||||
|
|
||||||
@@ -57,8 +60,32 @@ class UserIT extends BaseIT {
|
|||||||
|
|
||||||
Element a = Jsoup.parse(message.getHtml()).select("a").getFirst();
|
Element a = Jsoup.parse(message.getHtml()).select("a").getFirst();
|
||||||
String link = a.attr("href");
|
String link = a.attr("href");
|
||||||
String newPasswordResponse = RestAssured.given().urlEncodingEnabled(false).get(link).then().statusCode(200).extract().asString();
|
|
||||||
Assertions.assertTrue(newPasswordResponse.contains("Your new password is:"));
|
String email = null;
|
||||||
|
String token = null;
|
||||||
|
String queryString = link.substring(link.indexOf('?') + 1);
|
||||||
|
for (String param : queryString.split("&")) {
|
||||||
|
String[] keyValue = param.split("=");
|
||||||
|
if ("email".equals(keyValue[0])) {
|
||||||
|
email = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||||
|
} else if ("token".equals(keyValue[0])) {
|
||||||
|
token = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertNotNull(email);
|
||||||
|
Assertions.assertNotNull(token);
|
||||||
|
Assertions.assertTrue(link.contains("#/passwordReset?"));
|
||||||
|
|
||||||
|
String newPassword = "MyNewPassword123!";
|
||||||
|
PasswordResetConfirmationRequest confirmReq = new PasswordResetConfirmationRequest();
|
||||||
|
confirmReq.setEmail(email);
|
||||||
|
confirmReq.setToken(token);
|
||||||
|
confirmReq.setPassword(newPassword);
|
||||||
|
RestAssured.given().body(confirmReq).contentType(ContentType.JSON).post("rest/user/passwordResetCallback").then().statusCode(200);
|
||||||
|
|
||||||
|
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, newPassword);
|
||||||
|
RestAssured.given().get("rest/user/settings").then().statusCode(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
# we generate the jacoco report ourselves by aggregating the unit tests and integration tests jacoco.exec files
|
|
||||||
quarkus.jacoco.report=false
|
|
||||||
4
pom.xml
4
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>6.0.0</version>
|
<version>6.2.0</version>
|
||||||
<name>CommaFeed</name>
|
<name>CommaFeed</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.14.1</version>
|
<version>3.15.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<parameters>true</parameters>
|
<parameters>true</parameters>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user