Compare commits
174 Commits
Author | SHA1 | Date | |
---|---|---|---|
9f228e3221 | |||
d88888a29d | |||
1c94635f9f | |||
29eb5518c7 | |||
3e0b4b5499 | |||
ebb786769f | |||
39fa66a0e2 | |||
bc7cc8879e | |||
a366b2ada9 | |||
|
1c3ea039f9 | ||
17d622f0a7 | |||
|
2bbae46573 | ||
a9a714326a | |||
9b075bc9d5 | |||
19f343741e | |||
22bfc17163 | |||
|
500315695a | ||
3e49c5e857 | |||
7985f9bb5c | |||
5535716c2a | |||
3054bed12b | |||
b708cf221b | |||
d817ae3259 | |||
bd91ed0af4 | |||
cb56c30de1 | |||
317ac90a3d | |||
c0959be2a2 | |||
793c25a9c8 | |||
f5f7e855c0 | |||
8752f8d4ba | |||
97e5b5ad06 | |||
d3d3ffddd3 | |||
47cd77e6c2 | |||
79ef1cd016 | |||
15598768af | |||
4dfd8e6fa7 | |||
5e34d205ed | |||
66153f9e2c | |||
4e3aaad50b | |||
8f33614882 | |||
190085a0ac | |||
14cfbd0b24 | |||
df6627a9c1 | |||
588a25f2bd | |||
1149ef4f5c | |||
9c6105dc78 | |||
58c0f2ae7d | |||
2cc5e6e5b3 | |||
debd0e4a7c | |||
139c83512e | |||
a66dcc5270 | |||
d2195890d5 | |||
62a260375a | |||
edf5bb871b | |||
b7df5a07f4 | |||
b5bb069198 | |||
58b02ee2cd | |||
324de85667 | |||
1b56e4385d | |||
0604528562 | |||
84a2be8338 | |||
df3c31e23e | |||
391eb1f317 | |||
6649a2e841 | |||
70209acb57 | |||
2733206ae9 | |||
778220c9f1 | |||
0c13fd2af6 | |||
2b0d4bf64e | |||
03312d4f8b | |||
0bfbba130b | |||
0f3b47cb63 | |||
1ed39f2d83 | |||
7045a9e517 | |||
1e2baf04ef | |||
c1d6b3dd4d | |||
ee5d979d7f | |||
9b99fd26a4 | |||
c44ba8fba6 | |||
15a4862785 | |||
dd7fdfa638 | |||
15113de92a | |||
195b5a83e6 | |||
82bea7dcf0 | |||
6dd8bb4686 | |||
3f0d58469e | |||
6278c6f748 | |||
d80e73cee5 | |||
3197873d0f | |||
6d27ec4ac0 | |||
de622e8a78 | |||
f66a70e335 | |||
a7cb4cc45c | |||
23051c75e2 | |||
2a6a008e8f | |||
475732fce2 | |||
2272cb5511 | |||
f4db651cc4 | |||
cea8480359 | |||
e744ebd047 | |||
ecdfededd2 | |||
4720835a0c | |||
a1695ff92c | |||
946a31ecb5 | |||
de8cba9d2d | |||
b0a1280fd0 | |||
fbe935ef13 | |||
44fdae5b2d | |||
749c9639bf | |||
39fa1b8549 | |||
592577086c | |||
705b49268e | |||
38d13e0f85 | |||
cb76f10896 | |||
4e818db3d6 | |||
b9d2fc5975 | |||
a2e671ecfb | |||
2b0f597011 | |||
ca7ba7a338 | |||
57a8110e29 | |||
|
1a5bb2e8d4 | ||
e1628a3513 | |||
3d04a3b9b8 | |||
301e8a1864 | |||
dfa6bc84c7 | |||
e2735080f0 | |||
c4a9908f58 | |||
86d741ae75 | |||
e79b166579 | |||
c5baf3e032 | |||
e7557e05c3 | |||
d25d3c68b5 | |||
10b1971130 | |||
901a3ee3c7 | |||
7d2f44ce44 | |||
7445ced99e | |||
b7583eec23 | |||
ecec5d22a1 | |||
6f6698c758 | |||
097747e201 | |||
2a3e1cfa76 | |||
66f671ac97 | |||
157e75b2f4 | |||
c30775917e | |||
92f77c6e00 | |||
69d82f2160 | |||
d579b74022 | |||
ea3f56a7f3 | |||
9a4fcc3427 | |||
b4059cee54 | |||
8b6203cd6b | |||
61a0c7c1b9 | |||
be208df148 | |||
000605e0cb | |||
56817aa772 | |||
f4ae23f31e | |||
e3d06627dc | |||
6a64545380 | |||
4e4edf40f0 | |||
df3d6e824d | |||
1abcee87ea | |||
f96ec96f56 | |||
afbfbe8487 | |||
87ad98f341 | |||
cc5434004e | |||
519cf82703 | |||
abfa1491fc | |||
59c02ba994 | |||
6cd74a9482 | |||
|
40f13d92aa | ||
172085bf2d | |||
4a93cb9964 | |||
|
cace2c5fb8 | ||
c6915193db |
@ -1,11 +1,9 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'@nextcloud',
|
||||
'@vue/eslint-config-typescript/recommended',
|
||||
'@nextcloud/eslint-config/vue3',
|
||||
'plugin:pinia/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
parser: 'vue-eslint-parser',
|
||||
rules: {
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
'vue/first-attribute-linebreak': 'off',
|
||||
|
@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
php:
|
||||
runs-on: ubuntu-latest
|
||||
container: nextcloud:30
|
||||
container: nextcloud:31
|
||||
steps:
|
||||
- run: apt-get update
|
||||
- run: apt-get install -y git nodejs
|
||||
@ -24,15 +24,21 @@ jobs:
|
||||
- run: composer install
|
||||
- run: composer run lint
|
||||
- run: composer run cs:check
|
||||
- run: composer run psalm
|
||||
- run: composer run phpstan
|
||||
|
||||
nodejs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: skjnldsv/read-package-engines-version-actions@v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "^20"
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
||||
- run: npm run stylelint
|
||||
@ -41,16 +47,22 @@ jobs:
|
||||
release:
|
||||
if: gitea.ref_type == 'tag'
|
||||
runs-on: ubuntu-latest
|
||||
container: nextcloud:30
|
||||
container: nextcloud:31
|
||||
steps:
|
||||
- run: apt-get update
|
||||
- run: apt-get install -y git nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- run: curl -sSLo /usr/local/bin/composer https://getcomposer.org/download/latest-stable/composer.phar
|
||||
- run: chmod +x /usr/local/bin/composer
|
||||
- uses: skjnldsv/read-package-engines-version-actions@v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "^20"
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
- run: make dist
|
||||
- uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
|
28
CHANGELOG.md
28
CHANGELOG.md
@ -1,3 +1,31 @@
|
||||
## 3.5.7 - Prince of Persia - 2025-04-24
|
||||
|
||||
### Added
|
||||
- 🔍 You can now search and filter your subscriptions to quickly find what you want to listen
|
||||
- 🌐 Add Persian language (thanks to @alr86)
|
||||
|
||||
### Changed
|
||||
- ⬆️ Update @nextcloud/vue and many other dependencies
|
||||
|
||||
## 3.5.6 - March comes in like a lion - 2025-03-05
|
||||
|
||||
### Changed
|
||||
- ⬆️ Update @nextcloud/vue
|
||||
|
||||
### Fixed
|
||||
- 🮰 No pointer on play / stop icon on episodes list
|
||||
[#264](https://git.crystalyx.net/Xefir/repod/issues/264)
|
||||
|
||||
## 3.5.5 - Alone in the dark - 2025-02-14
|
||||
|
||||
### Changed
|
||||
- ⬆️ Update @nextcloud/vue
|
||||
- 🔖 Support Nextcloud 31
|
||||
- 🌐 Updated german language (thanks markus phi)
|
||||
|
||||
### Fixed
|
||||
- 🔇 Cancel notification when stopping playback
|
||||
|
||||
## 3.5.4 - Under the spotlight - 2025-01-03
|
||||
|
||||
### Added
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM nextcloud:30
|
||||
FROM nextcloud:31
|
||||
|
||||
ARG APP_NAME=repod
|
||||
ENV NEXTCLOUD_UPDATE=1
|
||||
|
44
Makefile
44
Makefile
@ -84,42 +84,14 @@ appstore:
|
||||
rm -rf $(appstore_build_directory)
|
||||
mkdir -p $(appstore_build_directory)
|
||||
tar -C .. -cvzf $(appstore_package_name).tar.gz \
|
||||
--exclude="$(app_name)/build" \
|
||||
--exclude="$(app_name)/tests" \
|
||||
--exclude="$(app_name)/Makefile" \
|
||||
--exclude="$(app_name)/*.log" \
|
||||
--exclude="$(app_name)/phpunit*xml" \
|
||||
--exclude="$(app_name)/composer.*" \
|
||||
--exclude="$(app_name)/node_modules" \
|
||||
--exclude="$(app_name)/js/node_modules" \
|
||||
--exclude="$(app_name)/js/tests" \
|
||||
--exclude="$(app_name)/js/test" \
|
||||
--exclude="$(app_name)/js/*.log" \
|
||||
--exclude="$(app_name)/js/package.json" \
|
||||
--exclude="$(app_name)/js/bower.json" \
|
||||
--exclude="$(app_name)/js/karma.*" \
|
||||
--exclude="$(app_name)/js/protractor.*" \
|
||||
--exclude="$(app_name)/package.json" \
|
||||
--exclude="$(app_name)/bower.json" \
|
||||
--exclude="$(app_name)/karma.*" \
|
||||
--exclude="$(app_name)/protractor\.*" \
|
||||
--exclude="$(app_name)/.*" \
|
||||
--exclude="$(app_name)/js/.*" \
|
||||
--exclude="$(app_name)/tsconfig.json" \
|
||||
--exclude="$(app_name)/stylelint.config.cjs" \
|
||||
--exclude="$(app_name)/README.md" \
|
||||
--exclude="$(app_name)/package-lock.json" \
|
||||
--exclude="$(app_name)/LICENSE" \
|
||||
--exclude="$(app_name)/src" \
|
||||
--exclude="$(app_name)/stubs" \
|
||||
--exclude="$(app_name)/screens" \
|
||||
--exclude="$(app_name)/vendor" \
|
||||
--exclude="$(app_name)/translationfiles" \
|
||||
--exclude="$(app_name)/Dockerfile" \
|
||||
--exclude="$(app_name)/psalm.xml" \
|
||||
--exclude="$(app_name)/renovate.json" \
|
||||
--exclude="$(app_name)/vite.config.ts" \
|
||||
$(app_name)
|
||||
$(app_name)/appinfo \
|
||||
$(app_name)/css \
|
||||
$(app_name)/img \
|
||||
$(app_name)/js \
|
||||
$(app_name)/l10n \
|
||||
$(app_name)/lib \
|
||||
$(app_name)/templates \
|
||||
$(app_name)/CHANGELOG.md
|
||||
|
||||
# Start a nextcloud server on Docker to kickstart developement
|
||||
.PHONY: dev
|
||||
|
@ -34,7 +34,7 @@ You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) inst
|
||||
| Integrate with [Nextcloud Notes](https://apps.nextcloud.com/apps/notes) | ❌ | ✅ | ❌ | ❌ |
|
||||
| Mobile friendly interface | ✅ | ❌ | ✅ | ✅ |
|
||||
| Support chapters | ✅ | ❌ | ❌ | ✅ |
|
||||
| Available in multiple languages | [✅](https://translate.crystalyx.net/projects/repod/gitea/) (en/fr/de) | ❌ | [✅](https://github.com/owncloud/music/issues/671#issuecomment-782746463) | [✅](https://www.transifex.com/project-insanityorg/podcast-1/dashboard/) (en/de) |
|
||||
| Available in multiple languages | [✅](https://translate.crystalyx.net/projects/repod/gitea/) (5) | ❌ | [✅](https://github.com/owncloud/music/issues/671#issuecomment-782746463) | [✅](https://www.transifex.com/project-insanityorg/podcast-1/dashboard/) (2) |
|
||||
|
||||
> Click on ⭕ to open the ticket
|
||||
|
||||
@ -69,6 +69,9 @@ You can contribute to translate the app in your language and you don't need to h
|
||||
|
||||
Please join the effort at our **[Weblate](https://translate.crystalyx.net/projects/repod/gitea/)** project.
|
||||
|
||||
- [Start a new language](https://translate.crystalyx.net/new-lang/repod/gitea/)
|
||||
- [Contribute to missing translations](https://translate.crystalyx.net/search/repod/gitea/?q=NOT+is%3Atranslated&sort_by=-priority%2Cposition&checksum=)
|
||||
|
||||
Thank you so much if you decide to participate ❤️
|
||||
|
||||
## Credits
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
## Requirements
|
||||
You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!]]></description>
|
||||
<version>3.5.4</version>
|
||||
<version>3.5.7</version>
|
||||
<licence>agpl</licence>
|
||||
<author mail="xefir@crystalyx.net" homepage="https://crystalyx.net">Michel Roux</author>
|
||||
<namespace>RePod</namespace>
|
||||
@ -29,7 +29,7 @@ You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) inst
|
||||
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/modal.png</screenshot>
|
||||
<dependencies>
|
||||
<php min-version="8.1"/>
|
||||
<nextcloud min-version="29" max-version="30"/>
|
||||
<nextcloud min-version="29" max-version="31"/>
|
||||
</dependencies>
|
||||
<navigations>
|
||||
<navigation>
|
||||
|
@ -5,26 +5,28 @@
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OCA\\RePod\\": "lib/",
|
||||
"OCA\\GPodderSync\\": "stubs/OCA/GPodderSync/"
|
||||
"OCA\\GPodderSync\\": "stubs/OCA/GPodderSync/",
|
||||
"OCP\\": "vendor/nextcloud/ocp/OCP/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './vendor-bin/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l",
|
||||
"cs:check": "php-cs-fixer fix --dry-run --diff",
|
||||
"cs:fix": "php-cs-fixer fix",
|
||||
"psalm": "psalm --threads=1 --no-cache --show-info=true",
|
||||
"phpstan": "phpstan clear-result-cache && phpstan analyse -c phpstan.neon",
|
||||
"rector": "rector && composer cs:fix"
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"nextcloud/ocp": "^30.0.4",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"nextcloud/coding-standard": "^1.3.2",
|
||||
"nextcloud/rector": "^0.2.1",
|
||||
"rector/rector": "~1.2.10",
|
||||
"vimeo/psalm": "^5.26.1"
|
||||
"nextcloud/ocp": "^v31.0.4",
|
||||
"nextcloud/rector": "^0.4.1",
|
||||
"phpstan/phpstan": "^2.1.12",
|
||||
"phpstan/phpstan-deprecation-rules": "^2.0.1",
|
||||
"rector/rector": "^2.0.12",
|
||||
"roave/security-advisories": "dev-latest"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
2281
composer.lock
generated
2281
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -19,9 +19,9 @@ OC.L10N.register(
|
||||
"Link copied to the clipboard" : "Link in die Zwischenablage kopiert",
|
||||
"Play" : "Abspielen",
|
||||
"Stop" : "Stopp",
|
||||
"Read" : "Gelesen",
|
||||
"Read" : "gehört",
|
||||
"Open website" : "Webseite aufrufen",
|
||||
"Select" : "Wählen",
|
||||
"Select" : "Auswählen",
|
||||
"Could not change the status of the episode" : "Kann den Status der Folge nicht ändern",
|
||||
"Read all" : "Alles lesen",
|
||||
"Unread all" : "Ungelesen",
|
||||
@ -43,6 +43,7 @@ OC.L10N.register(
|
||||
"Import subscriptions" : "Importiere Abonnements",
|
||||
"Import OPML file" : "Importiere OPML-Datei",
|
||||
"Rate RePod ❤️" : "Bewerte RePod ❤️",
|
||||
"Settings" : "Einstellungen",
|
||||
"Sleep timer" : "Einschlaftimer",
|
||||
"Minutes" : "Minuten",
|
||||
"_%n min_::_%n mins_" : ["%n Minute","%n Minuten"],
|
||||
@ -58,7 +59,7 @@ OC.L10N.register(
|
||||
"Error loading feed" : "Fehler beim Laden des Feeds",
|
||||
"Missing required app" : "Benötigte App fehlt",
|
||||
"Install GPodder Sync" : "Installiere GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "Pinne einige Abonnements, um ihre neuesten Updates zu sehen",
|
||||
"Pin some subscriptions to see their latest updates" : "Markiere Abonnements, um die neuesten Updates zu sehen",
|
||||
"No favorites" : "Keine Favoriten",
|
||||
"A browser extension conflict with RePod" : "Ein Browser-Plugin Problem mit RePod"
|
||||
},
|
||||
|
@ -17,9 +17,9 @@
|
||||
"Link copied to the clipboard" : "Link in die Zwischenablage kopiert",
|
||||
"Play" : "Abspielen",
|
||||
"Stop" : "Stopp",
|
||||
"Read" : "Gelesen",
|
||||
"Read" : "gehört",
|
||||
"Open website" : "Webseite aufrufen",
|
||||
"Select" : "Wählen",
|
||||
"Select" : "Auswählen",
|
||||
"Could not change the status of the episode" : "Kann den Status der Folge nicht ändern",
|
||||
"Read all" : "Alles lesen",
|
||||
"Unread all" : "Ungelesen",
|
||||
@ -41,6 +41,7 @@
|
||||
"Import subscriptions" : "Importiere Abonnements",
|
||||
"Import OPML file" : "Importiere OPML-Datei",
|
||||
"Rate RePod ❤️" : "Bewerte RePod ❤️",
|
||||
"Settings" : "Einstellungen",
|
||||
"Sleep timer" : "Einschlaftimer",
|
||||
"Minutes" : "Minuten",
|
||||
"_%n min_::_%n mins_" : ["%n Minute","%n Minuten"],
|
||||
@ -56,7 +57,7 @@
|
||||
"Error loading feed" : "Fehler beim Laden des Feeds",
|
||||
"Missing required app" : "Benötigte App fehlt",
|
||||
"Install GPodder Sync" : "Installiere GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "Pinne einige Abonnements, um ihre neuesten Updates zu sehen",
|
||||
"Pin some subscriptions to see their latest updates" : "Markiere Abonnements, um die neuesten Updates zu sehen",
|
||||
"No favorites" : "Keine Favoriten",
|
||||
"A browser extension conflict with RePod" : "Ein Browser-Plugin Problem mit RePod"
|
||||
},"pluralForm" :"nplurals=2; plural=n != 1;"
|
||||
|
66
l10n/fa.js
Normal file
66
l10n/fa.js
Normal file
@ -0,0 +1,66 @@
|
||||
OC.L10N.register(
|
||||
"repod",
|
||||
{
|
||||
"RePod Subscriptions" : "اشتراکهای ریپاد",
|
||||
"Podcast" : "پادپخش",
|
||||
"RePod" : "ریپاد",
|
||||
"🔊 Browse, manage and listen to podcasts" : "🔊 مرور، مدیریت و گوش دادن به پادپخشها",
|
||||
"## Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Mobile friendly interface\n- 📡 Import and export your subscriptions\n- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## ویژگیها\n- 🔍 مرور و اشتراک در مجموعه بزرگ پادپخشها\n- 🔊 گوش دادن به قسمتها مستقیماً در نکستکلود\n- 🌐 همگامسازی فعالیتها با [AntennaPod](https://antennapod.org/) و [برنامههای دیگر](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 رابط مناسب برای تلفنهمراه\n- 📡 وارد کردن و صادر کردن اشتراکها\n- ➡️ مقایسه کامل ویژگیها در [اینجا](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## پیشنیازها\nبرای بهکارگیری این برنامه، باید [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) نصب شده باشد!",
|
||||
"Download" : "بارگیری",
|
||||
"Skip to {match}" : "پرش به {match}",
|
||||
"Add a RSS link" : "افزودن پیوند RSS",
|
||||
"Subscribe" : "اشتراک کردن",
|
||||
"Error while adding the feed" : "خطا در افزودن خوراک",
|
||||
"Could not fetch search results" : "ناتوانی در دریافت یافتههای جستجو",
|
||||
"New podcasts" : "پادپخشهای تازه",
|
||||
"Hot podcasts" : "پادپخشهای پرطرفدار",
|
||||
"Could not fetch tops" : "ناتوانی در دریافت برترینها",
|
||||
"Copy feed" : "رونوشت خوراک",
|
||||
"Link copied to the clipboard" : "پیوند به بریدهدان رونویسی شد",
|
||||
"Play" : "پخش",
|
||||
"Stop" : "توقف",
|
||||
"Read" : "خواندهشده",
|
||||
"Open website" : "بازکردن وبگاه",
|
||||
"Select" : "گزینش",
|
||||
"Could not change the status of the episode" : "ناتوانی در تغییر وضعیت قسمت",
|
||||
"Read all" : "خواندن همه",
|
||||
"Unread all" : "ناخوانده کردن همه",
|
||||
"Select all" : "گزینش همه",
|
||||
"Unselect all" : "رد گزینش همه",
|
||||
"Could not fetch episodes" : "ناتوانی در دریافت قسمتها",
|
||||
"_%n episode selected_::_%n episodes selected_" : ["%n قسمت گزینش شد","%n قسمت گزینش شدند"],
|
||||
"Rewind 10 seconds" : "بازگرداندن ۱۰ ثانیه",
|
||||
"Pause" : "مکث",
|
||||
"Fast forward 30 seconds" : "پیشروی سریع ۳۰ ثانیه",
|
||||
"Mute" : "بیصدا",
|
||||
"Unmute" : "با صدا",
|
||||
"Export subscriptions" : "صادر کردن اشتراکها",
|
||||
"Filtering episodes" : "پالایش قسمتها",
|
||||
"Show all" : "نمایش همه",
|
||||
"Listened" : "گوششده",
|
||||
"Listening" : "در حال گوش دادن",
|
||||
"Unlistened" : "شنیده نشده",
|
||||
"Import subscriptions" : "وارد کردن اشتراکها",
|
||||
"Import OPML file" : "وارد کردن پرونده OPML",
|
||||
"Rate RePod ❤️" : "امتیاز به ریپاد ❤️",
|
||||
"Settings" : "تنظیمات",
|
||||
"Sleep timer" : "زمانسنج خواب",
|
||||
"Minutes" : "دقیقه",
|
||||
"_%n min_::_%n mins_" : ["%n دقیقه","%n دقیقه"],
|
||||
"_%n sec_::_%n secs_" : ["%n ثانیه","%n ثانیه"],
|
||||
"Playback speed" : "سرعت پخش",
|
||||
"Favorite" : "برگزیدن",
|
||||
"Are you sure you want to delete this subscription?" : "آیا مطمئن هستید که میخواهید این اشتراک را پاک کنید؟",
|
||||
"Error while removing the feed" : "خطا در پاک کردن خوراک",
|
||||
"You can only have 10 favorites" : "فقط میتوانید ۱۰ مورد برگزیده داشته باشید",
|
||||
"Add a podcast" : "افزودن پادپخش",
|
||||
"Could not fetch subscriptions" : "ناتوانی در دریافت اشتراکها",
|
||||
"Find a podcast" : "یافتن پادپخش",
|
||||
"Error loading feed" : "خطا در بارگذاری خوراک",
|
||||
"Missing required app" : "برنامه موردنیاز نیست",
|
||||
"Install GPodder Sync" : "نصب GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "سنجاق کردن برخی اشتراکها برای دیدن بهروزرسانیهای تازه",
|
||||
"No favorites" : "بدون برگزیده",
|
||||
"A browser extension conflict with RePod" : "ناسازگاری افزونه مرورگر با ریپاد"
|
||||
},
|
||||
"nplurals=2; plural=n > 1;");
|
64
l10n/fa.json
Normal file
64
l10n/fa.json
Normal file
@ -0,0 +1,64 @@
|
||||
{ "translations": {
|
||||
"RePod Subscriptions" : "اشتراکهای ریپاد",
|
||||
"Podcast" : "پادپخش",
|
||||
"RePod" : "ریپاد",
|
||||
"🔊 Browse, manage and listen to podcasts" : "🔊 مرور، مدیریت و گوش دادن به پادپخشها",
|
||||
"## Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Mobile friendly interface\n- 📡 Import and export your subscriptions\n- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## ویژگیها\n- 🔍 مرور و اشتراک در مجموعه بزرگ پادپخشها\n- 🔊 گوش دادن به قسمتها مستقیماً در نکستکلود\n- 🌐 همگامسازی فعالیتها با [AntennaPod](https://antennapod.org/) و [برنامههای دیگر](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 رابط مناسب برای تلفنهمراه\n- 📡 وارد کردن و صادر کردن اشتراکها\n- ➡️ مقایسه کامل ویژگیها در [اینجا](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## پیشنیازها\nبرای بهکارگیری این برنامه، باید [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) نصب شده باشد!",
|
||||
"Download" : "بارگیری",
|
||||
"Skip to {match}" : "پرش به {match}",
|
||||
"Add a RSS link" : "افزودن پیوند RSS",
|
||||
"Subscribe" : "اشتراک کردن",
|
||||
"Error while adding the feed" : "خطا در افزودن خوراک",
|
||||
"Could not fetch search results" : "ناتوانی در دریافت یافتههای جستجو",
|
||||
"New podcasts" : "پادپخشهای تازه",
|
||||
"Hot podcasts" : "پادپخشهای پرطرفدار",
|
||||
"Could not fetch tops" : "ناتوانی در دریافت برترینها",
|
||||
"Copy feed" : "رونوشت خوراک",
|
||||
"Link copied to the clipboard" : "پیوند به بریدهدان رونویسی شد",
|
||||
"Play" : "پخش",
|
||||
"Stop" : "توقف",
|
||||
"Read" : "خواندهشده",
|
||||
"Open website" : "بازکردن وبگاه",
|
||||
"Select" : "گزینش",
|
||||
"Could not change the status of the episode" : "ناتوانی در تغییر وضعیت قسمت",
|
||||
"Read all" : "خواندن همه",
|
||||
"Unread all" : "ناخوانده کردن همه",
|
||||
"Select all" : "گزینش همه",
|
||||
"Unselect all" : "رد گزینش همه",
|
||||
"Could not fetch episodes" : "ناتوانی در دریافت قسمتها",
|
||||
"_%n episode selected_::_%n episodes selected_" : ["%n قسمت گزینش شد","%n قسمت گزینش شدند"],
|
||||
"Rewind 10 seconds" : "بازگرداندن ۱۰ ثانیه",
|
||||
"Pause" : "مکث",
|
||||
"Fast forward 30 seconds" : "پیشروی سریع ۳۰ ثانیه",
|
||||
"Mute" : "بیصدا",
|
||||
"Unmute" : "با صدا",
|
||||
"Export subscriptions" : "صادر کردن اشتراکها",
|
||||
"Filtering episodes" : "پالایش قسمتها",
|
||||
"Show all" : "نمایش همه",
|
||||
"Listened" : "گوششده",
|
||||
"Listening" : "در حال گوش دادن",
|
||||
"Unlistened" : "شنیده نشده",
|
||||
"Import subscriptions" : "وارد کردن اشتراکها",
|
||||
"Import OPML file" : "وارد کردن پرونده OPML",
|
||||
"Rate RePod ❤️" : "امتیاز به ریپاد ❤️",
|
||||
"Settings" : "تنظیمات",
|
||||
"Sleep timer" : "زمانسنج خواب",
|
||||
"Minutes" : "دقیقه",
|
||||
"_%n min_::_%n mins_" : ["%n دقیقه","%n دقیقه"],
|
||||
"_%n sec_::_%n secs_" : ["%n ثانیه","%n ثانیه"],
|
||||
"Playback speed" : "سرعت پخش",
|
||||
"Favorite" : "برگزیدن",
|
||||
"Are you sure you want to delete this subscription?" : "آیا مطمئن هستید که میخواهید این اشتراک را پاک کنید؟",
|
||||
"Error while removing the feed" : "خطا در پاک کردن خوراک",
|
||||
"You can only have 10 favorites" : "فقط میتوانید ۱۰ مورد برگزیده داشته باشید",
|
||||
"Add a podcast" : "افزودن پادپخش",
|
||||
"Could not fetch subscriptions" : "ناتوانی در دریافت اشتراکها",
|
||||
"Find a podcast" : "یافتن پادپخش",
|
||||
"Error loading feed" : "خطا در بارگذاری خوراک",
|
||||
"Missing required app" : "برنامه موردنیاز نیست",
|
||||
"Install GPodder Sync" : "نصب GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "سنجاق کردن برخی اشتراکها برای دیدن بهروزرسانیهای تازه",
|
||||
"No favorites" : "بدون برگزیده",
|
||||
"A browser extension conflict with RePod" : "ناسازگاری افزونه مرورگر با ریپاد"
|
||||
},"pluralForm" :"nplurals=2; plural=n > 1;"
|
||||
}
|
@ -43,6 +43,7 @@ OC.L10N.register(
|
||||
"Import subscriptions" : "Importer les abonnements",
|
||||
"Import OPML file" : "Importer un fichier OPML",
|
||||
"Rate RePod ❤️" : "Donnez votre avis ❤️",
|
||||
"Settings" : "Paramètres",
|
||||
"Sleep timer" : "Minuteur",
|
||||
"Minutes" : "Minutes",
|
||||
"_%n min_::_%n mins_" : ["%n min","%n mins"],
|
||||
|
@ -41,6 +41,7 @@
|
||||
"Import subscriptions" : "Importer les abonnements",
|
||||
"Import OPML file" : "Importer un fichier OPML",
|
||||
"Rate RePod ❤️" : "Donnez votre avis ❤️",
|
||||
"Settings" : "Paramètres",
|
||||
"Sleep timer" : "Minuteur",
|
||||
"Minutes" : "Minutes",
|
||||
"_%n min_::_%n mins_" : ["%n min","%n mins"],
|
||||
|
66
l10n/pl.js
Normal file
66
l10n/pl.js
Normal file
@ -0,0 +1,66 @@
|
||||
OC.L10N.register(
|
||||
"repod",
|
||||
{
|
||||
"RePod Subscriptions" : "Subskrypcje RePod",
|
||||
"Podcast" : "Podkast",
|
||||
"RePod" : "RePod",
|
||||
"🔊 Browse, manage and listen to podcasts" : "🔊 Przeglądanie, zarządzanie i słuchanie podkastów",
|
||||
"## Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Mobile friendly interface\n- 📡 Import and export your subscriptions\n- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## Funkcje\n- 🔍 Przeglądaj i subskrybuj ogromną kolekcję podcastów\n- 🔊 Słuchaj odcinków bezpośrednio w Nextcloud\n- 🌐 Synchronizuj swoją aktywność z [AntennaPod](https://antennapod.org/) i [innymi aplikacjami](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Interfejs dla urządzeń mobilnych\n- 📡 Importuj i eksportuj swoje subskrypcje\n- ➡️ Pełne porównanie funkcji [tutaj](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Wymagania\nAby korzystać z tej aplikacji, musisz mieć zainstalowany [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync)!",
|
||||
"Download" : "Pobierz",
|
||||
"Skip to {match}" : "Skocz do {match}",
|
||||
"Add a RSS link" : "Dodaj RSS z linka",
|
||||
"Subscribe" : "Subskrybuj",
|
||||
"Error while adding the feed" : "Błąd podczas dodawania kanału",
|
||||
"Could not fetch search results" : "Nie można pobrać wyników wyszukiwania",
|
||||
"New podcasts" : "Nowe podkasty",
|
||||
"Hot podcasts" : "Gorące podkasty",
|
||||
"Could not fetch tops" : "Nie można pobrać poleceń",
|
||||
"Copy feed" : "Kopiuj kanał",
|
||||
"Link copied to the clipboard" : "Link skopiowany do schowka",
|
||||
"Play" : "Odtwarzaj",
|
||||
"Stop" : "Stop",
|
||||
"Read" : "Czytaj",
|
||||
"Open website" : "Otwórz stronę",
|
||||
"Select" : "Wybierz",
|
||||
"Could not change the status of the episode" : "Nie można zmienić stanu odcinka",
|
||||
"Read all" : "Czytaj wszystko",
|
||||
"Unread all" : "Cofnij czytaj wszystko",
|
||||
"Select all" : "Zaznacz wszystko",
|
||||
"Unselect all" : "Odznacz wszystko",
|
||||
"Could not fetch episodes" : "Nie można pobrać odcinków",
|
||||
"_%n episode selected_::_%n episodes selected_" : ["%n wybrany odcinek","%n wybrane odcinki","%n wybranych odcinków"],
|
||||
"Rewind 10 seconds" : "Przewiń 10 sekund",
|
||||
"Pause" : "Pauza",
|
||||
"Fast forward 30 seconds" : "Do przodu 30 sekund",
|
||||
"Mute" : "Wycisz",
|
||||
"Unmute" : "Wyłącz wyciszenie",
|
||||
"Export subscriptions" : "Eksportuj subskrypcje",
|
||||
"Filtering episodes" : "Filtr odcinków",
|
||||
"Show all" : "Pokaż wszystko",
|
||||
"Listened" : "Słuchany",
|
||||
"Listening" : "Słuchanie",
|
||||
"Unlistened" : "Niewysłuchane",
|
||||
"Import subscriptions" : "Import subskrypcji",
|
||||
"Import OPML file" : "Import pliku OPML",
|
||||
"Rate RePod ❤️" : "Oceń RePod ❤️",
|
||||
"Settings" : "Ustawienia",
|
||||
"Sleep timer" : "Wyłącznik czasowy",
|
||||
"Minutes" : "Minuty",
|
||||
"_%n min_::_%n mins_" : ["%n minuta","%n minuty","%n minut"],
|
||||
"_%n sec_::_%n secs_" : ["%n sekunda","%n sekundy","%n sekund"],
|
||||
"Playback speed" : "Prędkość odtwarzania",
|
||||
"Favorite" : "Ulubione",
|
||||
"Are you sure you want to delete this subscription?" : "Czy na pewno chcesz usunąć tę subskrypcję?",
|
||||
"Error while removing the feed" : "Błąd podczas usuwania kanału",
|
||||
"You can only have 10 favorites" : "Możesz mieć tylko 10 ulubionych",
|
||||
"Add a podcast" : "Dodaj podkast",
|
||||
"Could not fetch subscriptions" : "Nie można pobrać subskrypcji",
|
||||
"Find a podcast" : "Znajdź podkast",
|
||||
"Error loading feed" : "Błąd ładowania kanału",
|
||||
"Missing required app" : "Brak wymaganej aplikacji",
|
||||
"Install GPodder Sync" : "Zainstaluj GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "Przypnij niektóre subskrypcje, by zobaczyć aktualizacje",
|
||||
"No favorites" : "Brak ulubionych",
|
||||
"A browser extension conflict with RePod" : "Konflikt rozszerzenia przeglądarki z RePod"
|
||||
},
|
||||
"nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");
|
64
l10n/pl.json
Normal file
64
l10n/pl.json
Normal file
@ -0,0 +1,64 @@
|
||||
{ "translations": {
|
||||
"RePod Subscriptions" : "Subskrypcje RePod",
|
||||
"Podcast" : "Podkast",
|
||||
"RePod" : "RePod",
|
||||
"🔊 Browse, manage and listen to podcasts" : "🔊 Przeglądanie, zarządzanie i słuchanie podkastów",
|
||||
"## Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Mobile friendly interface\n- 📡 Import and export your subscriptions\n- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## Funkcje\n- 🔍 Przeglądaj i subskrybuj ogromną kolekcję podcastów\n- 🔊 Słuchaj odcinków bezpośrednio w Nextcloud\n- 🌐 Synchronizuj swoją aktywność z [AntennaPod](https://antennapod.org/) i [innymi aplikacjami](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)\n- 📱 Interfejs dla urządzeń mobilnych\n- 📡 Importuj i eksportuj swoje subskrypcje\n- ➡️ Pełne porównanie funkcji [tutaj](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n\n## Wymagania\nAby korzystać z tej aplikacji, musisz mieć zainstalowany [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync)!",
|
||||
"Download" : "Pobierz",
|
||||
"Skip to {match}" : "Skocz do {match}",
|
||||
"Add a RSS link" : "Dodaj RSS z linka",
|
||||
"Subscribe" : "Subskrybuj",
|
||||
"Error while adding the feed" : "Błąd podczas dodawania kanału",
|
||||
"Could not fetch search results" : "Nie można pobrać wyników wyszukiwania",
|
||||
"New podcasts" : "Nowe podkasty",
|
||||
"Hot podcasts" : "Gorące podkasty",
|
||||
"Could not fetch tops" : "Nie można pobrać poleceń",
|
||||
"Copy feed" : "Kopiuj kanał",
|
||||
"Link copied to the clipboard" : "Link skopiowany do schowka",
|
||||
"Play" : "Odtwarzaj",
|
||||
"Stop" : "Stop",
|
||||
"Read" : "Czytaj",
|
||||
"Open website" : "Otwórz stronę",
|
||||
"Select" : "Wybierz",
|
||||
"Could not change the status of the episode" : "Nie można zmienić stanu odcinka",
|
||||
"Read all" : "Czytaj wszystko",
|
||||
"Unread all" : "Cofnij czytaj wszystko",
|
||||
"Select all" : "Zaznacz wszystko",
|
||||
"Unselect all" : "Odznacz wszystko",
|
||||
"Could not fetch episodes" : "Nie można pobrać odcinków",
|
||||
"_%n episode selected_::_%n episodes selected_" : ["%n wybrany odcinek","%n wybrane odcinki","%n wybranych odcinków"],
|
||||
"Rewind 10 seconds" : "Przewiń 10 sekund",
|
||||
"Pause" : "Pauza",
|
||||
"Fast forward 30 seconds" : "Do przodu 30 sekund",
|
||||
"Mute" : "Wycisz",
|
||||
"Unmute" : "Wyłącz wyciszenie",
|
||||
"Export subscriptions" : "Eksportuj subskrypcje",
|
||||
"Filtering episodes" : "Filtr odcinków",
|
||||
"Show all" : "Pokaż wszystko",
|
||||
"Listened" : "Słuchany",
|
||||
"Listening" : "Słuchanie",
|
||||
"Unlistened" : "Niewysłuchane",
|
||||
"Import subscriptions" : "Import subskrypcji",
|
||||
"Import OPML file" : "Import pliku OPML",
|
||||
"Rate RePod ❤️" : "Oceń RePod ❤️",
|
||||
"Settings" : "Ustawienia",
|
||||
"Sleep timer" : "Wyłącznik czasowy",
|
||||
"Minutes" : "Minuty",
|
||||
"_%n min_::_%n mins_" : ["%n minuta","%n minuty","%n minut"],
|
||||
"_%n sec_::_%n secs_" : ["%n sekunda","%n sekundy","%n sekund"],
|
||||
"Playback speed" : "Prędkość odtwarzania",
|
||||
"Favorite" : "Ulubione",
|
||||
"Are you sure you want to delete this subscription?" : "Czy na pewno chcesz usunąć tę subskrypcję?",
|
||||
"Error while removing the feed" : "Błąd podczas usuwania kanału",
|
||||
"You can only have 10 favorites" : "Możesz mieć tylko 10 ulubionych",
|
||||
"Add a podcast" : "Dodaj podkast",
|
||||
"Could not fetch subscriptions" : "Nie można pobrać subskrypcji",
|
||||
"Find a podcast" : "Znajdź podkast",
|
||||
"Error loading feed" : "Błąd ładowania kanału",
|
||||
"Missing required app" : "Brak wymaganej aplikacji",
|
||||
"Install GPodder Sync" : "Zainstaluj GPodder Sync",
|
||||
"Pin some subscriptions to see their latest updates" : "Przypnij niektóre subskrypcje, by zobaczyć aktualizacje",
|
||||
"No favorites" : "Brak ulubionych",
|
||||
"A browser extension conflict with RePod" : "Konflikt rozszerzenia przeglądarki z RePod"
|
||||
},"pluralForm" :"nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
|
||||
}
|
@ -24,7 +24,6 @@ class Application extends App implements IBootstrap
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
/** @psalm-suppress DeprecatedInterface */
|
||||
$appContainer = $context->getAppContainer();
|
||||
|
||||
/** @var IAppManager $appManager */
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\RePod\Controller;
|
||||
|
||||
use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;
|
||||
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCA\RePod\Core\EpisodeAction\EpisodeActionExtraData;
|
||||
@ -15,9 +16,13 @@ use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IRequest;
|
||||
|
||||
/**
|
||||
* @phpstan-import-type EpisodeActionType from EpisodeAction
|
||||
*/
|
||||
class EpisodesController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
@ -30,23 +35,32 @@ class EpisodesController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JSONResponse<Http::STATUS_*, array<int, EpisodeActionExtraData>, array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/episodes/list')]
|
||||
public function list(string $url): JSONResponse {
|
||||
public function list(string $url): Response {
|
||||
$client = $this->clientService->newClient();
|
||||
$feed = $client->get($url);
|
||||
$episodes = $this->episodeActionReader->parseRssXml((string) $feed->getBody());
|
||||
usort($episodes, fn (EpisodeActionExtraData $a, EpisodeActionExtraData $b): int => $b->getPubDate() <=> $a->getPubDate());
|
||||
$episodes = array_values(array_intersect_key($episodes, array_unique(array_map(fn (EpisodeActionExtraData $episode): string => $episode->getGuid(), $episodes))));
|
||||
|
||||
return new JSONResponse($episodes, $feed->getStatusCode());
|
||||
/** @var Http::STATUS_* $returnStatusCode */
|
||||
$returnStatusCode = $feed->getStatusCode();
|
||||
|
||||
return new JSONResponse($episodes, $returnStatusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-ignore missingType.generics
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/episodes/action')]
|
||||
public function action(string $url): JSONResponse {
|
||||
public function action(string $url): Response {
|
||||
$action = $this->episodeActionRepository->findByEpisodeUrl($url, $this->userService->getUserUID());
|
||||
|
||||
if ($action) {
|
||||
|
@ -10,6 +10,7 @@ use OCA\GPodderSync\Core\SubscriptionChange\SubscriptionChangeSaver;
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCA\RePod\Service\UserService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
@ -31,10 +32,13 @@ class OpmlController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DataDownloadResponse<Http::STATUS_OK, 'application/xml', array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/opml/export')]
|
||||
public function export(): DataDownloadResponse {
|
||||
public function export(): Response {
|
||||
// https://github.com/AntennaPod/AntennaPod/blob/master/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java
|
||||
$xml = new \SimpleXMLElement('<opml/>', namespaceOrPrefix: 'http://xmlpull.org/v1/doc/features.html#indent-output');
|
||||
$xml->addAttribute('version', '2.0');
|
||||
@ -81,9 +85,12 @@ class OpmlController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return new DataDownloadResponse((string) $xml->asXML(), 'repod-'.$dateCreated->getTimestamp().'.opml', ' application/xml');
|
||||
return new DataDownloadResponse((string) $xml->asXML(), 'repod-'.$dateCreated->getTimestamp().'.opml', 'application/xml');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Response<Http::STATUS_OK, array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/opml/import')]
|
||||
@ -91,17 +98,21 @@ class OpmlController extends Controller
|
||||
$file = $this->request->getUploadedFile('import');
|
||||
|
||||
if ($file) {
|
||||
$xml = new \SimpleXMLElement(file_get_contents((string) $file['tmp_name']));
|
||||
$fileContent = file_get_contents((string) $file['tmp_name']);
|
||||
|
||||
/** @var \SimpleXMLElement[] $outlines */
|
||||
$outlines = $xml->body->children();
|
||||
if (is_string($fileContent)) {
|
||||
$xml = new \SimpleXMLElement($fileContent);
|
||||
|
||||
$toSubscribe = [];
|
||||
foreach ($outlines as $outline) {
|
||||
$toSubscribe[] = (string) $outline['xmlUrl'];
|
||||
/** @var \SimpleXMLElement[] $outlines */
|
||||
$outlines = $xml->body->children();
|
||||
|
||||
$toSubscribe = [];
|
||||
foreach ($outlines as $outline) {
|
||||
$toSubscribe[] = (string) $outline['xmlUrl'];
|
||||
}
|
||||
|
||||
$this->subscriptionChangeSaver->saveSubscriptionChanges($toSubscribe, [], $this->userService->getUserUID());
|
||||
}
|
||||
|
||||
$this->subscriptionChangeSaver->saveSubscriptionChanges($toSubscribe, [], $this->userService->getUserUID());
|
||||
}
|
||||
|
||||
return new Response();
|
||||
|
@ -6,13 +6,14 @@ namespace OCA\RePod\Controller;
|
||||
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\Util;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
@ -22,13 +23,13 @@ class PageController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse<Http::STATUS_OK, array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/')]
|
||||
public function index(): TemplateResponse {
|
||||
Util::addScript(Application::APP_ID, Application::APP_ID.'-main');
|
||||
Util::addStyle(Application::APP_ID, Application::APP_ID.'-main');
|
||||
|
||||
public function index(): Response {
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedImageDomain('*');
|
||||
$csp->addAllowedMediaDomain('*');
|
||||
@ -39,17 +40,23 @@ class PageController extends Controller
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse<Http::STATUS_OK, array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/discover')]
|
||||
public function discover(): TemplateResponse {
|
||||
public function discover(): Response {
|
||||
return $this->index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse<Http::STATUS_OK, array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/feed/{path}', requirements: ['path' => '.+'])]
|
||||
public function feed(): TemplateResponse {
|
||||
public function feed(): Response {
|
||||
return $this->index();
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,12 @@ use OCA\GPodderSync\Core\PodcastData\PodcastData;
|
||||
use OCA\GPodderSync\Core\PodcastData\PodcastDataReader;
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IRequest;
|
||||
@ -27,10 +29,13 @@ class PodcastController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-ignore missingType.generics
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/podcast')]
|
||||
public function index(string $url): JSONResponse {
|
||||
public function index(string $url): Response {
|
||||
$podcast = null;
|
||||
|
||||
if ($this->cacheFactory->isLocalCacheAvailable()) {
|
||||
@ -55,6 +60,9 @@ class PodcastController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return new JSONResponse($podcast, $feed->getStatusCode());
|
||||
/** @var Http::STATUS_* $returnStatusCode */
|
||||
$returnStatusCode = $feed->getStatusCode();
|
||||
|
||||
return new JSONResponse($podcast, $returnStatusCode);
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\RePod\Controller;
|
||||
|
||||
use OCA\GPodderSync\Core\PodcastData\PodcastData;
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCA\RePod\Service\MultiPodService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
|
||||
class SearchController extends Controller
|
||||
@ -22,10 +25,13 @@ class SearchController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JSONResponse<Http::STATUS_OK, PodcastData[], array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/search')]
|
||||
public function index(string $q): JSONResponse {
|
||||
public function index(string $q): Response {
|
||||
return new JSONResponse($this->multiPodService->search($q));
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\RePod\Controller;
|
||||
|
||||
use OCA\GPodderSync\Core\PodcastData\PodcastData;
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCA\RePod\Service\FyydService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
|
||||
class ToplistController extends Controller
|
||||
@ -22,17 +25,23 @@ class ToplistController extends Controller
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JSONResponse<Http::STATUS_OK, PodcastData[], array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/toplist/hot')]
|
||||
public function hot(): JSONResponse {
|
||||
public function hot(): Response {
|
||||
return new JSONResponse($this->fyydService->hot());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JSONResponse<Http::STATUS_OK, PodcastData[], array{}>
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/toplist/new')]
|
||||
public function new(): JSONResponse {
|
||||
public function new(): Response {
|
||||
return new JSONResponse($this->fyydService->latest());
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;
|
||||
* Base: https://github.com/pbek/nextcloud-nextpod/blob/main/lib/Core/EpisodeAction/EpisodeActionExtraData.php.
|
||||
* Specs: https://github.com/Podcast-Standards-Project/PSP-1-Podcast-RSS-Specification/blob/main/README.md#required-item-elements.
|
||||
*
|
||||
* @psalm-import-type EpisodeActionType from EpisodeAction
|
||||
* @phpstan-import-type EpisodeActionType from EpisodeAction
|
||||
*
|
||||
* @psalm-type EpisodeActionExtraDataType = array{
|
||||
* @phpstan-type EpisodeActionExtraDataType = array{
|
||||
* title: string,
|
||||
* url: ?string,
|
||||
* name: string,
|
||||
|
@ -142,7 +142,6 @@ class EpisodeActionReader extends CoreEpisodeActionReader
|
||||
* @param null|\SimpleXMLElement|string $value
|
||||
*/
|
||||
private function stringOrNull($value): ?string {
|
||||
/** @psalm-suppress RiskyTruthyFalsyComparison */
|
||||
if (!empty($value)) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
@ -35,13 +35,14 @@ class FyydService implements IPodProvider
|
||||
/** @var string[] $feed */
|
||||
foreach ($json['data'] as $feed) {
|
||||
if ($feed['title']) {
|
||||
$time = strtotime($feed['lastpub']);
|
||||
$podcasts[] = new PodcastData(
|
||||
$feed['title'],
|
||||
$feed['author'],
|
||||
$feed['xmlURL'],
|
||||
$feed['description'],
|
||||
$feed['imgURL'],
|
||||
strtotime($feed['lastpub'])
|
||||
is_int($time) ? $time : time()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -63,13 +64,14 @@ class FyydService implements IPodProvider
|
||||
/** @var string[] $feed */
|
||||
foreach ($podcastJson['data'] as $feed) {
|
||||
if ($feed['title']) {
|
||||
$time = strtotime($feed['lastpub']);
|
||||
$podcasts[] = new PodcastData(
|
||||
$feed['title'],
|
||||
$feed['author'],
|
||||
$feed['xmlURL'],
|
||||
$feed['description'],
|
||||
$feed['imgURL'],
|
||||
strtotime($feed['lastpub'])
|
||||
is_int($time) ? $time : time()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -111,13 +113,14 @@ class FyydService implements IPodProvider
|
||||
/** @var string[] $feed */
|
||||
foreach ($postCastJson['data'] as $feed) {
|
||||
if ($feed['title']) {
|
||||
$time = strtotime($feed['lastpub']);
|
||||
$podcasts[] = new PodcastData(
|
||||
$feed['title'],
|
||||
$feed['author'],
|
||||
$feed['xmlURL'],
|
||||
$feed['description'],
|
||||
$feed['imgURL'],
|
||||
strtotime($feed['lastpub'])
|
||||
is_int($time) ? $time : time()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -32,13 +32,14 @@ class ItunesService implements IPodProvider
|
||||
if (array_key_exists('results', $json) && is_array($json['results'])) {
|
||||
/** @var string[] $feed */
|
||||
foreach ($json['results'] as $feed) {
|
||||
$time = strtotime($feed['releaseDate']);
|
||||
$podcasts[] = new PodcastData(
|
||||
$feed['trackName'],
|
||||
$feed['artistName'],
|
||||
$feed['feedUrl'],
|
||||
$feed['primaryGenreName'],
|
||||
$feed['artworkUrl600'],
|
||||
strtotime($feed['releaseDate'])
|
||||
is_int($time) ? $time : time()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class MultiPodService implements IPodProvider
|
||||
array_unique(
|
||||
array_map(
|
||||
fn (PodcastData $feed) => $feed->getLink(),
|
||||
array_filter($podcasts, fn (PodcastData $feed) => $feed->getLink())
|
||||
array_filter($podcasts, fn (PodcastData $feed): bool => null !== $feed->getLink())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -29,6 +29,9 @@ class SearchProvider implements IProvider
|
||||
return $this->l10n->t('Podcast');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $routeParameters
|
||||
*/
|
||||
public function getOrder(string $route, array $routeParameters): int {
|
||||
if (str_starts_with($route, Application::APP_ID.'.')) {
|
||||
// Active app, prefer my results
|
||||
|
4064
package-lock.json
generated
4064
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -16,34 +16,33 @@
|
||||
],
|
||||
"prettier": "@nextcloud/prettier-config",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-segmenter": "^11.7.8",
|
||||
"@nextcloud/axios": "^2.5.1",
|
||||
"@nextcloud/initial-state": "^2.2.0",
|
||||
"@nextcloud/l10n": "^3.1.0",
|
||||
"@nextcloud/l10n": "^3.2.0",
|
||||
"@nextcloud/router": "^3.0.1",
|
||||
"@nextcloud/vite-config": "^2.2.2",
|
||||
"@nextcloud/vue": "9.0.0-alpha.5",
|
||||
"dompurify": "^3.2.3",
|
||||
"@nextcloud/vite-config": "^2.3.2",
|
||||
"@nextcloud/vue": "~9.0.0-rc.0",
|
||||
"dompurify": "^3.2.5",
|
||||
"linkify-html": "^4.2.0",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia": "^3.0.2",
|
||||
"toastify-js": "^1.12.0",
|
||||
"vite": "~5.4.11",
|
||||
"vite": "^6.3.3",
|
||||
"vue": "^3.5.13",
|
||||
"vue-material-design-icons": "^5.3.1",
|
||||
"vue-router": "^4.5.0"
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nextcloud/browserslist-config": "^3.0.1",
|
||||
"@nextcloud/eslint-config": "^8.4.1",
|
||||
"@nextcloud/prettier-config": "^1.1.0",
|
||||
"@nextcloud/eslint-config": "^8.4.2",
|
||||
"@nextcloud/prettier-config": "^1.2.0",
|
||||
"@nextcloud/stylelint-config": "^3.0.1",
|
||||
"@types/node": "~20.17.31",
|
||||
"@types/toastify-js": "^1.12.3",
|
||||
"@vue/eslint-config-typescript": "~13.0.0",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-prettier": "^10.1.2",
|
||||
"eslint-plugin-pinia": "^0.4.1",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-prettier": "^5.2.6",
|
||||
"typescript": "~5.5.4",
|
||||
"vue-tsc": "^2.2.0"
|
||||
"vue-tsc": "^2.2.10"
|
||||
}
|
||||
}
|
||||
|
6
phpstan.neon
Normal file
6
phpstan.neon
Normal file
@ -0,0 +1,6 @@
|
||||
parameters:
|
||||
level: 9
|
||||
paths:
|
||||
- lib
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
|
29
psalm.xml
29
psalm.xml
@ -1,29 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="1"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
findUnusedBaselineEntry="true"
|
||||
findUnusedCode="false"
|
||||
phpVersion="8.1"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="lib" />
|
||||
<directory name="stubs" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
<extraFiles>
|
||||
<directory name="vendor" />
|
||||
</extraFiles>
|
||||
<issueHandlers>
|
||||
<InvalidReturnType>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="stubs" />
|
||||
</errorLevel>
|
||||
</InvalidReturnType>
|
||||
</issueHandlers>
|
||||
</psalm>
|
@ -7,12 +7,11 @@ use Rector\Config\RectorConfig;
|
||||
|
||||
return RectorConfig::configure()
|
||||
->withPaths([
|
||||
__DIR__.'/appinfo',
|
||||
__DIR__.'/lib',
|
||||
])
|
||||
->withPhpSets(php81: true)
|
||||
->withSets([
|
||||
NextcloudSets::NEXTCLOUD_27,
|
||||
NextcloudSets::NEXTCLOUD_30,
|
||||
])
|
||||
->withPreparedSets(
|
||||
deadCode: true,
|
||||
@ -28,7 +27,5 @@ return RectorConfig::configure()
|
||||
doctrineCodeQuality: true,
|
||||
symfonyCodeQuality: true,
|
||||
symfonyConfigs: true,
|
||||
twig: true,
|
||||
phpunit: true,
|
||||
)
|
||||
;
|
||||
|
@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<NcAppNavigation :class="{ episode }">
|
||||
<slot />
|
||||
<template #search>
|
||||
<slot name="search" />
|
||||
</template>
|
||||
<template #list>
|
||||
<slot name="list" />
|
||||
</template>
|
||||
@ -31,3 +34,9 @@ export default {
|
||||
padding-bottom: 6rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
#app-navigation-vue .app-navigation__body {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
</style>
|
||||
|
@ -2,7 +2,6 @@
|
||||
<NcListItem
|
||||
:active="isCurrentEpisode(episode)"
|
||||
class="episode"
|
||||
:counter-number="episode.duration"
|
||||
:details="
|
||||
!oneLine && episode.pubDate
|
||||
? formatLocaleDate(new Date(episode.pubDate?.date))
|
||||
@ -13,14 +12,14 @@
|
||||
:one-line="oneLine"
|
||||
:style="{ opacity: hasEnded(episode) ? 0.4 : 1 }"
|
||||
@click="modalEpisode = episode">
|
||||
<template #actions>
|
||||
<template #extra-actions>
|
||||
<NcActionButton
|
||||
v-if="!isCurrentEpisode(episode)"
|
||||
:aria-label="t('repod', 'Play')"
|
||||
:title="t('repod', 'Play')"
|
||||
@click="load(episode, url)">
|
||||
<template #icon>
|
||||
<PlayIcon :size="20" />
|
||||
<PlayIcon class="pointer" :size="20" />
|
||||
</template>
|
||||
</NcActionButton>
|
||||
<NcActionButton
|
||||
@ -29,48 +28,51 @@
|
||||
:title="t('repod', 'Stop')"
|
||||
@click="load(null)">
|
||||
<template #icon>
|
||||
<StopIcon :size="20" />
|
||||
<StopIcon class="pointer" :size="20" />
|
||||
</template>
|
||||
</NcActionButton>
|
||||
</template>
|
||||
<template #actions>
|
||||
<NcActionButton
|
||||
v-if="episode.duration"
|
||||
:aria-label="t('repod', 'Read')"
|
||||
:disabled="loading"
|
||||
:model-value="hasEnded(episode)"
|
||||
:name="t('repod', 'Read')"
|
||||
:title="t('repod', 'Read')"
|
||||
@click="read(episode, !hasEnded(episode))">
|
||||
<template #icon>
|
||||
<PlaylistPlayIcon v-if="!hasEnded(episode)" :size="20" />
|
||||
<PlaylistRemoveIcon v-if="hasEnded(episode)" :size="20" />
|
||||
</template>
|
||||
</NcActionButton>
|
||||
<NcActionLink
|
||||
v-if="episode.link"
|
||||
:href="episode.link"
|
||||
:name="t('repod', 'Open website')"
|
||||
target="_blank"
|
||||
:title="t('repod', 'Open website')">
|
||||
<template #icon>
|
||||
<OpenInNewIcon :size="20" />
|
||||
</template>
|
||||
</NcActionLink>
|
||||
<NcActionLink
|
||||
v-if="episode.url"
|
||||
:download="filenameFromUrl(episode.url)"
|
||||
:href="episode.url"
|
||||
:name="t('repod', 'Download')"
|
||||
target="_blank"
|
||||
:title="t('repod', 'Download')">
|
||||
<template #icon>
|
||||
<DownloadIcon :size="20" />
|
||||
</template>
|
||||
</NcActionLink>
|
||||
</template>
|
||||
<template #extra>
|
||||
<NcActions v-if="displayActions">
|
||||
<NcActionButton
|
||||
v-if="episode.duration"
|
||||
:aria-label="t('repod', 'Read')"
|
||||
:disabled="loading"
|
||||
:model-value="hasEnded(episode)"
|
||||
:name="t('repod', 'Read')"
|
||||
:title="t('repod', 'Read')"
|
||||
@click="read(episode, !hasEnded(episode))">
|
||||
<template #icon>
|
||||
<PlaylistPlayIcon v-if="!hasEnded(episode)" :size="20" />
|
||||
<PlaylistRemoveIcon v-if="hasEnded(episode)" :size="20" />
|
||||
</template>
|
||||
</NcActionButton>
|
||||
<NcActionLink
|
||||
v-if="episode.link"
|
||||
:href="episode.link"
|
||||
:name="t('repod', 'Open website')"
|
||||
target="_blank"
|
||||
:title="t('repod', 'Open website')">
|
||||
<template #icon>
|
||||
<OpenInNewIcon :size="20" />
|
||||
</template>
|
||||
</NcActionLink>
|
||||
<NcActionLink
|
||||
v-if="episode.url"
|
||||
:download="filenameFromUrl(episode.url)"
|
||||
:href="episode.url"
|
||||
:name="t('repod', 'Download')"
|
||||
target="_blank"
|
||||
:title="t('repod', 'Download')">
|
||||
<template #icon>
|
||||
<DownloadIcon :size="20" />
|
||||
</template>
|
||||
</NcActionLink>
|
||||
</NcActions>
|
||||
<NcModal v-if="modalEpisode" @close="modalEpisode = null">
|
||||
<NcModal
|
||||
v-if="modalEpisode"
|
||||
:close-on-click-outside="true"
|
||||
@close="modalEpisode = null">
|
||||
<Modal :episode="episode" />
|
||||
</NcModal>
|
||||
</template>
|
||||
@ -87,13 +89,18 @@
|
||||
</NcAvatar>
|
||||
</template>
|
||||
<template #indicator>
|
||||
<NcProgressBar
|
||||
v-if="episode.action && isListening(episode) && !oneLine"
|
||||
class="progress"
|
||||
:value="(episode.action.position * 100) / episode.action.total" />
|
||||
<div class="indicator">
|
||||
<NcProgressBar
|
||||
v-if="episode.action && isListening(episode) && !oneLine"
|
||||
class="progress"
|
||||
:value="
|
||||
(episode.action.position * 100) / episode.action.total
|
||||
" />
|
||||
{{ episode.duration }}
|
||||
</div>
|
||||
</template>
|
||||
<template #subname>
|
||||
{{ !oneLine ? episode.author : '' }}
|
||||
<template v-if="!oneLine" #subname>
|
||||
{{ episode.author }}
|
||||
</template>
|
||||
</NcListItem>
|
||||
</template>
|
||||
@ -102,7 +109,6 @@
|
||||
import {
|
||||
NcActionButton,
|
||||
NcActionLink,
|
||||
NcActions,
|
||||
NcAvatar,
|
||||
NcListItem,
|
||||
NcModal,
|
||||
@ -135,7 +141,6 @@ export default {
|
||||
Modal,
|
||||
NcActionButton,
|
||||
NcActionLink,
|
||||
NcActions,
|
||||
NcAvatar,
|
||||
NcListItem,
|
||||
NcModal,
|
||||
@ -147,10 +152,6 @@ export default {
|
||||
StopIcon,
|
||||
},
|
||||
props: {
|
||||
displayActions: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
episode: {
|
||||
type: Object as () => EpisodeInterface,
|
||||
required: true,
|
||||
@ -208,24 +209,24 @@ export default {
|
||||
.progress {
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.episode .list-item-content__name {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.episode .list-item-content__subname {
|
||||
flex-basis: auto;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.episode .list-item-details__extra {
|
||||
flex-direction: row-reverse;
|
||||
.indicator {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.episode .list-item-details__counter {
|
||||
max-width: fit-content;
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.episode .list-item--one-line .list-item-content__name {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.episode .list-item--one-line .list-item-content__subname {
|
||||
flex-basis: auto;
|
||||
flex-grow: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -61,6 +61,7 @@
|
||||
episodes.filter((e: EpisodeInterface) => e.selected)
|
||||
.length < episodes.length
|
||||
"
|
||||
class="avatar"
|
||||
:display-name="t('repod', 'Select all')"
|
||||
:is-no-user="true">
|
||||
<template #icon>
|
||||
@ -75,6 +76,7 @@
|
||||
episodes.filter((e: EpisodeInterface) => e.selected)
|
||||
.length >= episodes.length
|
||||
"
|
||||
class="avatar"
|
||||
:display-name="t('repod', 'Unselect all')"
|
||||
:is-no-user="true">
|
||||
<template #icon>
|
||||
@ -89,9 +91,6 @@
|
||||
<Episode
|
||||
v-for="episode in filteredEpisodes"
|
||||
:key="episode.guid"
|
||||
:display-actions="
|
||||
episodes.every((e: EpisodeInterface) => !e.selected)
|
||||
"
|
||||
:episode="episode"
|
||||
:url="url"
|
||||
@select="episode.selected = !episode.selected" />
|
||||
@ -175,8 +174,8 @@ export default {
|
||||
)
|
||||
this.episodes = [...episodes.data].sort(
|
||||
(a: EpisodeInterface, b: EpisodeInterface) =>
|
||||
new Date(b.pubDate?.date || '').getTime() -
|
||||
new Date(a.pubDate?.date || '').getTime(),
|
||||
new Date(b.pubDate?.date || '').getTime()
|
||||
- new Date(a.pubDate?.date || '').getTime(),
|
||||
)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@ -217,6 +216,10 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.avatar {
|
||||
color: var(--color-main-text);
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ export default {
|
||||
this.episodes = [...episodes.data]
|
||||
.sort(
|
||||
(a: EpisodeInterface, b: EpisodeInterface) =>
|
||||
new Date(b.pubDate?.date || '').getTime() -
|
||||
new Date(a.pubDate?.date || '').getTime(),
|
||||
new Date(b.pubDate?.date || '').getTime()
|
||||
- new Date(a.pubDate?.date || '').getTime(),
|
||||
)
|
||||
.filter((episode: EpisodeInterface) => !this.hasEnded(episode))
|
||||
.slice(0, 4)
|
||||
|
@ -6,7 +6,7 @@
|
||||
<router-link :to="toFeedUrl(podcastUrl)">
|
||||
<i>{{ episode.title }}</i>
|
||||
</router-link>
|
||||
<NcModal v-if="modal" @close="modal = false">
|
||||
<NcModal v-if="modal" :close-on-click-outside="true" @close="modal = false">
|
||||
<Modal :episode="episode" />
|
||||
</NcModal>
|
||||
</div>
|
||||
|
@ -58,9 +58,9 @@ export default {
|
||||
...mapState(useSettings, ['filters']),
|
||||
all() {
|
||||
return (
|
||||
this.filters.listened &&
|
||||
this.filters.listening &&
|
||||
this.filters.unlistened
|
||||
this.filters.listened
|
||||
&& this.filters.listening
|
||||
&& this.filters.unlistened
|
||||
)
|
||||
},
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NcAppNavigationSettings>
|
||||
<NcAppNavigationSettings :name="t('repod', 'Settings')">
|
||||
<Filters />
|
||||
<Sleep />
|
||||
<Speed />
|
||||
@ -17,6 +17,7 @@ import { NcAppNavigationSettings } from '@nextcloud/vue'
|
||||
import Rate from './Rate.vue'
|
||||
import Sleep from './Sleep.vue'
|
||||
import Speed from './Speed.vue'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
@ -29,5 +30,8 @@ export default {
|
||||
Sleep,
|
||||
Speed,
|
||||
},
|
||||
methods: {
|
||||
t,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -3,7 +3,10 @@
|
||||
<template #extra>
|
||||
<div class="extra">
|
||||
<MinusIcon class="pointer" :size="20" @click="changeRate(-0.1)" />
|
||||
<NcCounterBubble class="counter">x{{ rate }}</NcCounterBubble>
|
||||
<NcCounterBubble
|
||||
:active="rate !== 1"
|
||||
class="counter"
|
||||
:count="rate" />
|
||||
<PlusIcon class="pointer" :size="20" @click="changeRate(0.1)" />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<NcAppNavigationItem
|
||||
<NcListItem
|
||||
:loading="loading"
|
||||
:name="feed?.data?.title || url"
|
||||
:one-line="true"
|
||||
:to="toFeedUrl(url)">
|
||||
<template #actions>
|
||||
<NcActionButton
|
||||
@ -9,7 +10,7 @@
|
||||
:model-value="feed?.isFavorite"
|
||||
:name="t('repod', 'Favorite')"
|
||||
:title="t('repod', 'Favorite')"
|
||||
@update:modelValue="switchFavorite($event)">
|
||||
@update:model-value="switchFavorite($event)">
|
||||
<template #icon>
|
||||
<StarPlusIcon v-if="!feed?.isFavorite" :size="20" />
|
||||
<StarRemoveIcon v-if="feed?.isFavorite" :size="20" />
|
||||
@ -34,11 +35,11 @@
|
||||
<StarIcon v-if="feed?.isFavorite" class="star" :size="20" />
|
||||
<AlertIcon v-if="failed" />
|
||||
</template>
|
||||
</NcAppNavigationItem>
|
||||
</NcListItem>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { NcActionButton, NcAppNavigationItem, NcAvatar } from '@nextcloud/vue'
|
||||
import { NcActionButton, NcAvatar, NcListItem } from '@nextcloud/vue'
|
||||
import type {
|
||||
PersonalSettingsPodcastDataInterface,
|
||||
SubscriptionInterface,
|
||||
@ -62,8 +63,8 @@ export default {
|
||||
AlertIcon,
|
||||
DeleteIcon,
|
||||
NcActionButton,
|
||||
NcAppNavigationItem,
|
||||
NcAvatar,
|
||||
NcListItem,
|
||||
StarIcon,
|
||||
StarPlusIcon,
|
||||
StarRemoveIcon,
|
||||
|
@ -1,26 +1,41 @@
|
||||
<template>
|
||||
<AppNavigation>
|
||||
<template #list>
|
||||
<NcAppContentList>
|
||||
<router-link to="/discover">
|
||||
<NcAppNavigationNew :text="t('repod', 'Add a podcast')">
|
||||
<template #icon>
|
||||
<PlusIcon :size="20" />
|
||||
</template>
|
||||
</NcAppNavigationNew>
|
||||
</router-link>
|
||||
<Loading v-if="loading" />
|
||||
<NcAppNavigationList v-if="!loading">
|
||||
<Subscription
|
||||
v-for="sub of subs.filter((sub) => sub.isFavorite)"
|
||||
:key="sub.metrics.url"
|
||||
:url="sub.metrics.url" />
|
||||
<Subscription
|
||||
v-for="sub of subs.filter((sub) => !sub.isFavorite)"
|
||||
:key="sub.metrics.url"
|
||||
:url="sub.metrics.url" />
|
||||
</NcAppNavigationList>
|
||||
</NcAppContentList>
|
||||
<router-link to="/discover">
|
||||
<NcAppNavigationNew :text="t('repod', 'Add a podcast')">
|
||||
<template #icon>
|
||||
<PlusIcon :size="20" />
|
||||
</template>
|
||||
</NcAppNavigationNew>
|
||||
</router-link>
|
||||
<Loading v-if="loading" />
|
||||
<template #search>
|
||||
<NcAppNavigationSearch
|
||||
v-model="searchValue"
|
||||
:label="t(`core`, 'Filter in current view')" />
|
||||
</template>
|
||||
<template v-if="!loading" #list>
|
||||
<Subscription
|
||||
v-for="sub of subs.filter(
|
||||
(sub) =>
|
||||
sub.isFavorite
|
||||
&& (sub.data?.title
|
||||
.toLowerCase()
|
||||
.includes(searchValue.toLowerCase())
|
||||
|| !searchValue),
|
||||
)"
|
||||
:key="sub.metrics.url"
|
||||
:url="sub.metrics.url" />
|
||||
<Subscription
|
||||
v-for="sub of subs.filter(
|
||||
(sub) =>
|
||||
!sub.isFavorite
|
||||
&& (sub.data?.title
|
||||
.toLowerCase()
|
||||
.includes(searchValue.toLowerCase())
|
||||
|| !searchValue),
|
||||
)"
|
||||
:key="sub.metrics.url"
|
||||
:url="sub.metrics.url" />
|
||||
</template>
|
||||
<template #footer>
|
||||
<Settings />
|
||||
@ -29,11 +44,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
NcAppContentList,
|
||||
NcAppNavigationList,
|
||||
NcAppNavigationNew,
|
||||
} from '@nextcloud/vue'
|
||||
import { NcAppNavigationNew, NcAppNavigationSearch } from '@nextcloud/vue'
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import AppNavigation from '../Atoms/AppNavigation.vue'
|
||||
import Loading from '../Atoms/Loading.vue'
|
||||
@ -49,15 +60,15 @@ export default {
|
||||
components: {
|
||||
AppNavigation,
|
||||
Loading,
|
||||
NcAppContentList,
|
||||
NcAppNavigationList,
|
||||
NcAppNavigationNew,
|
||||
NcAppNavigationSearch,
|
||||
PlusIcon,
|
||||
Settings,
|
||||
Subscription,
|
||||
},
|
||||
data: () => ({
|
||||
loading: true,
|
||||
searchValue: '',
|
||||
}),
|
||||
computed: {
|
||||
...mapState(useSubscriptions, ['subs']),
|
||||
|
@ -1,4 +1,3 @@
|
||||
import '@formatjs/intl-segmenter/polyfill'
|
||||
import App from './App.vue'
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
@ -95,8 +95,8 @@ export const usePlayer = defineStore('player', {
|
||||
} catch {}
|
||||
|
||||
if (
|
||||
this.episode.action &&
|
||||
this.episode.action.position < this.episode.action.total
|
||||
this.episode.action
|
||||
&& this.episode.action.position < this.episode.action.total
|
||||
) {
|
||||
audio.currentTime = this.episode.action.position
|
||||
this.started = audio.currentTime
|
||||
@ -107,6 +107,7 @@ export const usePlayer = defineStore('player', {
|
||||
} else {
|
||||
this.loaded = false
|
||||
this.podcastUrl = null
|
||||
navigator.mediaSession.metadata = null
|
||||
audio.src = ''
|
||||
}
|
||||
},
|
||||
|
@ -2,8 +2,8 @@
|
||||
export const humanFileSize = (size: number) => {
|
||||
const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024))
|
||||
return (
|
||||
(size / Math.pow(1024, i)).toFixed(2) +
|
||||
' ' +
|
||||
['B', 'kB', 'MB', 'GB', 'TB'][i]
|
||||
(size / Math.pow(1024, i)).toFixed(2)
|
||||
+ ' '
|
||||
+ ['B', 'kB', 'MB', 'GB', 'TB'][i]
|
||||
)
|
||||
}
|
||||
|
@ -2,19 +2,19 @@ import { durationToSeconds, formatEpisodeTimestamp } from './time'
|
||||
import type { EpisodeInterface } from './types'
|
||||
|
||||
export const hasEnded = (episode: EpisodeInterface) =>
|
||||
episode.action &&
|
||||
episode.action.action &&
|
||||
(episode.action.action.toLowerCase() === 'delete' ||
|
||||
(episode.action.position > 0 &&
|
||||
episode.action.total > 0 &&
|
||||
episode.action.position >= episode.action.total))
|
||||
episode.action
|
||||
&& episode.action.action
|
||||
&& (episode.action.action.toLowerCase() === 'delete'
|
||||
|| (episode.action.position > 0
|
||||
&& episode.action.total > 0
|
||||
&& episode.action.position >= episode.action.total))
|
||||
|
||||
export const isListening = (episode: EpisodeInterface) =>
|
||||
episode.action &&
|
||||
episode.action.action &&
|
||||
episode.action.action.toLowerCase() === 'play' &&
|
||||
episode.action.position > 0 &&
|
||||
!hasEnded(episode)
|
||||
episode.action
|
||||
&& episode.action.action
|
||||
&& episode.action.action.toLowerCase() === 'play'
|
||||
&& episode.action.position > 0
|
||||
&& !hasEnded(episode)
|
||||
|
||||
export const markAs = (episode: EpisodeInterface, read: boolean, url: string) => {
|
||||
episode.action = {
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace OCA\GPodderSync\Core\EpisodeAction;
|
||||
|
||||
/**
|
||||
* @psalm-type EpisodeActionType = array{
|
||||
* @phpstan-type EpisodeActionType = array{
|
||||
* podcast: string,
|
||||
* episode: string,
|
||||
* action: string,
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace OCA\GPodderSync\Core\PodcastData;
|
||||
|
||||
/**
|
||||
* @psalm-type PodcastActionCountsType = array{
|
||||
* @phpstan-type PodcastActionCountsType = array{
|
||||
* delete: int,
|
||||
* download: int,
|
||||
* flattr: int,
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace OCA\GPodderSync\Core\PodcastData;
|
||||
|
||||
/**
|
||||
* @psalm-type PodcastDataType = array{
|
||||
* @phpstan-type PodcastDataType = array{
|
||||
* title: ?string,
|
||||
* author: ?string,
|
||||
* link: ?string,
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace OCA\GPodderSync\Core\PodcastData;
|
||||
|
||||
/**
|
||||
* @psalm-type PodcastMetricsType = array{
|
||||
* @phpstan-type PodcastMetricsType = array{
|
||||
* url: string,
|
||||
* listenedSeconds: int,
|
||||
* actionCounts: PodcastActionCounts
|
||||
|
@ -8,7 +8,7 @@ use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
|
||||
/**
|
||||
* @psalm-import-type EpisodeActionType from EpisodeAction
|
||||
* @phpstan-import-type EpisodeActionType from EpisodeAction
|
||||
*
|
||||
* @method string getPodcast()
|
||||
* @method void setPodcast(string $podcast)
|
||||
|
@ -1 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OCA\RePod\AppInfo\Application;
|
||||
use OCP\Util;
|
||||
|
||||
Util::addScript(Application::APP_ID, Application::APP_ID.'-main');
|
||||
Util::addStyle(Application::APP_ID, Application::APP_ID.'-main');
|
||||
|
||||
?>
|
||||
|
||||
<div id="content"></div>
|
||||
|
@ -2,15 +2,15 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Nextcloud package.
|
||||
# OiledAmoeba <florian+crystalyx@ruhnke.cloud>, 2024.
|
||||
# Michel Roux <xefir@crystalyx.net>, 2024.
|
||||
# markus phi <repodtranslate@solinetcafe.org>, 2024.
|
||||
# Michel Roux <xefir@crystalyx.net>, 2024, 2025.
|
||||
# markus phi <repodtranslate@solinetcafe.org>, 2024, 2025.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Nextcloud 3.14159\n"
|
||||
"Report-Msgid-Bugs-To: translations\\@example.com\n"
|
||||
"POT-Creation-Date: 2024-12-11 20:03+0000\n"
|
||||
"PO-Revision-Date: 2024-12-25 21:02+0000\n"
|
||||
"Last-Translator: markus phi <repodtranslate@solinetcafe.org>\n"
|
||||
"POT-Creation-Date: 2025-04-23 21:17+0000\n"
|
||||
"PO-Revision-Date: 2025-04-23 21:19+0000\n"
|
||||
"Last-Translator: Michel Roux <xefir@crystalyx.net>\n"
|
||||
"Language-Team: German <https://translate.crystalyx.net/projects/repod/gitea/"
|
||||
"de/>\n"
|
||||
"Language: de\n"
|
||||
@ -18,14 +18,14 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.9.2\n"
|
||||
"X-Generator: Weblate 5.11\n"
|
||||
|
||||
#: /app/lib/Controller/OpmlController.php:46
|
||||
#: /app/lib/Controller/OpmlController.php:50
|
||||
msgid "RePod Subscriptions"
|
||||
msgstr "RePod Abonnements"
|
||||
|
||||
#: /app/lib/Service/SearchProvider.php:29
|
||||
#: /app/lib/Service/SearchProvider.php:61
|
||||
#: /app/lib/Service/SearchProvider.php:64
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:3
|
||||
msgid "Podcast"
|
||||
msgstr "Podcast"
|
||||
@ -58,8 +58,8 @@ msgstr ""
|
||||
"## Funktionen\n"
|
||||
"- 🔍 Durchsuchen und abonnieren einer großen Sammlung von Podcasts\n"
|
||||
"- 🔊 Episoden direkt in Nextcloud anhören\n"
|
||||
"- 🌐 Synchronisiere deine Aktivität mit [AntennaPod](https://antennapod.org/)"
|
||||
"\n"
|
||||
"- 🌐 Synchronisiere deine Aktivität mit [AntennaPod](https://"
|
||||
"antennapod.org/)\n"
|
||||
"- 📱 Handy-freundliche Schnittstelle\n"
|
||||
"- 📡 Importieren und Exportieren Ihrer Abonnements\n"
|
||||
"- ➡️ Vollständiger Funktionsvergleich [hier](https://git.crystalyx.net/Xefir/"
|
||||
@ -133,9 +133,8 @@ msgstr "Stopp"
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:20
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:21
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:22
|
||||
#, fuzzy
|
||||
msgid "Read"
|
||||
msgstr "Gelesen"
|
||||
msgstr "gehört"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:23
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:24
|
||||
@ -143,9 +142,8 @@ msgid "Open website"
|
||||
msgstr "Webseite aufrufen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:27
|
||||
#, fuzzy
|
||||
msgid "Select"
|
||||
msgstr "Wählen"
|
||||
msgstr "Auswählen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:28
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:38
|
||||
@ -155,7 +153,6 @@ msgstr "Kann den Status der Folge nicht ändern"
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:29
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:30
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:31
|
||||
#, fuzzy
|
||||
msgid "Read all"
|
||||
msgstr "Alles lesen"
|
||||
|
||||
@ -243,80 +240,84 @@ msgid "Rate RePod ❤️"
|
||||
msgstr "Bewerte RePod ❤️"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:58
|
||||
#, fuzzy
|
||||
msgid "Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
msgid "Sleep timer"
|
||||
msgstr "Einschlaftimer"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
msgid "Minutes"
|
||||
msgstr "Minuten"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
msgid "%n min"
|
||||
msgid_plural "%n mins"
|
||||
msgstr[0] "%n Minute"
|
||||
msgstr[1] "%n Minuten"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
msgid "%n sec"
|
||||
msgid_plural "%n secs"
|
||||
msgstr[0] "%n sec"
|
||||
msgstr[1] "%n secs"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
msgid "Playback speed"
|
||||
msgstr "Wiedergabegeschwindigkeit"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:64
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:65
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
msgid "Favorite"
|
||||
msgstr "Favorit"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
msgid "Are you sure you want to delete this subscription?"
|
||||
msgstr "Bist Du sicher, dass Du das Abonnement löschen möchtest?"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
msgid "Error while removing the feed"
|
||||
msgstr "Fehler beim Löschen des Feeds"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
msgid "You can only have 10 favorites"
|
||||
msgstr "Du kannst nur max. 10 Favoriten haben"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
msgid "Add a podcast"
|
||||
msgstr "Einen Podcast hinzufügen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
msgid "Could not fetch subscriptions"
|
||||
msgstr "Abonnements können nicht abgerufen werden"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
msgid "Find a podcast"
|
||||
msgstr "Finde einen Podcast"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
msgid "Error loading feed"
|
||||
msgstr "Fehler beim Laden des Feeds"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
msgid "Missing required app"
|
||||
msgstr "Benötigte App fehlt"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
msgid "Install GPodder Sync"
|
||||
msgstr "Installiere GPodder Sync"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
#, fuzzy
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr "Pinne einige Abonnements, um ihre neuesten Updates zu sehen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr "Markiere Abonnements, um die neuesten Updates zu sehen"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:77
|
||||
msgid "No favorites"
|
||||
msgstr "Keine Favoriten"
|
||||
|
||||
#: /app/src/store/player.ts:93
|
||||
#: /app/src/store/player.ts:123
|
||||
msgid "A browser extension conflict with RePod"
|
||||
msgstr "Ein Browser-Plugin Problem mit RePod"
|
||||
|
323
translationfiles/fa/repod.po
Normal file
323
translationfiles/fa/repod.po
Normal file
@ -0,0 +1,323 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Nextcloud package.
|
||||
# Michel Roux <xefir@crystalyx.net>, 2025.
|
||||
# Alireza <injaneb@duck.com>, 2025.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Nextcloud 3.14159\n"
|
||||
"Report-Msgid-Bugs-To: translations\\@example.com\n"
|
||||
"POT-Creation-Date: 2025-04-23 21:17+0000\n"
|
||||
"PO-Revision-Date: 2025-04-23 21:19+0000\n"
|
||||
"Last-Translator: Michel Roux <xefir@crystalyx.net>\n"
|
||||
"Language-Team: Persian <https://translate.crystalyx.net/projects/repod/gitea/"
|
||||
"fa/>\n"
|
||||
"Language: fa\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.11\n"
|
||||
|
||||
#: /app/lib/Controller/OpmlController.php:50
|
||||
msgid "RePod Subscriptions"
|
||||
msgstr "اشتراکهای ریپاد"
|
||||
|
||||
#: /app/lib/Service/SearchProvider.php:29
|
||||
#: /app/lib/Service/SearchProvider.php:64
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:3
|
||||
msgid "Podcast"
|
||||
msgstr "پادپخش"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:2
|
||||
msgid "RePod"
|
||||
msgstr "ریپاد"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:4
|
||||
msgid "🔊 Browse, manage and listen to podcasts"
|
||||
msgstr "🔊 مرور، مدیریت و گوش دادن به پادپخشها"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:5
|
||||
msgid ""
|
||||
"## Features\n"
|
||||
"- 🔍 Browse and subscribe huge collection of podcasts\n"
|
||||
"- 🔊 Listen to episodes directly in Nextcloud\n"
|
||||
"- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and "
|
||||
"[other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-"
|
||||
"of-gpoddersync)\n"
|
||||
"- 📱 Mobile friendly interface\n"
|
||||
"- 📡 Import and export your subscriptions\n"
|
||||
"- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/"
|
||||
"repod#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"\n"
|
||||
"## Requirements\n"
|
||||
"You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) "
|
||||
"installed to use this app!"
|
||||
msgstr ""
|
||||
"## ویژگیها\n"
|
||||
"- 🔍 مرور و اشتراک در مجموعه بزرگ پادپخشها\n"
|
||||
"- 🔊 گوش دادن به قسمتها مستقیماً در نکستکلود\n"
|
||||
"- 🌐 همگامسازی فعالیتها با [AntennaPod](https://antennapod.org/) و "
|
||||
"[برنامههای دیگر](https://git.crystalyx.net/Xefir/repod#clients-supporting-"
|
||||
"sync-of-gpoddersync)\n"
|
||||
"- 📱 رابط مناسب برای تلفنهمراه\n"
|
||||
"- 📡 وارد کردن و صادر کردن اشتراکها\n"
|
||||
"- ➡️ مقایسه کامل ویژگیها در [اینجا](https://git.crystalyx.net/Xefir/"
|
||||
"repod#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"\n"
|
||||
"## پیشنیازها\n"
|
||||
"برای بهکارگیری این برنامه، باید [GPodderSync](https://apps.nextcloud.com/"
|
||||
"apps/gpoddersync) نصب شده باشد!"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:1
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:25
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:26
|
||||
msgid "Download"
|
||||
msgstr "بارگیری"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:2
|
||||
msgid "Skip to {match}"
|
||||
msgstr "پرش به {match}"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:3
|
||||
msgid "Add a RSS link"
|
||||
msgstr "افزودن پیوند RSS"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:4
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:5
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:6
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:13
|
||||
msgid "Subscribe"
|
||||
msgstr "اشتراک کردن"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:7
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:14
|
||||
msgid "Error while adding the feed"
|
||||
msgstr "خطا در افزودن خوراک"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:8
|
||||
msgid "Could not fetch search results"
|
||||
msgstr "ناتوانی در دریافت یافتههای جستجو"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:9
|
||||
msgid "New podcasts"
|
||||
msgstr "پادپخشهای تازه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:10
|
||||
msgid "Hot podcasts"
|
||||
msgstr "پادپخشهای پرطرفدار"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:11
|
||||
msgid "Could not fetch tops"
|
||||
msgstr "ناتوانی در دریافت برترینها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:12
|
||||
msgid "Copy feed"
|
||||
msgstr "رونوشت خوراک"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:15
|
||||
msgid "Link copied to the clipboard"
|
||||
msgstr "پیوند به بریدهدان رونویسی شد"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:16
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:17
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:43
|
||||
msgid "Play"
|
||||
msgstr "پخش"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:18
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:19
|
||||
msgid "Stop"
|
||||
msgstr "توقف"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:20
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:21
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:22
|
||||
msgid "Read"
|
||||
msgstr "خواندهشده"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:23
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:24
|
||||
msgid "Open website"
|
||||
msgstr "بازکردن وبگاه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:27
|
||||
msgid "Select"
|
||||
msgstr "گزینش"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:28
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:38
|
||||
msgid "Could not change the status of the episode"
|
||||
msgstr "ناتوانی در تغییر وضعیت قسمت"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:29
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:30
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:31
|
||||
msgid "Read all"
|
||||
msgstr "خواندن همه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:32
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:33
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:34
|
||||
msgid "Unread all"
|
||||
msgstr "ناخوانده کردن همه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:35
|
||||
msgid "Select all"
|
||||
msgstr "گزینش همه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:36
|
||||
msgid "Unselect all"
|
||||
msgstr "رد گزینش همه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:37
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:40
|
||||
msgid "Could not fetch episodes"
|
||||
msgstr "ناتوانی در دریافت قسمتها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:39
|
||||
msgid "%n episode selected"
|
||||
msgid_plural "%n episodes selected"
|
||||
msgstr[0] "%n قسمت گزینش شد"
|
||||
msgstr[1] "%n قسمت گزینش شدند"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:41
|
||||
msgid "Rewind 10 seconds"
|
||||
msgstr "بازگرداندن ۱۰ ثانیه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:42
|
||||
msgid "Pause"
|
||||
msgstr "مکث"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:44
|
||||
msgid "Fast forward 30 seconds"
|
||||
msgstr "پیشروی سریع ۳۰ ثانیه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:45
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:46
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:47
|
||||
msgid "Mute"
|
||||
msgstr "بیصدا"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:48
|
||||
msgid "Unmute"
|
||||
msgstr "با صدا"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:49
|
||||
msgid "Export subscriptions"
|
||||
msgstr "صادر کردن اشتراکها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:50
|
||||
msgid "Filtering episodes"
|
||||
msgstr "پالایش قسمتها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:51
|
||||
msgid "Show all"
|
||||
msgstr "نمایش همه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:52
|
||||
msgid "Listened"
|
||||
msgstr "گوششده"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:53
|
||||
msgid "Listening"
|
||||
msgstr "در حال گوش دادن"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:54
|
||||
msgid "Unlistened"
|
||||
msgstr "شنیده نشده"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:55
|
||||
msgid "Import subscriptions"
|
||||
msgstr "وارد کردن اشتراکها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:56
|
||||
msgid "Import OPML file"
|
||||
msgstr "وارد کردن پرونده OPML"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:57
|
||||
msgid "Rate RePod ❤️"
|
||||
msgstr "امتیاز به ریپاد ❤️"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:58
|
||||
#, fuzzy
|
||||
msgid "Settings"
|
||||
msgstr "تنظیمات"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
msgid "Sleep timer"
|
||||
msgstr "زمانسنج خواب"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
msgid "Minutes"
|
||||
msgstr "دقیقه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
msgid "%n min"
|
||||
msgid_plural "%n mins"
|
||||
msgstr[0] "%n دقیقه"
|
||||
msgstr[1] "%n دقیقه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
msgid "%n sec"
|
||||
msgid_plural "%n secs"
|
||||
msgstr[0] "%n ثانیه"
|
||||
msgstr[1] "%n ثانیه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
msgid "Playback speed"
|
||||
msgstr "سرعت پخش"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:64
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:65
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
msgid "Favorite"
|
||||
msgstr "برگزیدن"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
msgid "Are you sure you want to delete this subscription?"
|
||||
msgstr "آیا مطمئن هستید که میخواهید این اشتراک را پاک کنید؟"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
msgid "Error while removing the feed"
|
||||
msgstr "خطا در پاک کردن خوراک"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
msgid "You can only have 10 favorites"
|
||||
msgstr "فقط میتوانید ۱۰ مورد برگزیده داشته باشید"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
msgid "Add a podcast"
|
||||
msgstr "افزودن پادپخش"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
msgid "Could not fetch subscriptions"
|
||||
msgstr "ناتوانی در دریافت اشتراکها"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
msgid "Find a podcast"
|
||||
msgstr "یافتن پادپخش"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
msgid "Error loading feed"
|
||||
msgstr "خطا در بارگذاری خوراک"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
msgid "Missing required app"
|
||||
msgstr "برنامه موردنیاز نیست"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
msgid "Install GPodder Sync"
|
||||
msgstr "نصب GPodder Sync"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr "سنجاق کردن برخی اشتراکها برای دیدن بهروزرسانیهای تازه"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:77
|
||||
msgid "No favorites"
|
||||
msgstr "بدون برگزیده"
|
||||
|
||||
#: /app/src/store/player.ts:123
|
||||
msgid "A browser extension conflict with RePod"
|
||||
msgstr "ناسازگاری افزونه مرورگر با ریپاد"
|
@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Nextcloud 3.14159\n"
|
||||
"Report-Msgid-Bugs-To: translations\\@example.com\n"
|
||||
"POT-Creation-Date: 2024-12-11 20:03+0000\n"
|
||||
"POT-Creation-Date: 2025-04-23 21:17+0000\n"
|
||||
"PO-Revision-Date: 2024-12-11 20:06+0000\n"
|
||||
"Last-Translator: Michel Roux <xefir@crystalyx.net>\n"
|
||||
"Language-Team: French <https://translate.crystalyx.net/projects/repod/gitea/"
|
||||
@ -18,12 +18,12 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.8.4\n"
|
||||
|
||||
#: /app/lib/Controller/OpmlController.php:46
|
||||
#: /app/lib/Controller/OpmlController.php:50
|
||||
msgid "RePod Subscriptions"
|
||||
msgstr "Abonnements sur RePod"
|
||||
|
||||
#: /app/lib/Service/SearchProvider.php:29
|
||||
#: /app/lib/Service/SearchProvider.php:61
|
||||
#: /app/lib/Service/SearchProvider.php:64
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:3
|
||||
msgid "Podcast"
|
||||
msgstr "Podcast"
|
||||
@ -61,8 +61,8 @@ msgstr ""
|
||||
"supporting-sync-of-gpoddersync)\n"
|
||||
"- 📱 Interface optimisée pour mobiles et ordinateurs\n"
|
||||
"- 📡 Import/export de ses abonnements\n"
|
||||
"- ➡️ Tableau récapitulatif complet des fonctionnalitées [ici](https://git."
|
||||
"crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"- ➡️ Tableau récapitulatif complet des fonctionnalitées [ici](https://"
|
||||
"git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"\n"
|
||||
"## Pré-requis\n"
|
||||
"Vous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) "
|
||||
@ -239,80 +239,84 @@ msgid "Rate RePod ❤️"
|
||||
msgstr "Donnez votre avis ❤️"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:58
|
||||
msgid "Settings"
|
||||
msgstr "Paramètres"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
msgid "Sleep timer"
|
||||
msgstr "Minuteur"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
msgid "Minutes"
|
||||
msgstr "Minutes"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
msgid "%n min"
|
||||
msgid_plural "%n mins"
|
||||
msgstr[0] "%n min"
|
||||
msgstr[1] "%n mins"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
msgid "%n sec"
|
||||
msgid_plural "%n secs"
|
||||
msgstr[0] "%n sec"
|
||||
msgstr[1] "%n secs"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
msgid "Playback speed"
|
||||
msgstr "Vitesse de lecture"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:64
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:65
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
msgid "Favorite"
|
||||
msgstr "Favori"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
msgid "Are you sure you want to delete this subscription?"
|
||||
msgstr "Êtes-vous sûr de vouloir supprimer ce flux ?"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
msgid "Error while removing the feed"
|
||||
msgstr "Erreur lors de la suppression du flux"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
msgid "You can only have 10 favorites"
|
||||
msgstr "Vous ne pouvez avoir que 10 favoris"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
msgid "Add a podcast"
|
||||
msgstr "Ajouter un podcast"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
msgid "Could not fetch subscriptions"
|
||||
msgstr "Impossible de récupérer les flux"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
msgid "Find a podcast"
|
||||
msgstr "Chercher un podcast"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
msgid "Error loading feed"
|
||||
msgstr "Erreur lors du chargement du flux"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
msgid "Missing required app"
|
||||
msgstr "Une application requise est manquante"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
msgid "Install GPodder Sync"
|
||||
msgstr "Installer GPodder Sync"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr ""
|
||||
"Ajoutez des abonnements en favoris pour obtenir les dernières nouvelles ici"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:77
|
||||
msgid "No favorites"
|
||||
msgstr "Aucun favoris"
|
||||
|
||||
#: /app/src/store/player.ts:93
|
||||
#: /app/src/store/player.ts:123
|
||||
msgid "A browser extension conflict with RePod"
|
||||
msgstr "Une extension de votre navigateur entre en conflit avec RePod"
|
||||
|
325
translationfiles/pl/repod.po
Normal file
325
translationfiles/pl/repod.po
Normal file
@ -0,0 +1,325 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Nextcloud package.
|
||||
# m0bi <m0bi@koop.net.pl>, 2025.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Nextcloud 3.14159\n"
|
||||
"Report-Msgid-Bugs-To: translations\\@example.com\n"
|
||||
"POT-Creation-Date: 2025-04-23 21:17+0000\n"
|
||||
"PO-Revision-Date: 2025-04-25 08:26+0000\n"
|
||||
"Last-Translator: m0bi <m0bi@koop.net.pl>\n"
|
||||
"Language-Team: Polish <https://translate.crystalyx.net/projects/repod/gitea/"
|
||||
"pl/>\n"
|
||||
"Language: pl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.11\n"
|
||||
|
||||
#: /app/lib/Controller/OpmlController.php:50
|
||||
msgid "RePod Subscriptions"
|
||||
msgstr "Subskrypcje RePod"
|
||||
|
||||
#: /app/lib/Service/SearchProvider.php:29
|
||||
#: /app/lib/Service/SearchProvider.php:64
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:3
|
||||
msgid "Podcast"
|
||||
msgstr "Podkast"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:2
|
||||
msgid "RePod"
|
||||
msgstr "RePod"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:4
|
||||
msgid "🔊 Browse, manage and listen to podcasts"
|
||||
msgstr "🔊 Przeglądanie, zarządzanie i słuchanie podkastów"
|
||||
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:5
|
||||
msgid ""
|
||||
"## Features\n"
|
||||
"- 🔍 Browse and subscribe huge collection of podcasts\n"
|
||||
"- 🔊 Listen to episodes directly in Nextcloud\n"
|
||||
"- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other "
|
||||
"apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-"
|
||||
"gpoddersync)\n"
|
||||
"- 📱 Mobile friendly interface\n"
|
||||
"- 📡 Import and export your subscriptions\n"
|
||||
"- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/"
|
||||
"repod#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"\n"
|
||||
"## Requirements\n"
|
||||
"You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) "
|
||||
"installed to use this app!"
|
||||
msgstr ""
|
||||
"## Funkcje\n"
|
||||
"- 🔍 Przeglądaj i subskrybuj ogromną kolekcję podcastów\n"
|
||||
"- 🔊 Słuchaj odcinków bezpośrednio w Nextcloud\n"
|
||||
"- 🌐 Synchronizuj swoją aktywność z [AntennaPod](https://antennapod.org/) i "
|
||||
"[innymi aplikacjami](https://git.crystalyx.net/Xefir/repod#clients-"
|
||||
"supporting-sync-of-gpoddersync)\n"
|
||||
"- 📱 Interfejs dla urządzeń mobilnych\n"
|
||||
"- 📡 Importuj i eksportuj swoje subskrypcje\n"
|
||||
"- ➡️ Pełne porównanie funkcji [tutaj](https://git.crystalyx.net/Xefir/repod"
|
||||
"#comparaison-with-similar-apps-for-nextcloud)\n"
|
||||
"\n"
|
||||
"## Wymagania\n"
|
||||
"Aby korzystać z tej aplikacji, musisz mieć zainstalowany [GPodderSync]"
|
||||
"(https://apps.nextcloud.com/apps/gpoddersync)!"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:1
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:25
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:26
|
||||
msgid "Download"
|
||||
msgstr "Pobierz"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:2
|
||||
msgid "Skip to {match}"
|
||||
msgstr "Skocz do {match}"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:3
|
||||
msgid "Add a RSS link"
|
||||
msgstr "Dodaj RSS z linka"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:4
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:5
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:6
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:13
|
||||
msgid "Subscribe"
|
||||
msgstr "Subskrybuj"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:7
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:14
|
||||
msgid "Error while adding the feed"
|
||||
msgstr "Błąd podczas dodawania kanału"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:8
|
||||
msgid "Could not fetch search results"
|
||||
msgstr "Nie można pobrać wyników wyszukiwania"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:9
|
||||
msgid "New podcasts"
|
||||
msgstr "Nowe podkasty"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:10
|
||||
msgid "Hot podcasts"
|
||||
msgstr "Gorące podkasty"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:11
|
||||
msgid "Could not fetch tops"
|
||||
msgstr "Nie można pobrać poleceń"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:12
|
||||
msgid "Copy feed"
|
||||
msgstr "Kopiuj kanał"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:15
|
||||
msgid "Link copied to the clipboard"
|
||||
msgstr "Link skopiowany do schowka"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:16
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:17
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:43
|
||||
msgid "Play"
|
||||
msgstr "Odtwarzaj"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:18
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:19
|
||||
msgid "Stop"
|
||||
msgstr "Stop"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:20
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:21
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:22
|
||||
msgid "Read"
|
||||
msgstr "Czytaj"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:23
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:24
|
||||
msgid "Open website"
|
||||
msgstr "Otwórz stronę"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:27
|
||||
msgid "Select"
|
||||
msgstr "Wybierz"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:28
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:38
|
||||
msgid "Could not change the status of the episode"
|
||||
msgstr "Nie można zmienić stanu odcinka"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:29
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:30
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:31
|
||||
msgid "Read all"
|
||||
msgstr "Czytaj wszystko"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:32
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:33
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:34
|
||||
msgid "Unread all"
|
||||
msgstr "Cofnij czytaj wszystko"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:35
|
||||
msgid "Select all"
|
||||
msgstr "Zaznacz wszystko"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:36
|
||||
msgid "Unselect all"
|
||||
msgstr "Odznacz wszystko"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:37
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:40
|
||||
msgid "Could not fetch episodes"
|
||||
msgstr "Nie można pobrać odcinków"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:39
|
||||
msgid "%n episode selected"
|
||||
msgid_plural "%n episodes selected"
|
||||
msgstr[0] "%n wybrany odcinek"
|
||||
msgstr[1] "%n wybrane odcinki"
|
||||
msgstr[2] "%n wybranych odcinków"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:41
|
||||
msgid "Rewind 10 seconds"
|
||||
msgstr "Przewiń 10 sekund"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:42
|
||||
msgid "Pause"
|
||||
msgstr "Pauza"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:44
|
||||
msgid "Fast forward 30 seconds"
|
||||
msgstr "Do przodu 30 sekund"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:45
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:46
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:47
|
||||
msgid "Mute"
|
||||
msgstr "Wycisz"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:48
|
||||
msgid "Unmute"
|
||||
msgstr "Wyłącz wyciszenie"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:49
|
||||
msgid "Export subscriptions"
|
||||
msgstr "Eksportuj subskrypcje"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:50
|
||||
msgid "Filtering episodes"
|
||||
msgstr "Filtr odcinków"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:51
|
||||
msgid "Show all"
|
||||
msgstr "Pokaż wszystko"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:52
|
||||
msgid "Listened"
|
||||
msgstr "Słuchany"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:53
|
||||
msgid "Listening"
|
||||
msgstr "Słuchanie"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:54
|
||||
msgid "Unlistened"
|
||||
msgstr "Niewysłuchane"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:55
|
||||
msgid "Import subscriptions"
|
||||
msgstr "Import subskrypcji"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:56
|
||||
msgid "Import OPML file"
|
||||
msgstr "Import pliku OPML"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:57
|
||||
msgid "Rate RePod ❤️"
|
||||
msgstr "Oceń RePod ❤️"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:58
|
||||
msgid "Settings"
|
||||
msgstr "Ustawienia"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
msgid "Sleep timer"
|
||||
msgstr "Wyłącznik czasowy"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
msgid "Minutes"
|
||||
msgstr "Minuty"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
msgid "%n min"
|
||||
msgid_plural "%n mins"
|
||||
msgstr[0] "%n minuta"
|
||||
msgstr[1] "%n minuty"
|
||||
msgstr[2] "%n minut"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
msgid "%n sec"
|
||||
msgid_plural "%n secs"
|
||||
msgstr[0] "%n sekunda"
|
||||
msgstr[1] "%n sekundy"
|
||||
msgstr[2] "%n sekund"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
msgid "Playback speed"
|
||||
msgstr "Prędkość odtwarzania"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:64
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:65
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
msgid "Favorite"
|
||||
msgstr "Ulubione"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
msgid "Are you sure you want to delete this subscription?"
|
||||
msgstr "Czy na pewno chcesz usunąć tę subskrypcję?"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
msgid "Error while removing the feed"
|
||||
msgstr "Błąd podczas usuwania kanału"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
msgid "You can only have 10 favorites"
|
||||
msgstr "Możesz mieć tylko 10 ulubionych"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
msgid "Add a podcast"
|
||||
msgstr "Dodaj podkast"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
msgid "Could not fetch subscriptions"
|
||||
msgstr "Nie można pobrać subskrypcji"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
msgid "Find a podcast"
|
||||
msgstr "Znajdź podkast"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
msgid "Error loading feed"
|
||||
msgstr "Błąd ładowania kanału"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
msgid "Missing required app"
|
||||
msgstr "Brak wymaganej aplikacji"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
msgid "Install GPodder Sync"
|
||||
msgstr "Zainstaluj GPodder Sync"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr "Przypnij niektóre subskrypcje, by zobaczyć aktualizacje"
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:77
|
||||
msgid "No favorites"
|
||||
msgstr "Brak ulubionych"
|
||||
|
||||
#: /app/src/store/player.ts:123
|
||||
msgid "A browser extension conflict with RePod"
|
||||
msgstr "Konflikt rozszerzenia przeglądarki z RePod"
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Nextcloud 3.14159\n"
|
||||
"Report-Msgid-Bugs-To: translations\\@example.com\n"
|
||||
"POT-Creation-Date: 2024-12-11 20:03+0000\n"
|
||||
"POT-Creation-Date: 2025-04-23 21:17+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -18,12 +18,12 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||
|
||||
#: /app/lib/Controller/OpmlController.php:46
|
||||
#: /app/lib/Controller/OpmlController.php:50
|
||||
msgid "RePod Subscriptions"
|
||||
msgstr ""
|
||||
|
||||
#: /app/lib/Service/SearchProvider.php:29
|
||||
#: /app/lib/Service/SearchProvider.php:61
|
||||
#: /app/lib/Service/SearchProvider.php:64
|
||||
#: /app/specialAppInfoFakeDummyForL10nScript.php:3
|
||||
msgid "Podcast"
|
||||
msgstr ""
|
||||
@ -225,79 +225,83 @@ msgid "Rate RePod ❤️"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:58
|
||||
msgid "Sleep timer"
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:59
|
||||
msgid "Minutes"
|
||||
msgid "Sleep timer"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:60
|
||||
msgid "Minutes"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
msgid "%n min"
|
||||
msgid_plural "%n mins"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:61
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
msgid "%n sec"
|
||||
msgid_plural "%n secs"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:62
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
msgid "Playback speed"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:63
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:64
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:65
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
msgid "Favorite"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:66
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
msgid "Are you sure you want to delete this subscription?"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:67
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
msgid "Error while removing the feed"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:68
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
msgid "You can only have 10 favorites"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:69
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
msgid "Add a podcast"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:70
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
msgid "Could not fetch subscriptions"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:71
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
msgid "Find a podcast"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:72
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
msgid "Error loading feed"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:73
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
msgid "Missing required app"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:74
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
msgid "Install GPodder Sync"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:75
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
msgid "Pin some subscriptions to see their latest updates"
|
||||
msgstr ""
|
||||
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:76
|
||||
#: /app/specialVueFakeDummyForL10nScript.js:77
|
||||
msgid "No favorites"
|
||||
msgstr ""
|
||||
|
||||
#: /app/src/store/player.ts:93
|
||||
#: /app/src/store/player.ts:123
|
||||
msgid "A browser extension conflict with RePod"
|
||||
msgstr ""
|
||||
|
Loading…
x
Reference in New Issue
Block a user