Compare commits

...

416 Commits
1.1.1 ... main

Author SHA1 Message Date
674f0193db fix: 👷 update makefile to ignore new ts files
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Successful in 1m15s
2024-09-15 15:47:18 +02:00
ccc903be97 docs: 📝 better wording (#137)
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 1m3s
repod / release (push) Has been skipped
2024-09-15 15:41:30 +02:00
10c7a1f907 docs: 📝 add other app listing (#137)
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 46s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-09-15 15:36:25 +02:00
a6ab9c69d9 chore: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 46s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-09-15 15:28:52 +02:00
285e9f7dfb chore: 🔖 update version
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 1m6s
repod / release (push) Has been skipped
2024-09-15 15:07:47 +02:00
60fc620b79 fix: 📝 update first impressions (fix #137)
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 20s
repod / php (push) Successful in 44s
repod / nodejs (push) Has been cancelled
2024-09-15 15:06:00 +02:00
5588bb93e3 fix: 💄 add margin to make favorites more spaced
All checks were successful
repod / xml (push) Successful in 1m45s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m43s
repod / release (push) Has been skipped
2024-09-15 14:34:13 +02:00
b97d4487bb fix: 🧑‍💻 fix sourcemap crashing on watch by disabling sourcemap entierly 2024-09-15 14:33:37 +02:00
29c29cdfdd Merge pull request 'typescript #149' (#152) from typescript into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 38s
repod / nodejs (push) Successful in 1m0s
repod / release (push) Has been skipped
Reviewed-on: #152
2024-09-14 15:26:16 +00:00
d7c3b87d8d chore: ⬆️ update locks
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 57s
repod / release (push) Has been skipped
2024-09-14 17:14:49 +02:00
9fa48c2da3 fix: 📱 fix subscribe button to the right
Some checks failed
repod / xml (push) Successful in 7s
repod / php (push) Failing after 19s
repod / nodejs (push) Successful in 50s
repod / release (push) Has been skipped
2024-09-14 17:11:11 +02:00
3cea8d3505 fix: 🎨 improve small tips 2024-09-14 17:11:11 +02:00
23280d68b9 fix: 🐛 fix all small bugs 2024-09-14 17:11:11 +02:00
1e1bb03c23 chore: ⬆️ update locks 2024-09-14 17:11:11 +02:00
fc86f62d93 refactor: ♻️ typescript ok, need tests 2024-09-14 17:10:56 +02:00
83e3358e9b refactor: 🚧 still working on typescript conversion 2024-09-14 17:10:56 +02:00
38bc986bb3 refactor: 🚧 introducing typescript (not working now) 2024-09-14 17:10:46 +02:00
eae106e72b Merge pull request 'chore(deps): update dependency vue to v3.5.5' (#154) from renovate/vue-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 39s
repod / nodejs (push) Successful in 54s
repod / release (push) Has been skipped
Reviewed-on: #154
2024-09-14 09:12:54 +00:00
3c358a3c5c Merge pull request 'chore(deps): update dependency vite to v5.4.5' (#153) from renovate/vite-5.x-lockfile into main
Some checks are pending
repod / xml (push) Waiting to run
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
Reviewed-on: #153
2024-09-14 09:12:48 +00:00
Renovate Bot
79ee855f9b chore(deps): update dependency vue to v3.5.5
All checks were successful
repod / xml (push) Successful in 7s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 43s
repod / release (push) Has been skipped
2024-09-14 06:57:27 +00:00
Renovate Bot
5150cb6501 chore(deps): update dependency vite to v5.4.5
All checks were successful
repod / xml (push) Successful in 1m4s
repod / php (push) Successful in 42s
repod / nodejs (push) Successful in 53s
repod / release (push) Has been skipped
2024-09-14 06:57:16 +00:00
1d85811ad3 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.7' (#150) from renovate/nextcloud-ocp-29.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 55s
repod / release (push) Has been skipped
Reviewed-on: #150
2024-09-13 07:32:52 +00:00
872b0ced0a Merge pull request 'chore(deps): update dependency vue-router to v4.4.5' (#151) from renovate/vue-router-4.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 15s
repod / php (push) Has been cancelled
Reviewed-on: #151
2024-09-13 07:32:30 +00:00
Renovate Bot
2a280c3493 chore(deps): update dependency vue-router to v4.4.5
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 46s
repod / nodejs (push) Successful in 51s
repod / release (push) Has been skipped
2024-09-13 06:56:37 +00:00
Renovate Bot
c9f922b31d chore(deps): update dependency nextcloud/ocp to v29.0.7
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 57s
repod / release (push) Has been skipped
2024-09-13 06:56:20 +00:00
c983ab8d3b fix: disable iife and build with inlineCSS enable
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Has been skipped
2024-09-12 22:10:10 +02:00
4f0685ccbd Merge pull request 'chore(deps): update dependency vite to v5.4.4' (#147) from renovate/vite-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 1m29s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m13s
repod / release (push) Has been skipped
Reviewed-on: #147
2024-09-12 13:40:56 +00:00
e165a070c8 Merge pull request 'chore(deps): update dependency vite-plugin-vue-devtools to v7.4.5' (#148) from renovate/vite-plugin-vue-devtools-7.x-lockfile into main
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
Reviewed-on: #148
2024-09-12 13:40:48 +00:00
Renovate Bot
622f5ec635 chore(deps): update dependency vite-plugin-vue-devtools to v7.4.5
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 47s
repod / nodejs (push) Successful in 54s
repod / release (push) Has been skipped
2024-09-12 06:51:56 +00:00
Renovate Bot
7d64e3370c chore(deps): update dependency vite to v5.4.4
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m8s
repod / release (push) Has been skipped
2024-09-12 06:51:39 +00:00
fcf99e5bbf chore: ⬆️ update locks
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
2024-09-11 09:12:59 +02:00
924106202a docs: 📝 Add Cardo to list of compatible clients 2024-09-11 09:09:07 +02:00
ce2412fb01 Merge pull request 'chore(deps): update dependency vue-router to v4.4.4' (#146) from renovate/vue-router-4.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m0s
repod / release (push) Has been skipped
Reviewed-on: #146
2024-09-11 07:06:40 +00:00
6c348d5583 Merge pull request 'chore(deps): update dependency vue to v3.5.4' (#145) from renovate/vue-3.x-lockfile into main
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
Reviewed-on: #145
2024-09-11 07:06:25 +00:00
Renovate Bot
7eef3ceaf0 chore(deps): update dependency vue-router to v4.4.4
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 56s
repod / release (push) Has been skipped
2024-09-11 06:36:34 +00:00
Renovate Bot
5321c0a3bf chore(deps): update dependency vue to v3.5.4
All checks were successful
repod / xml (push) Successful in 1m32s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m42s
repod / release (push) Has been skipped
2024-09-11 06:36:19 +00:00
fe40b7c9f7 Merge pull request 'chore(deps): update dependency vimeo/psalm to v5.26.1' (#144) from renovate/vimeo-psalm-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m3s
repod / release (push) Has been skipped
Reviewed-on: #144
2024-09-10 07:14:57 +00:00
Renovate Bot
11a1db72c6 chore(deps): update dependency vimeo/psalm to v5.26.1
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-09-10 06:43:50 +00:00
7f00696140 Merge pull request 'chore(deps): update dependency vimeo/psalm to v5.26.0' (#143) from renovate/vimeo-psalm-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
Reviewed-on: #143
2024-09-09 08:52:40 +00:00
Renovate Bot
33dcbe9162 chore(deps): update dependency vimeo/psalm to v5.26.0
All checks were successful
repod / xml (push) Successful in 1m46s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 1m45s
repod / release (push) Has been skipped
2024-09-09 06:49:32 +00:00
5c6542e60c Merge pull request 'chore(deps): update dependency vue to v3.5.3' (#142) from renovate/vue-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
Reviewed-on: #142
2024-09-06 07:13:09 +00:00
Renovate Bot
ea6704c537 chore(deps): update dependency vue to v3.5.3
All checks were successful
repod / xml (push) Successful in 1m30s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m35s
repod / release (push) Has been skipped
2024-09-06 06:49:43 +00:00
df4ac80554 Merge pull request 'chore(deps): update dependency vite-plugin-vue-devtools to v7.4.4' (#140) from renovate/vite-plugin-vue-devtools-7.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
Reviewed-on: #140
2024-09-05 07:08:30 +00:00
2b2ab2af8f Merge pull request 'chore(deps): update dependency vue to v3.5.1' (#141) from renovate/vue-3.x-lockfile into main
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
Reviewed-on: #141
2024-09-05 07:08:19 +00:00
Renovate Bot
7b00eb22ff chore(deps): update dependency vue to v3.5.1
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 1m0s
repod / release (push) Has been skipped
2024-09-05 06:31:41 +00:00
Renovate Bot
ecee6ff2a8 chore(deps): update dependency vite-plugin-vue-devtools to v7.4.4
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m8s
repod / release (push) Has been skipped
2024-09-05 06:31:31 +00:00
57a22d9390 chore: ⬆️ update lock
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Has been skipped
2024-09-04 10:48:22 +02:00
42c35d3856 Merge pull request 'chore(deps): update dependency vite to v5.4.3' (#139) from renovate/vite-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 1m54s
repod / php (push) Successful in 1m38s
repod / nodejs (push) Successful in 1m50s
repod / release (push) Has been skipped
Reviewed-on: #139
2024-09-04 08:41:03 +00:00
4d199bc02b Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.6' (#138) from renovate/nextcloud-ocp-29.x-lockfile into main
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
Reviewed-on: #138
2024-09-04 08:40:23 +00:00
Renovate Bot
8a89cc06cd chore(deps): update dependency vite to v5.4.3
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 53s
repod / release (push) Has been skipped
2024-09-04 06:59:04 +00:00
Renovate Bot
03740231c5 chore(deps): update dependency nextcloud/ocp to v29.0.6
All checks were successful
repod / xml (push) Successful in 36s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m1s
repod / release (push) Has been skipped
2024-09-04 06:58:41 +00:00
b54ab2be91 style: 💩 leverage the available space between the episode title and the play button (but hacky way) fix #59
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
2024-09-03 16:12:11 +02:00
d1658a9408 chore: ⬆️ update locks
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m6s
repod / release (push) Has been skipped
2024-09-03 14:44:19 +02:00
1eb8b35501 refactor: 🎨 cleanup some old css class
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 59s
repod / release (push) Has been skipped
2024-09-02 15:54:21 +02:00
fb7780fead fix: 🐛 the #list slot breaks navigation on AppContent
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Has been skipped
2024-09-02 15:35:10 +02:00
19c56ef31d fix: 🔨 move vite dev to main
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
2024-09-02 14:43:39 +02:00
2bad1852d7 refactor: 🩹 use same condition system on all App atoms
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 59s
repod / release (push) Has been skipped
2024-09-02 14:13:57 +02:00
0302489924 fix: 🏗️ add missing slots on atoms
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 1m1s
repod / release (push) Has been skipped
2024-09-02 14:06:43 +02:00
81cb6a0191 fix: 💄 fix missing icon on empty contents
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-09-02 12:37:55 +02:00
094b7812cd Merge pull request 'new homepage based on favorites (fixes #130 #59)' (#131) from favorites into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Successful in 1m37s
Reviewed-on: #131
2024-09-02 09:27:56 +00:00
491ad89242 docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 54s
repod / release (push) Has been skipped
2024-09-02 11:27:18 +02:00
01e2dabb65 chore: 🔖 update version 2024-09-02 11:27:10 +02:00
a86ea6ab3f chore: 🌐 update langs
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 59s
repod / release (push) Has been skipped
2024-09-02 11:12:58 +02:00
7b7ceef503 perf: write getters for accessible filtered cookies values
All checks were successful
repod / xml (push) Successful in 1m36s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m34s
repod / release (push) Has been skipped
2024-09-02 10:51:48 +02:00
437c7868dd fix: 🐛 fix wrong state placement on action (fix #136) 2024-09-02 10:51:21 +02:00
7c151d8f58 style: 💄 tweak home for mobile
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m9s
repod / release (push) Has been skipped
2024-08-27 17:39:53 +02:00
b7025a7aa1 fix: 💄 fix padding and routing
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m6s
repod / release (push) Has been skipped
2024-08-27 16:41:58 +02:00
42035d6e18 refactor: 💥 big rewrite to extract episode to his own component
All checks were successful
repod / xml (push) Successful in 35s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-08-27 16:11:12 +02:00
5ed33d1cf6 refactor: 🚚 rework how routing works
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m11s
repod / release (push) Has been skipped
2024-08-27 09:42:52 +02:00
4e4730efd5 style: 💄 use NcGuestContent to separate favorites
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 1m6s
repod / release (push) Has been skipped
2024-08-26 17:17:14 +02:00
9005b519f3 refactor: 💄 refacto NcEmptyContent
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m11s
repod / release (push) Has been skipped
2024-08-26 16:36:13 +02:00
b0132287f0 style: 💄 improve style and detection of gpodder sync 2024-08-26 16:23:58 +02:00
062da25264 Merge branch 'main' into favorites
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 1m21s
repod / release (push) Has been skipped
2024-08-26 13:14:56 +00:00
fd0f8f9c7a Merge pull request 'chore(deps): update dependency eslint-plugin-pinia to ^0.4.0' (#135) from renovate/eslint-plugin-pinia-0.x into main
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 1m1s
repod / release (push) Has been skipped
Reviewed-on: #135
2024-08-26 06:55:16 +00:00
Renovate Bot
35610ee8da chore(deps): update dependency eslint-plugin-pinia to ^0.4.0
All checks were successful
repod / xml (push) Successful in 1m44s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m41s
repod / release (push) Has been skipped
2024-08-26 06:40:11 +00:00
60aedf3be5 fix: ⬆️ update lock and fix severall typos
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 1m16s
repod / release (push) Has been skipped
2024-08-25 09:53:52 +00:00
4bafb3306b Merge branch 'main' into favorites 2024-08-25 09:42:58 +00:00
58af1f6d40 Merge pull request 'chore(deps): update dependency nextcloud/coding-standard to v1.2.3' (#134) from renovate/nextcloud-coding-standard-1.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
Reviewed-on: #134
2024-08-24 07:18:48 +00:00
Renovate Bot
4eb9236ecb chore(deps): update dependency nextcloud/coding-standard to v1.2.3
All checks were successful
repod / xml (push) Successful in 1m38s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m13s
repod / release (push) Has been skipped
2024-08-24 06:52:06 +00:00
eb1196c841 feat: 🚧 wip on showing favorites
Some checks failed
repod / xml (push) Successful in 31s
repod / php (push) Failing after 1m8s
repod / nodejs (push) Failing after 1m20s
repod / release (push) Has been skipped
2024-08-22 17:35:05 +02:00
dd275a1f03 feat: 🧑‍💻 add vue devtools in dev 2024-08-22 17:34:27 +02:00
f205d3243f refactor: ♻️ rewrite data to arrow function 2024-08-22 13:30:52 +02:00
46b30f1ebb feat: ⚗️ implement waiting on home
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 1m14s
repod / release (push) Has been skipped
2024-08-21 13:11:09 +00:00
9be107edc9 chore: ⬆️ update lock
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m11s
repod / release (push) Has been skipped
2024-08-21 09:33:30 +00:00
4e6eee96bf Merge branch 'main' into favorites
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 1m12s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
2024-08-21 09:25:09 +00:00
ddef81f92f Merge pull request 'chore(deps): update dependency vite to v5.4.2' (#133) from renovate/vite-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
Reviewed-on: #133
2024-08-21 07:43:23 +00:00
456592adfc Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.5' (#132) from renovate/nextcloud-ocp-29.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 13s
repod / php (push) Has been cancelled
Reviewed-on: #132
2024-08-21 07:42:40 +00:00
Renovate Bot
147311013c chore(deps): update dependency vite to v5.4.2
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m0s
repod / release (push) Has been skipped
2024-08-21 06:36:56 +00:00
Renovate Bot
99dc3582c4 chore(deps): update dependency nextcloud/ocp to v29.0.5
All checks were successful
repod / xml (push) Successful in 1m55s
repod / php (push) Successful in 1m16s
repod / nodejs (push) Successful in 1m46s
repod / release (push) Has been skipped
2024-08-21 06:36:35 +00:00
2824431330 refactor: 🌐 rework read and add missing translations
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 58s
repod / release (push) Has been skipped
2024-08-17 18:19:45 +02:00
a30678bfd2 feat: add favorites (missing homepage)
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 1m12s
repod / release (push) Has been skipped
2024-08-17 17:56:12 +02:00
6bc8d70016 docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 1m5s
repod / release (push) Successful in 1m35s
2024-08-17 14:40:30 +02:00
c42d455d4b chore: 🔖 bump to 3.0
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-08-17 14:25:29 +02:00
5b08cf970e Merge pull request 'Migrate to vue3 (fix #126)' (#127) from vue3 into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 14s
repod / php (push) Has been cancelled
Reviewed-on: #127
2024-08-17 12:24:26 +00:00
cf6dd25378 Merge branch 'main' into vue3
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 59s
repod / release (push) Has been skipped
2024-08-17 14:18:57 +02:00
a2c3b389ba refactor: ♻️ move filename from url on utils
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 14s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Has been cancelled
2024-08-17 14:17:24 +02:00
5917c59610 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v6' (#129) from renovate/nextcloud-dialogs-6.x into main
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m29s
repod / release (push) Has been skipped
Reviewed-on: #129
2024-08-17 12:03:39 +00:00
Renovate Bot
6cf868dc51 chore(deps): update dependency @nextcloud/dialogs to v6
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-08-17 06:49:02 +00:00
66b59c52fa revert: css is on js, no need for ignoring
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 55s
repod / release (push) Has been skipped
2024-08-17 00:13:58 +02:00
36c3bd875b build: 📝 fix build and remove COC for now
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Has been skipped
2024-08-17 00:10:17 +02:00
5742d1a762 fix: fix episode ending status with watch
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 1m13s
repod / nodejs (push) Successful in 1m18s
repod / release (push) Has been skipped
2024-08-16 23:50:36 +02:00
bd9e3691b9 chore: ⬆️ update pinia
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
2024-08-15 22:04:10 +02:00
19427809ca fix: add download on episode list
All checks were successful
repod / xml (push) Successful in 37s
repod / php (push) Successful in 1m12s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-08-15 21:50:44 +02:00
544c91edee fix: 🐛 fix loop action
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m8s
repod / release (push) Has been skipped
2024-08-15 21:18:20 +02:00
cf6bd440bf refactor: move autoload to init in the right vue
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m9s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-08-15 19:10:19 +02:00
891d4762d0 fix: ✏️ fix typo on setRate
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m3s
repod / release (push) Has been skipped
2024-08-15 18:52:50 +02:00
a2b63241cc build: 🦺 add eslint plugin pinia and update deps 2024-08-15 18:52:34 +02:00
5db93914d2 fix: 🐛 fix filters
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m11s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-08-15 17:07:15 +02:00
68ada2b0e0 fix: 🐛 fix current active episode
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-08-15 16:42:51 +02:00
c91c17ae66 fix: 🐛 fix opacity
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 1m9s
repod / release (push) Has been skipped
2024-08-15 16:25:11 +02:00
b4160d23d2 chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 1m36s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m34s
repod / release (push) Has been skipped
2024-08-15 15:29:25 +02:00
caf0bb7ec0 fix: 🐛 fix forgotten player pinia trasition
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m2s
repod / release (push) Has been skipped
2024-08-11 21:48:13 +02:00
5f528e6b9b revert: revert extra-actions
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 38s
repod / php (push) Successful in 1m10s
repod / nodejs (push) Has been cancelled
2024-08-11 21:45:10 +02:00
196bc23b1a feat: add download attribute to download button
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 59s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Has been skipped
2024-08-10 22:30:35 +02:00
e78e3b2565 fix: 🐛 fix modal alignment
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m1s
repod / release (push) Has been skipped
2024-08-10 22:21:26 +02:00
b67123b578 fix: 🐛 fix modal
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 1m6s
repod / release (push) Has been skipped
2024-08-10 22:05:06 +02:00
53543a259f fix: 🐛 fix description bug
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-08-10 20:59:15 +02:00
7efb0327d4 fix: 🐛 fix prototype with async
All checks were successful
repod / xml (push) Successful in 1m47s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 1m18s
repod / release (push) Has been skipped
2024-08-09 22:51:32 +02:00
81af0c219f fix: 🐛 fix crash NcTextField
Some checks failed
repod / xml (push) Successful in 1m38s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Failing after 1m6s
repod / release (push) Has been skipped
2024-08-09 22:21:07 +02:00
1feb0291bb fix: 🎉 first working basic functionnalities
All checks were successful
repod / xml (push) Successful in 33s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 1m23s
repod / release (push) Has been skipped
2024-08-09 16:50:24 +02:00
989d5d38e1 perf: improve build by removing sourcemaps
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m9s
repod / release (push) Has been skipped
2024-08-09 10:10:58 +00:00
b4ccd98f77 fix: 📦 make it build !
Some checks failed
repod / xml (push) Successful in 13s
repod / php (push) Successful in 58s
repod / nodejs (push) Failing after 48s
repod / release (push) Has been skipped
2024-08-09 09:52:56 +00:00
75da02e05b refactor: 🏗️ rework to use pinia
Some checks failed
repod / xml (push) Successful in 1m38s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Failing after 57s
repod / release (push) Has been skipped
2024-08-09 09:38:00 +00:00
1530e8b294 style: 🎨 remove useless spaces
Some checks failed
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Failing after 59s
repod / release (push) Has been skipped
2024-08-09 01:11:44 +02:00
7e359bdf29 fix: 📈 forgot time loop
Some checks failed
repod / xml (push) Successful in 12s
repod / php (push) Successful in 58s
repod / nodejs (push) Failing after 45s
repod / release (push) Has been skipped
2024-08-09 01:02:39 +02:00
082161e177 refactor: ♻️ rewrite player store to pinia
Some checks failed
repod / xml (push) Successful in 28s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Failing after 58s
repod / release (push) Has been skipped
2024-08-09 00:58:25 +02:00
04ed6b101a build: 💄 use toastify instead of dialogs
Some checks failed
repod / xml (push) Successful in 33s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Failing after 1m4s
repod / release (push) Has been skipped
2024-08-08 22:39:43 +02:00
6456ccc3d0 refactor: 🧱 first commit to enable vue3 support
Some checks failed
repod / xml (push) Successful in 27s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Failing after 2m29s
repod / release (push) Has been skipped
2024-08-08 15:20:54 +00:00
e190a9eeb6 refactor: ♻️ use linkify and dompurify to show good descriptions
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 1m25s
repod / release (push) Has been skipped
2024-08-08 11:37:48 +02:00
e63ff6ef04 fix: 🔧 use new ENV syntax for dockerfile
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m33s
repod / release (push) Has been skipped
2024-08-08 09:56:42 +02:00
a50947ffaf fix: 💄 use NcActionButton instead of NcButton
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 1m41s
repod / release (push) Has been skipped
2024-08-07 22:17:51 +02:00
c97e927a15 style: 💄 use the new extra-actions on NcListItem
All checks were successful
repod / xml (push) Successful in 33s
repod / php (push) Successful in 1m13s
repod / nodejs (push) Successful in 1m36s
repod / release (push) Has been skipped
2024-08-07 22:05:50 +02:00
a6a0f0d4f8 chore: 📌 update lock
All checks were successful
repod / xml (push) Successful in 1m20s
repod / php (push) Successful in 1m9s
repod / nodejs (push) Successful in 1m44s
repod / release (push) Has been skipped
2024-08-07 20:24:17 +02:00
358c1d06c8 chore: 📌 update to nextcloud 30
All checks were successful
repod / xml (push) Successful in 1m54s
repod / php (push) Successful in 1m17s
repod / nodejs (push) Successful in 1m49s
repod / release (push) Has been skipped
2024-08-07 10:15:10 +02:00
1e452263a7 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.16.0' (#125) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
Reviewed-on: #125
2024-08-06 06:47:13 +00:00
Renovate Bot
bfa9cde661 chore(deps): update dependency @nextcloud/vue to v8.16.0
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 1m29s
repod / release (push) Has been skipped
2024-08-06 06:41:14 +00:00
0238107be2 chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m30s
repod / release (push) Has been skipped
2024-08-05 09:51:30 +02:00
f94b529d6d fix: 💄 take itunes image first
All checks were successful
repod / xml (push) Successful in 1m36s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
2024-08-05 09:38:37 +02:00
1302c82fdb Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.15.1' (#124) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 1m43s
repod / release (push) Has been skipped
Reviewed-on: #124
2024-07-30 07:26:04 +00:00
Renovate Bot
08b327e408 chore(deps): update dependency @nextcloud/vue to v8.15.1
All checks were successful
repod / xml (push) Successful in 1m34s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 2m5s
repod / release (push) Has been skipped
2024-07-30 06:40:01 +00:00
2104e2e6d8 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.15.0' (#123) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 1m15s
repod / nodejs (push) Successful in 1m45s
repod / release (push) Has been skipped
Reviewed-on: #123
2024-07-23 09:37:37 +00:00
Renovate Bot
c73e53d04e chore(deps): update dependency @nextcloud/vue to v8.15.0
All checks were successful
repod / xml (push) Successful in 1m44s
repod / php (push) Successful in 1m36s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Has been skipped
2024-07-23 06:42:44 +00:00
cee28f51a6 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.4' (#122) from renovate/nextcloud-ocp-29.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 1m32s
repod / release (push) Has been skipped
Reviewed-on: #122
2024-07-19 12:11:43 +00:00
Renovate Bot
1665e1e193 chore(deps): update dependency nextcloud/ocp to v29.0.4
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 1m29s
repod / release (push) Has been skipped
2024-07-19 06:30:15 +00:00
1d73de5925 Merge pull request 'chore(deps): update dependency eslint-plugin-prettier to v5.2.1' (#121) from renovate/eslint-plugin-prettier-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
Reviewed-on: #121
2024-07-18 14:14:50 +00:00
Renovate Bot
a753d1d634 chore(deps): update dependency eslint-plugin-prettier to v5.2.1
All checks were successful
repod / xml (push) Successful in 1m53s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Has been skipped
2024-07-18 06:50:42 +00:00
a91648848b fix: 🌐 fix translation
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m26s
repod / release (push) Has been skipped
2024-07-15 16:41:31 +02:00
a538b38160 fix: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 47s
repod / nodejs (push) Successful in 1m14s
repod / release (push) Has been skipped
2024-07-15 16:19:55 +02:00
8479cc1553 feat: 🌐 add german translation #120
All checks were successful
repod / xml (push) Successful in 1m7s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m58s
repod / release (push) Has been skipped
2024-07-15 16:14:02 +02:00
69a2c20338 docs: 📈 add more comparaisons between nextcloud apps
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m29s
repod / release (push) Has been skipped
2024-07-09 15:40:46 +02:00
55ee2634df fix: 🗑️ DELETE should show ended
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 1m22s
repod / release (push) Has been skipped
2024-07-09 14:58:50 +02:00
f3090c5490 chore: ⬆️ update deps
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 3m29s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Has been cancelled
2024-07-09 14:53:28 +02:00
d57189490e Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.14.0' (#118) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m17s
repod / release (push) Has been skipped
Reviewed-on: #118
2024-07-05 08:05:18 +00:00
d5c34fa719 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.5' (#117) from renovate/nextcloud-dialogs-5.x-lockfile into main
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 26s
repod / php (push) Successful in 55s
repod / nodejs (push) Has been cancelled
Reviewed-on: #117
2024-07-05 08:02:53 +00:00
Renovate Bot
57b581fa54 chore(deps): update dependency @nextcloud/vue to v8.14.0
All checks were successful
repod / xml (push) Successful in 29s
repod / php (push) Successful in 1m11s
repod / nodejs (push) Successful in 2m8s
repod / release (push) Has been skipped
2024-07-05 06:43:08 +00:00
Renovate Bot
74fa105d5a chore(deps): update dependency @nextcloud/dialogs to v5.3.5
All checks were successful
repod / xml (push) Successful in 1m34s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Has been skipped
2024-07-04 06:34:16 +00:00
d81e6b505c Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.13.0' (#115) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m43s
repod / release (push) Has been skipped
Reviewed-on: #115
2024-06-27 07:30:21 +00:00
Renovate Bot
ef66427afc chore(deps): update dependency @nextcloud/vue to v8.13.0
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 1m44s
repod / release (push) Has been skipped
2024-06-27 06:37:35 +00:00
f9b0c8fa39 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.4' (#113) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m40s
repod / release (push) Has been skipped
Reviewed-on: #113
2024-06-26 06:42:49 +00:00
b8466aebf1 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.3' (#114) from renovate/nextcloud-ocp-29.x-lockfile into main
Some checks are pending
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Waiting to run
repod / php (push) Waiting to run
Reviewed-on: #114
2024-06-26 06:42:34 +00:00
Renovate Bot
1aa6dad3ba chore(deps): update dependency nextcloud/ocp to v29.0.3
All checks were successful
repod / xml (push) Successful in 20s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 1m36s
repod / release (push) Has been skipped
2024-06-26 06:37:29 +00:00
Renovate Bot
0c0946559a chore(deps): update dependency @nextcloud/dialogs to v5.3.4
All checks were successful
repod / xml (push) Successful in 1m31s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 2m7s
repod / release (push) Has been skipped
2024-06-26 06:37:02 +00:00
fcf389f925 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.3' (#112) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 34s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 2m22s
repod / release (push) Has been skipped
Reviewed-on: #112
2024-06-23 14:02:31 +00:00
Renovate Bot
6c59851cb9 chore(deps): update dependency @nextcloud/dialogs to v5.3.3
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m29s
repod / release (push) Has been skipped
2024-06-22 06:39:27 +00:00
1d15ade42e Merge pull request 'chore(deps): update dependency vimeo/psalm to v5.25.0' (#111) from renovate/vimeo-psalm-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
Reviewed-on: #111
2024-06-20 07:30:16 +00:00
Renovate Bot
c85a347032 chore(deps): update dependency vimeo/psalm to v5.25.0
All checks were successful
repod / xml (push) Successful in 1m18s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 1m51s
repod / release (push) Has been skipped
2024-06-20 06:55:41 +00:00
ec605fde0a docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Successful in 1m46s
2024-06-14 20:06:45 +02:00
46b7d80652 chore: 📌 update version
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 42s
repod / nodejs (push) Successful in 1m25s
repod / release (push) Has been skipped
2024-06-14 19:53:35 +02:00
541c669dd5 chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 39s
repod / nodejs (push) Successful in 1m19s
repod / release (push) Has been skipped
2024-06-14 19:41:51 +02:00
79c6fbcc16 chore: 💚 fix psalm 2024-06-14 19:40:32 +02:00
42bfdb530b fix: 🐛 fix crash if no cache is configured
Some checks failed
repod / xml (push) Successful in 1m10s
repod / php (push) Failing after 44s
repod / nodejs (push) Successful in 1m25s
repod / release (push) Has been skipped
2024-06-14 19:32:26 +02:00
bc8db22fce Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.2' (#109) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m17s
repod / release (push) Has been skipped
Reviewed-on: #109
2024-06-11 14:04:36 +00:00
Renovate Bot
a4a00d4aea chore(deps): update dependency @nextcloud/dialogs to v5.3.2
All checks were successful
repod / xml (push) Successful in 1m29s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 2m0s
repod / release (push) Has been skipped
2024-06-11 06:38:37 +00:00
8d13fac7aa Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.2' (#108) from renovate/nextcloud-ocp-29.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 1m17s
repod / release (push) Has been skipped
Reviewed-on: #108
2024-06-07 07:04:32 +00:00
Renovate Bot
83e519d4c5 chore(deps): update dependency nextcloud/ocp to v29.0.2
All checks were successful
repod / xml (push) Successful in 1m28s
repod / php (push) Successful in 1m22s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-06-07 06:44:13 +00:00
7ba27d7c9c docs: 📝 wrong label for current changelog
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 38s
repod / nodejs (push) Successful in 1m16s
repod / release (push) Successful in 1m43s
2024-05-31 13:59:28 +02:00
5d75b51c63 docs: 📝 update changelog
Some checks failed
repod / xml (push) Successful in 9s
repod / php (push) Successful in 39s
repod / nodejs (push) Has been cancelled
repod / release (push) Has been cancelled
2024-05-31 13:58:36 +02:00
a60341f352 chore: 🔖 update version and deps
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 1m25s
repod / release (push) Has been skipped
2024-05-31 13:53:47 +02:00
c27f358f71 fix: missing aria-lebel on new subscribe on search button 2024-05-31 13:47:11 +02:00
691ee72ac5 fix: 🐛 do not show add if already subscribed
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 42s
repod / nodejs (push) Successful in 1m18s
repod / release (push) Has been skipped
2024-05-30 07:31:47 +00:00
7a4bbd8e47 fix: 🗑️ do not include screens on release
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 1m14s
repod / release (push) Successful in 1m29s
2024-05-30 00:24:33 +02:00
a53bab8be5 chore: 🔖 update version and changelog
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m18s
repod / release (push) Has been skipped
2024-05-30 00:21:45 +02:00
93b3cdbdc0 perf: disable sourcemap when building in prod
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 39s
repod / nodejs (push) Successful in 1m19s
repod / release (push) Has been skipped
2024-05-30 00:18:50 +02:00
46eb48e81e docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 1m14s
repod / release (push) Successful in 1m40s
2024-05-29 23:55:49 +02:00
8ee01ed80f revert: back to main to be consistent
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 39s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-29 23:47:20 +02:00
010550fa60 refactor: ♻️ app-template refacto part 2
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 39s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-29 17:55:14 +02:00
de1b7184d2 refactor: ♻️ update project from app-template
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 1m22s
repod / release (push) Has been skipped
2024-05-29 17:11:53 +02:00
e7d74d5378 Merge pull request 'feat: ability to subscribe to podcast from search list (#105)' (#106) from search-add-subs into main
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m13s
repod / release (push) Has been skipped
Reviewed-on: #106
2024-05-29 12:18:36 +00:00
a2c96f746b docs: 📝 fix template and add changelog
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-29 14:15:35 +02:00
f5a8e09d52 feat: ability to subscribe to podcast from search list (#105)
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-29 11:28:52 +00:00
228fb82d5d chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 1m4s
repod / php (push) Successful in 47s
repod / nodejs (push) Successful in 1m42s
repod / release (push) Has been skipped
2024-05-29 07:28:43 +00:00
51c21bf4d6 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29.0.1' (#104) from renovate/nextcloud-ocp-29.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 8m28s
repod / php (push) Successful in 13m48s
repod / nodejs (push) Successful in 11m19s
repod / release (push) Has been skipped
Reviewed-on: #104
2024-05-24 08:34:38 +00:00
Renovate Bot
57c455e77a chore(deps): update dependency nextcloud/ocp to v29.0.1
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 28s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-05-24 06:30:35 +00:00
2364e83fb6 chore: 📌 update version and deps
All checks were successful
repod / xml (push) Successful in 1m23s
repod / php (push) Successful in 38s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
2024-05-21 10:33:47 +00:00
4478c07f0c Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.12.0' (#103) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 1m16s
repod / release (push) Has been skipped
Reviewed-on: #103
2024-05-20 15:51:05 +00:00
Renovate Bot
fe2df167e0 chore(deps): update dependency @nextcloud/vue to v8.12.0
All checks were successful
repod / xml (push) Successful in 1m6s
repod / php (push) Successful in 34s
repod / nodejs (push) Successful in 1m49s
repod / release (push) Has been skipped
2024-05-20 06:49:00 +00:00
eb427681fb fix: 🔖 fix version
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 34s
repod / nodejs (push) Successful in 1m9s
repod / release (push) Successful in 1m19s
2024-05-18 22:12:57 +02:00
473d181807 docs: 📝 fix doc
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 9s
repod / php (push) Successful in 26s
repod / nodejs (push) Has been cancelled
2024-05-18 22:11:58 +02:00
176760cf3b docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 24s
repod / nodejs (push) Successful in 1m7s
repod / release (push) Successful in 1m19s
2024-05-18 22:04:33 +02:00
5c117de552 fix: 🚑 rollback hiding incompatible eps
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 20s
repod / php (push) Successful in 31s
repod / nodejs (push) Has been cancelled
2024-05-18 22:02:34 +02:00
a747286341 docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 26s
repod / nodejs (push) Successful in 1m4s
repod / release (push) Successful in 1m25s
2024-05-18 19:14:14 +02:00
c46f4f1c61 docs: 📝 fix comparaisons
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m13s
repod / release (push) Has been skipped
2024-05-18 18:57:21 +02:00
d64746be0b chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 1m15s
repod / release (push) Has been skipped
2024-05-18 12:46:11 +02:00
aa3c782005 Merge pull request 'chore(deps): update dependency @nextcloud/babel-config to v1.2.0' (#102) from renovate/nextcloud-babel-config-1.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 6s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m7s
repod / release (push) Has been skipped
Reviewed-on: #102
2024-05-17 07:04:58 +00:00
41c577f5cb Merge pull request 'chore(deps): update dependency @nextcloud/eslint-config to v8.4.1' (#101) from renovate/nextcloud-eslint-config-8.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 8s
repod / php (push) Has been cancelled
Reviewed-on: #101
2024-05-17 07:04:41 +00:00
Renovate Bot
176874f979 chore(deps): update dependency @nextcloud/babel-config to v1.2.0
All checks were successful
repod / xml (push) Successful in 6s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 1m3s
repod / release (push) Has been skipped
2024-05-17 06:32:09 +00:00
Renovate Bot
c6ab2ff692 chore(deps): update dependency @nextcloud/eslint-config to v8.4.1
All checks were successful
repod / xml (push) Successful in 1m17s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m38s
repod / release (push) Has been skipped
2024-05-17 06:32:00 +00:00
0825598c36 Merge pull request 'chore(deps): update dependency @nextcloud/eslint-config to v8.4.0' (#100) from renovate/nextcloud-eslint-config-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 1m17s
repod / release (push) Has been skipped
Reviewed-on: #100
2024-05-15 21:29:05 +00:00
2c078d32ae docs: 📝 add comparison with other podcasts app
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-15 23:26:30 +02:00
Renovate Bot
402f167206 chore(deps): update dependency @nextcloud/eslint-config to v8.4.0
All checks were successful
repod / xml (push) Successful in 1m10s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 1m37s
repod / release (push) Has been skipped
2024-05-15 19:36:07 +00:00
ef064f0eb3 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.11.3' (#98) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
Reviewed-on: #98
2024-05-08 08:39:36 +00:00
Renovate Bot
bd905cae1c chore(deps): update dependency @nextcloud/vue to v8.11.3
All checks were successful
repod / xml (push) Successful in 1m29s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
2024-05-08 06:28:52 +00:00
d0142b01dd Merge pull request 'chore(deps): update dependency @nextcloud/stylelint-config to v3.0.1' (#96) from renovate/nextcloud-stylelint-config-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 1m22s
repod / release (push) Has been skipped
Reviewed-on: #96
2024-05-07 18:29:14 +00:00
fc8c8f23c2 Merge pull request 'chore(deps): update dependency @nextcloud/l10n to v3.1.0' (#97) from renovate/nextcloud-l10n-3.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 12s
repod / php (push) Has been cancelled
Reviewed-on: #97
2024-05-07 18:28:59 +00:00
Renovate Bot
cc149c2b4f chore(deps): update dependency @nextcloud/l10n to v3.1.0
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 1m10s
repod / release (push) Has been skipped
2024-05-07 06:49:09 +00:00
Renovate Bot
3af343910e chore(deps): update dependency @nextcloud/stylelint-config to v3.0.1
All checks were successful
repod / xml (push) Successful in 1m17s
repod / php (push) Successful in 42s
repod / nodejs (push) Successful in 1m19s
repod / release (push) Has been skipped
2024-05-07 06:48:59 +00:00
5d20fb5dd3 fix: 🐛 hide episode behing http on https env
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m26s
repod / release (push) Has been skipped
2024-05-06 12:56:26 +00:00
3da2da7e98 style: ⬆️ update deps and prettier
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 46s
repod / nodejs (push) Successful in 1m23s
repod / release (push) Has been skipped
2024-05-06 12:47:47 +00:00
c26599cdf7 Merge pull request 'chore(deps): update dependency @nextcloud/l10n to v3.0.1' (#94) from renovate/nextcloud-l10n-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 1m28s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 1m42s
repod / release (push) Has been skipped
Reviewed-on: #94
2024-05-05 11:09:09 +00:00
Renovate Bot
dae875140d chore(deps): update dependency @nextcloud/l10n to v3.0.1
All checks were successful
repod / xml (push) Successful in 6m6s
repod / php (push) Successful in 4m47s
repod / nodejs (push) Successful in 5m37s
repod / release (push) Has been skipped
2024-05-05 07:07:14 +00:00
601f77d6a3 chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
2024-05-03 18:39:07 +02:00
25bddc5b31 Merge pull request 'chore(deps): update dependency @nextcloud/l10n to v3' (#93) from renovate/nextcloud-l10n-3.x into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m30s
repod / release (push) Has been skipped
Reviewed-on: #93
2024-05-03 16:32:03 +00:00
Renovate Bot
3bd282a0c0 chore(deps): update dependency @nextcloud/l10n to v3
All checks were successful
repod / xml (push) Successful in 25s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m26s
repod / release (push) Has been skipped
2024-05-03 06:44:11 +00:00
bac5a5114f Merge pull request 'chore(deps): update dependency psalm/phar to v5.24.0' (#92) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
Reviewed-on: #92
2024-05-02 07:09:59 +00:00
Renovate Bot
0e16892874 chore(deps): update dependency psalm/phar to v5.24.0
All checks were successful
repod / xml (push) Successful in 1m37s
repod / php (push) Successful in 46s
repod / nodejs (push) Successful in 2m1s
repod / release (push) Has been skipped
2024-05-02 06:32:40 +00:00
9bf5b9c653 Merge pull request 'chore(deps): update dependency @nextcloud/axios to v2.5.0' (#91) from renovate/nextcloud-axios-2.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 48s
repod / nodejs (push) Successful in 1m33s
repod / release (push) Has been skipped
Reviewed-on: #91
2024-05-01 18:19:11 +00:00
Renovate Bot
2b7f43fb5c chore(deps): update dependency @nextcloud/axios to v2.5.0
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m25s
repod / release (push) Has been skipped
2024-05-01 06:43:07 +00:00
b0a0414fd4 refactor: 🎨 add prettier and update deps
All checks were successful
repod / xml (push) Successful in 1m25s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 1m30s
repod / release (push) Has been skipped
2024-04-30 00:48:47 +02:00
cbc9654af8 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v29' (#89) from renovate/nextcloud-ocp-29.x into main
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m35s
repod / release (push) Has been skipped
Reviewed-on: #89
2024-04-25 19:04:31 +00:00
e6621fee04 Merge pull request 'chore(deps): update nextcloud docker tag to v29' (#90) from renovate/nextcloud-29.x into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 16s
repod / php (push) Has been cancelled
Reviewed-on: #90
2024-04-25 19:03:57 +00:00
Renovate Bot
e55dc689f6 chore(deps): update nextcloud docker tag to v29
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 1m12s
repod / nodejs (push) Successful in 1m23s
repod / release (push) Has been skipped
2024-04-25 06:36:22 +00:00
Renovate Bot
dbd6816504 chore(deps): update dependency nextcloud/ocp to v29
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 43s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
2024-04-25 06:36:18 +00:00
7b5330e146 Merge pull request 'chore(deps): update dependency @nextcloud/browserslist-config to v3.0.1' (#88) from renovate/nextcloud-browserslist-config-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 1m21s
repod / php (push) Successful in 1m28s
repod / nodejs (push) Successful in 1m20s
repod / release (push) Has been skipped
Reviewed-on: #88
2024-04-24 23:28:34 +00:00
Renovate Bot
7492baad4e chore(deps): update dependency @nextcloud/browserslist-config to v3.0.1
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m22s
repod / release (push) Has been skipped
2024-04-24 06:57:21 +00:00
af25bc191c Merge pull request 'chore(deps): update dependency @nextcloud/router to v3.0.1' (#87) from renovate/nextcloud-router-3.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 1m28s
repod / release (push) Has been skipped
Reviewed-on: #87
2024-04-23 12:37:42 +00:00
Renovate Bot
b1df2759d3 chore(deps): update dependency @nextcloud/router to v3.0.1
All checks were successful
repod / xml (push) Successful in 1m30s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 1m54s
repod / release (push) Has been skipped
2024-04-23 06:53:26 +00:00
e25b384108 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.1' (#86) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m26s
repod / release (push) Has been skipped
Reviewed-on: #86
2024-04-18 07:18:24 +00:00
Renovate Bot
b11999dab8 chore(deps): update dependency @nextcloud/dialogs to v5.3.1
All checks were successful
repod / xml (push) Successful in 1m24s
repod / php (push) Successful in 33s
repod / nodejs (push) Successful in 1m56s
repod / release (push) Has been skipped
2024-04-18 06:47:24 +00:00
b55fe53304 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.11.2' (#83) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 36s
repod / nodejs (push) Successful in 1m27s
repod / release (push) Has been skipped
Reviewed-on: #83
2024-04-11 07:00:16 +00:00
8a421ebc8f Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.3.0' (#84) from renovate/nextcloud-dialogs-5.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 11s
repod / php (push) Has been cancelled
Reviewed-on: #84
2024-04-11 06:59:49 +00:00
Renovate Bot
742ca212ef chore(deps): update dependency @nextcloud/dialogs to v5.3.0
All checks were successful
repod / xml (push) Successful in 36s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 2m9s
repod / release (push) Has been skipped
2024-04-11 06:45:11 +00:00
Renovate Bot
e96c494421 chore(deps): update dependency @nextcloud/vue to v8.11.2
Some checks failed
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 2m28s
repod / release (push) Has been skipped
repod / xml (push) Failing after 14m1s
2024-04-11 06:44:51 +00:00
e7e03ca42d Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.2.1' (#82) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 2m6s
repod / release (push) Has been skipped
Reviewed-on: #82
2024-04-10 11:37:04 +00:00
Renovate Bot
4a3da45d03 chore(deps): update dependency @nextcloud/dialogs to v5.2.1
All checks were successful
repod / xml (push) Successful in 1m42s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 2m27s
repod / release (push) Has been skipped
2024-04-10 06:40:48 +00:00
ee22ac2726 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v28.0.4' (#79) from renovate/nextcloud-ocp-28.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 36s
repod / nodejs (push) Successful in 1m42s
repod / release (push) Has been skipped
Reviewed-on: #79
2024-03-29 08:13:30 +00:00
Renovate Bot
f389c225c4 chore(deps): update dependency nextcloud/ocp to v28.0.4
All checks were successful
repod / xml (push) Successful in 1m46s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 2m38s
repod / release (push) Has been skipped
2024-03-29 06:35:25 +00:00
5a6427f8a1 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.11.1' (#78) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m26s
repod / release (push) Has been skipped
Reviewed-on: #78
2024-03-22 08:18:13 +00:00
Renovate Bot
8058f328bf chore(deps): update dependency @nextcloud/vue to v8.11.1
All checks were successful
repod / xml (push) Successful in 1m49s
repod / php (push) Successful in 36s
repod / nodejs (push) Successful in 1m58s
repod / release (push) Has been skipped
2024-03-22 06:42:44 +00:00
e5beb6ef73 chore: 🔖 update version
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m52s
repod / release (push) Has been skipped
2024-03-16 19:26:05 +01:00
9178670194 docs: 📝 forgot to credit reported bug (sorry)
All checks were successful
repod / xml (push) Successful in 10s
repod / php (push) Successful in 38s
repod / nodejs (push) Successful in 1m50s
repod / release (push) Has been skipped
2024-03-16 19:19:44 +01:00
e96291d9a2 docs: 📝 update changelog
All checks were successful
repod / xml (push) Successful in 7s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m52s
repod / release (push) Successful in 2m40s
2024-03-16 19:02:42 +01:00
867afbe4df feat: 🔍 add CTA rating to settings
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 1m36s
repod / release (push) Has been skipped
2024-03-16 18:35:31 +01:00
bebd6bf5ed fix: 🔒 app should not require admin access (closes #76)
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 34s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Has been skipped
2024-03-16 17:42:28 +01:00
522c929a82 chore: 🔖 update to nc 29
All checks were successful
repod / xml (push) Successful in 7s
repod / php (push) Successful in 33s
repod / nodejs (push) Successful in 1m38s
repod / release (push) Has been skipped
2024-03-16 17:23:14 +01:00
a2e160afcb chore: ⬆️ update deps
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 13s
repod / php (push) Successful in 31s
repod / nodejs (push) Has been cancelled
2024-03-16 17:22:21 +01:00
8d7c44601c Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.11.0' (#77) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 1m50s
repod / release (push) Has been skipped
Reviewed-on: #77
2024-03-16 16:15:18 +00:00
Renovate Bot
a40b10171a chore(deps): update dependency @nextcloud/vue to v8.11.0
All checks were successful
repod / xml (push) Successful in 1m27s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 2m2s
repod / release (push) Has been skipped
2024-03-16 06:57:06 +00:00
00f33e64b8 chore: ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 1m59s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Has been skipped
2024-03-12 08:57:20 +00:00
90f75b10e6 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.10.0' (#75) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 13s
repod / php (push) Successful in 34s
repod / nodejs (push) Successful in 2m17s
repod / release (push) Has been skipped
Reviewed-on: #75
2024-03-12 08:06:15 +00:00
d3c682988c Merge pull request 'chore(deps): update dependency psalm/phar to v5.23.1' (#74) from renovate/psalm-phar-5.x-lockfile into main
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 17s
repod / php (push) Successful in 40s
repod / nodejs (push) Has been cancelled
Reviewed-on: #74
2024-03-12 08:04:46 +00:00
Renovate Bot
48e205d479 chore(deps): update dependency @nextcloud/vue to v8.10.0
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 1m53s
repod / release (push) Has been skipped
2024-03-12 06:41:22 +00:00
Renovate Bot
78a682acf4 chore(deps): update dependency psalm/phar to v5.23.1
All checks were successful
repod / xml (push) Successful in 1m54s
repod / php (push) Successful in 36s
repod / nodejs (push) Successful in 2m5s
repod / release (push) Has been skipped
2024-03-12 06:40:53 +00:00
0cb93cdb72 Merge pull request 'chore(deps): update dependency psalm/phar to v5.23.0' (#73) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 2m12s
repod / release (push) Has been skipped
Reviewed-on: #73
2024-03-10 10:07:50 +00:00
Renovate Bot
d1b83c8910 chore(deps): update dependency psalm/phar to v5.23.0
All checks were successful
repod / xml (push) Successful in 1m40s
repod / php (push) Successful in 41s
repod / nodejs (push) Successful in 2m13s
repod / release (push) Has been skipped
2024-03-10 06:45:34 +00:00
4e0253b383 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.2.0' (#71) from renovate/nextcloud-dialogs-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m44s
repod / release (push) Has been skipped
Reviewed-on: #71
2024-03-07 14:45:30 +00:00
10af8f87fb Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.9.1' (#72) from renovate/nextcloud-vue-8.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 13s
repod / php (push) Has been cancelled
Reviewed-on: #72
2024-03-07 14:45:10 +00:00
Renovate Bot
ce7be518dc chore(deps): update dependency @nextcloud/vue to v8.9.1
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 34s
repod / nodejs (push) Successful in 2m26s
repod / release (push) Has been skipped
2024-03-07 06:56:57 +00:00
Renovate Bot
1083b723b3 chore(deps): update dependency @nextcloud/dialogs to v5.2.0
All checks were successful
repod / xml (push) Successful in 1m53s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 2m6s
repod / release (push) Has been skipped
2024-03-07 06:56:49 +00:00
227b3eb938 fix(cookie): 🔒 fix warning message on firefox console, make cookie strict
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Has been skipped
2024-03-05 12:08:56 +01:00
3ec978be7e chore: 🌐 update pot (no change on po)
All checks were successful
repod / xml (push) Successful in 49s
repod / php (push) Successful in 30s
repod / nodejs (push) Successful in 1m41s
repod / release (push) Has been skipped
2024-03-05 11:55:32 +01:00
9e3043f0c8 docs: 📝 forgot link to issue
All checks were successful
repod / xml (push) Successful in 54s
repod / php (push) Successful in 28s
repod / nodejs (push) Successful in 1m43s
repod / release (push) Successful in 2m53s
2024-03-05 11:52:12 +01:00
6b30b2b507 docs: 📝 update changelog
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 10s
repod / php (push) Successful in 29s
repod / nodejs (push) Has been cancelled
2024-03-05 11:50:14 +01:00
988069b6a6 fix: 🐛 little last fixes before release
All checks were successful
repod / xml (push) Successful in 9s
repod / php (push) Successful in 32s
repod / nodejs (push) Successful in 1m40s
repod / release (push) Has been skipped
2024-03-05 11:39:16 +01:00
ffe1335ce0 chore(l10n): 🌐 translate new strings to fr
All checks were successful
repod / xml (push) Successful in 11s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 1m35s
repod / release (push) Has been skipped
2024-03-05 11:10:12 +01:00
3dd7bc372b fix: 🔖 forgot nextcloud xml
Some checks are pending
repod / release (push) Waiting to run
repod / xml (push) Successful in 7s
repod / php (push) Successful in 27s
repod / nodejs (push) Successful in 1m49s
2024-03-05 10:58:15 +01:00
a6d2d36f8d fix: 📌 typo in composer
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 33s
repod / php (push) Has been cancelled
2024-03-05 10:56:40 +01:00
185a8c8a7e chore: 🔖 update version number
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 12s
repod / php (push) Successful in 34s
repod / nodejs (push) Has been cancelled
2024-03-05 10:55:27 +01:00
6c406b5361 feat(filters): store filters state in cookie
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 2m29s
repod / release (push) Has been skipped
2024-03-05 10:50:50 +01:00
bdeb46a194 feat: 🚸 add event bus to player for auto update list
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 31s
repod / nodejs (push) Successful in 2m43s
repod / release (push) Has been skipped
2024-03-05 10:37:16 +01:00
2c1b95c6bb fix(player): 🚸 record action when using keyboard media keys
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 3m0s
repod / release (push) Has been skipped
2024-03-05 10:31:08 +01:00
ce0e6e06bc feat: 🏗️ add event bus to manage updating episode list
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 2m44s
repod / release (push) Has been skipped
2024-03-05 10:25:01 +01:00
624c52c231 feat: 🚧 refacto action
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 2m39s
repod / release (push) Has been skipped
2024-03-05 00:14:21 +01:00
e52d20ffbc feat: add actions to episodes view
All checks were successful
repod / xml (push) Successful in 1m42s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 2m51s
repod / release (push) Has been skipped
2024-03-04 16:55:16 +01:00
5a510016a7 fix(NcVue): 🦺 use new NcAppNavigationList
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 33s
repod / nodejs (push) Successful in 1m19s
repod / release (push) Has been skipped
2024-03-01 09:52:49 +01:00
9ccd237f80 chore(deps): ⬆️ update deps
All checks were successful
repod / xml (push) Successful in 12s
repod / php (push) Successful in 28s
repod / nodejs (push) Successful in 1m24s
repod / release (push) Has been skipped
2024-03-01 09:34:25 +01:00
ea62de33d0 feat(settings): 🧑‍💻 add cookie lib
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 35s
repod / nodejs (push) Successful in 1m22s
repod / release (push) Has been skipped
2024-03-01 09:28:58 +01:00
746d39c775 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.8.1' (#68) from renovate/nextcloud-vue-8.x-lockfile into main
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 9s
repod / php (push) Successful in 31s
repod / nodejs (push) Has been cancelled
Reviewed-on: #68
2024-03-01 08:26:49 +00:00
972b4ea207 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v28.0.3' (#67) from renovate/nextcloud-ocp-28.x-lockfile into main
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
Reviewed-on: #67
2024-03-01 08:26:04 +00:00
Renovate Bot
9a00971ce1 chore(deps): update dependency @nextcloud/vue to v8.8.1
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 29s
repod / nodejs (push) Successful in 2m1s
repod / release (push) Has been skipped
2024-03-01 06:59:02 +00:00
Renovate Bot
109d1087a4 chore(deps): update dependency nextcloud/ocp to v28.0.3
All checks were successful
repod / xml (push) Successful in 1m50s
repod / php (push) Successful in 37s
repod / nodejs (push) Successful in 2m11s
repod / release (push) Has been skipped
2024-03-01 06:57:56 +00:00
209fffc305 chore: ⬆️ update version and deps
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 40s
repod / nodejs (push) Successful in 2m59s
repod / release (push) Has been skipped
2024-02-25 18:42:36 +01:00
9e216ca96f Merge pull request 'chore(deps): update dependency psalm/phar to v5.22.2' (#65) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 8s
repod / php (push) Successful in 33s
repod / nodejs (push) Successful in 1m41s
repod / release (push) Has been skipped
Reviewed-on: #65
2024-02-23 09:31:30 +00:00
11e0abec67 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.1.2' (#64) from renovate/nextcloud-dialogs-5.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 12s
repod / php (push) Has been cancelled
Reviewed-on: #64
2024-02-23 09:31:13 +00:00
Renovate Bot
57bd010ed0 chore(deps): update dependency psalm/phar to v5.22.2
All checks were successful
repod / xml (push) Successful in 43s
repod / php (push) Successful in 33s
repod / nodejs (push) Successful in 1m40s
repod / release (push) Has been skipped
2024-02-23 06:49:00 +00:00
Renovate Bot
8f68aa1485 chore(deps): update dependency @nextcloud/dialogs to v5.1.2
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 47s
repod / nodejs (push) Successful in 1m39s
repod / release (push) Has been skipped
2024-02-23 06:48:47 +00:00
26aeefa70d Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.7.1' (#63) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 2m37s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 3m40s
repod / release (push) Has been skipped
Reviewed-on: #63
2024-02-22 11:00:47 +00:00
Renovate Bot
c31074457e chore(deps): update dependency @nextcloud/vue to v8.7.1
All checks were successful
repod / xml (push) Successful in 58s
repod / php (push) Successful in 1m27s
repod / nodejs (push) Successful in 4m50s
repod / release (push) Has been skipped
2024-02-22 06:40:02 +00:00
243ae7a7ef 📝 doc: Update changelog
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Successful in 3m14s
2024-02-20 22:08:15 +01:00
9a411358ca 🧑‍💻 feat: Modify some endpoints to match gPodder.net ones
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m25s
repod / nodejs (push) Successful in 2m12s
repod / release (push) Has been skipped
2024-02-20 21:31:38 +01:00
33fee28c02 ⬆️ chore: update @nextcloud/vue to 8.7.0 2024-02-20 21:30:32 +01:00
21760276cd Merge pull request 'chore(deps): update dependency psalm/phar to v5.22.1' (#61) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Has been skipped
Reviewed-on: #61
2024-02-16 08:17:25 +00:00
Renovate Bot
7c5b542125 chore(deps): update dependency psalm/phar to v5.22.1
All checks were successful
repod / xml (push) Successful in 32s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m58s
repod / release (push) Has been skipped
2024-02-16 06:33:23 +00:00
4909870d30 Merge pull request 'chore(deps): update dependency psalm/phar to v5.22.0' (#60) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 2m41s
repod / release (push) Has been skipped
Reviewed-on: #60
2024-02-14 09:33:24 +00:00
Renovate Bot
0d72ef82a2 chore(deps): update dependency psalm/phar to v5.22.0
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 47s
repod / nodejs (push) Successful in 2m41s
repod / release (push) Has been skipped
2024-02-14 06:53:12 +00:00
d215081086 doc: update changelog
All checks were successful
repod / xml (push) Successful in 40s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 2m55s
repod / release (push) Successful in 3m46s
2024-02-11 12:44:22 +01:00
6e925cd607 fix: fyyd API sometime send empty feed
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
2024-02-11 12:43:13 +01:00
add84b935c chore: update versions
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 2m19s
repod / release (push) Successful in 2m58s
2024-02-07 22:36:39 +01:00
c6f06a9f29 Revert "feat: Proxy episodes when they are behind an unsecure http server"
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 2m17s
repod / release (push) Has been skipped
This reverts commit 2398c9749d.
2024-02-07 22:29:47 +01:00
a16556c0eb fix: Undefined index if podcast definitly don't have any image
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m9s
repod / release (push) Has been skipped
2024-02-07 18:43:47 +01:00
6ce5c0c199 refacto: remove old debug csp for vue devtools
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 1m21s
repod / nodejs (push) Successful in 1m58s
repod / release (push) Has been skipped
2024-02-07 18:34:14 +01:00
c413e0cb1a doc: update vue on changelog
All checks were successful
repod / xml (push) Successful in 34s
repod / php (push) Successful in 48s
repod / nodejs (push) Successful in 1m46s
repod / release (push) Successful in 2m35s
2024-02-07 18:23:57 +01:00
2398c9749d feat: Proxy episodes when they are behind an unsecure http server
Some checks failed
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Has been cancelled
2024-02-07 18:23:00 +01:00
ef1fa64047 fix: do not exclude vcs for tar release
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Has been skipped
2024-02-05 23:48:10 +01:00
302e8c781b fix: Cannot Open Any Podcasts in Repod if cache missing or missconfigured (close #58)
All checks were successful
repod / xml (push) Successful in 58s
repod / php (push) Successful in 5m41s
repod / nodejs (push) Successful in 4m50s
repod / release (push) Successful in 10m29s
2024-02-04 09:40:21 +01:00
2c4a6e3e56 doc: misstype the LICENSES folder
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m50s
repod / release (push) Has been skipped
2024-02-03 10:34:15 +01:00
5f80d3cb3e doc: missing credits
All checks were successful
repod / xml (push) Successful in 48s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Successful in 3m19s
2024-02-03 10:21:08 +01:00
ddcca82979 fix: Cannot use Nextcloud Search with app enabled (close #57)
Some checks failed
repod / xml (push) Has been cancelled
repod / php (push) Has been cancelled
repod / release (push) Has been cancelled
repod / nodejs (push) Has been cancelled
2024-02-03 10:18:37 +01:00
b2ff2733a0 Merge pull request 'chore(deps): update skjnldsv/read-package-engines-version-actions action to v3' (#56) from renovate/skjnldsv-read-package-engines-version-actions-3.x into main
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 2m17s
repod / release (push) Has been skipped
Reviewed-on: #56
2024-02-02 10:52:13 +00:00
09a19505d4 Merge pull request 'chore(deps): update dependency nextcloud/ocp to v28.0.2' (#55) from renovate/nextcloud-ocp-28.x-lockfile into main
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 23s
repod / php (push) Has been cancelled
Reviewed-on: #55
2024-02-02 10:51:02 +00:00
Renovate Bot
604c9ed3f0 chore(deps): update skjnldsv/read-package-engines-version-actions action to v3
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-02-02 06:59:01 +00:00
Renovate Bot
d1dd708574 chore(deps): update dependency nextcloud/ocp to v28.0.2
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 1m44s
repod / release (push) Has been skipped
2024-02-02 06:58:57 +00:00
d9df7de1a7 fix: missing niño
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Successful in 2m58s
2024-02-01 22:31:53 +01:00
d808ac0609 fix: episode listing crashing if an invalid publication date is present in the RSS
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 39s
repod / php (push) Has been cancelled
2024-02-01 22:30:20 +01:00
abf73c0ce9 doc: update changelog
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Successful in 2m50s
2024-02-01 16:02:32 +01:00
1dba881a0e chore: update versions
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 2m7s
repod / release (push) Has been skipped
2024-02-01 15:00:56 +01:00
3ff5d636d5 Merge branch 'main' of ssh://patema.crystalyx.net:2222/Xefir/RePod
All checks were successful
repod / xml (push) Successful in 1m54s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Has been skipped
2024-02-01 14:19:57 +01:00
6b9ee6af5d Fix height alignment without the ncprogressbar 2024-02-01 14:19:43 +01:00
a627ebbf54 Merge pull request 'chore(deps): update dependency psalm/phar to v5.21.1' (#54) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 2m38s
repod / release (push) Has been skipped
Reviewed-on: #54
2024-02-01 09:14:52 +00:00
Renovate Bot
02171b80c7 chore(deps): update dependency psalm/phar to v5.21.1
All checks were successful
repod / xml (push) Successful in 25s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m54s
repod / release (push) Has been skipped
2024-02-01 06:46:42 +00:00
d5d91b3788 Merge pull request 'chore(deps): update dependency psalm/phar to v5.21.0' (#53) from renovate/psalm-phar-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 1m48s
repod / release (push) Has been skipped
Reviewed-on: #53
2024-01-31 07:48:53 +00:00
Renovate Bot
dcfdfe52ea chore(deps): update dependency psalm/phar to v5.21.0
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 45s
repod / nodejs (push) Successful in 1m30s
repod / release (push) Has been skipped
2024-01-31 06:34:11 +00:00
31064c84a3 doc: add licences in the proper folder
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m10s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Has been skipped
2024-01-31 00:14:00 +01:00
4687b5e00c doc: fix the old url
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m52s
repod / release (push) Has been skipped
2024-01-30 23:09:43 +01:00
bc42b08a25 doc: Use my real name, i don't care anymore
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 1m56s
repod / release (push) Has been skipped
2024-01-30 23:01:18 +01:00
b04d516b05 doc: update changelog
All checks were successful
repod / xml (push) Successful in 32s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Successful in 2m38s
2024-01-30 18:30:54 +01:00
f00d3b4b25 fix: filter setting placement
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Has been skipped
2024-01-30 18:26:27 +01:00
6df4813944 chore: update @nextcloud/vue
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Has been skipped
2024-01-30 18:11:50 +01:00
9d7d08f0dc fix: add a easier-to-see indicator at playhead (close #52)
All checks were successful
repod / xml (push) Successful in 24s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m24s
repod / release (push) Has been skipped
2024-01-30 17:34:20 +01:00
d4c2c4e49d fix: no need for the hasEnded condition here
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 2m7s
repod / release (push) Has been skipped
2024-01-30 16:05:58 +01:00
9b2d245e80 doc: update changelog
All checks were successful
repod / xml (push) Successful in 36s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Successful in 3m1s
2024-01-30 15:13:09 +01:00
1c261fbe4b fix: if the rss podcast server does not respond, do not crash when exporting
All checks were successful
repod / xml (push) Successful in 32s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Has been skipped
2024-01-30 14:38:26 +01:00
9fa69dfbb8 chore: update lock
All checks were successful
repod / xml (push) Successful in 19s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 2m0s
repod / release (push) Has been skipped
2024-01-30 10:57:41 +01:00
ac4161a18a feat: filtering options for each podcast section (close #50)
All checks were successful
repod / xml (push) Successful in 32s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m36s
repod / release (push) Has been skipped
2024-01-29 23:33:05 +01:00
99fa123640 refacto: rework Settings into several components
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 2m12s
repod / release (push) Has been skipped
2024-01-29 19:30:12 +01:00
87315b1221 feat: better display the reading status for episodes (in episodes list / podcast section) (close #51)
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m56s
repod / release (push) Has been skipped
2024-01-29 16:06:54 +01:00
b63e1175a0 feat: displaying episode publication as "dd mmm yyyy" instead of xyz ago (close #48)
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 2m11s
repod / release (push) Has been skipped
2024-01-29 15:47:50 +01:00
896fbf3e75 chore: update version and remove moment 2024-01-29 15:47:14 +01:00
10269aff99 Merge pull request 'chore(deps): update dependency vue-material-design-icons to v5.3.0' (#47) from renovate/vue-material-design-icons-5.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 39s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 2m35s
repod / release (push) Has been skipped
Reviewed-on: #47
2024-01-29 12:37:01 +00:00
Renovate Bot
7faead8d63 chore(deps): update dependency vue-material-design-icons to v5.3.0
All checks were successful
repod / xml (push) Successful in 2m19s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Has been skipped
2024-01-29 06:48:31 +00:00
e37c16e2df chore: update versions
All checks were successful
repod / xml (push) Successful in 29s
repod / php (push) Successful in 42s
repod / nodejs (push) Successful in 1m54s
repod / release (push) Has been skipped
2024-01-27 07:51:00 +01:00
78560b6239 Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.5.1' (#46) from renovate/nextcloud-vue-8.x-lockfile into main
Some checks are pending
repod / xml (push) Waiting to run
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
Reviewed-on: #46
2024-01-27 06:46:41 +00:00
70a8b83591 Merge pull request 'chore(deps): update dependency @nextcloud/dialogs to v5.1.1' (#45) from renovate/nextcloud-dialogs-5.x-lockfile into main
Some checks are pending
repod / xml (push) Waiting to run
repod / php (push) Waiting to run
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
Reviewed-on: #45
2024-01-27 06:45:40 +00:00
Renovate Bot
e43f7fa1e3 chore(deps): update dependency @nextcloud/vue to v8.5.1
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 44s
repod / nodejs (push) Successful in 1m46s
repod / release (push) Has been skipped
2024-01-27 06:41:10 +00:00
Renovate Bot
7d61dec632 chore(deps): update dependency @nextcloud/dialogs to v5.1.1
All checks were successful
repod / xml (push) Successful in 1m49s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Has been skipped
2024-01-27 06:41:00 +00:00
3b0f5bc852 Merge pull request 'chore(deps): update dependency @nextcloud/router to v2.2.1' (#44) from renovate/nextcloud-router-2.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 2m13s
repod / release (push) Has been skipped
Reviewed-on: #44
2024-01-25 11:41:20 +00:00
Renovate Bot
62b8829ee5 chore(deps): update dependency @nextcloud/router to v2.2.1
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m8s
repod / release (push) Has been skipped
2024-01-25 06:43:52 +00:00
4093b4922c doc: update changelog
All checks were successful
repod / xml (push) Successful in 2m11s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 1m48s
repod / release (push) Successful in 2m37s
2024-01-24 12:14:00 +01:00
1a3c27eed1 chore: update versions
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 21s
repod / php (push) Successful in 54s
repod / nodejs (push) Has been cancelled
2024-01-24 12:11:06 +01:00
6e2e7d7c59 chore: update deps
Some checks failed
repod / release (push) Waiting to run
repod / xml (push) Successful in 26s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Has been cancelled
2024-01-24 12:08:39 +01:00
0fbad1570f Merge pull request 'chore(deps): update dependency @nextcloud/vue to v8.5.0' (#43) from renovate/nextcloud-vue-8.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 39s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 3m3s
repod / release (push) Has been skipped
Reviewed-on: #43
2024-01-24 09:17:25 +00:00
Renovate Bot
7deb50a9e5 chore(deps): update dependency @nextcloud/vue to v8.5.0
All checks were successful
repod / xml (push) Successful in 2m0s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 1m55s
repod / release (push) Has been skipped
2024-01-24 06:49:49 +00:00
df7c9e8e25 Merge pull request 'chore(deps): update dependency @nextcloud/stylelint-config to v2.4.0' (#42) from renovate/nextcloud-stylelint-config-2.x-lockfile into main
All checks were successful
repod / xml (push) Successful in 40s
repod / php (push) Successful in 1m14s
repod / nodejs (push) Successful in 2m47s
repod / release (push) Has been skipped
Reviewed-on: #42
2024-01-23 10:34:44 +00:00
Renovate Bot
34cdb498eb chore(deps): update dependency @nextcloud/stylelint-config to v2.4.0
All checks were successful
repod / xml (push) Successful in 2m23s
repod / php (push) Successful in 1m16s
repod / nodejs (push) Successful in 2m27s
repod / release (push) Has been skipped
2024-01-23 06:33:44 +00:00
7a2d924e6b fix: typo in changelog
All checks were successful
repod / xml (push) Successful in 29s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 1m54s
repod / release (push) Successful in 3m1s
2024-01-21 12:34:09 +01:00
5c2e1a5dd6 doc: update changelog
Some checks failed
repod / nodejs (push) Waiting to run
repod / release (push) Waiting to run
repod / xml (push) Successful in 16s
repod / php (push) Has been cancelled
2024-01-21 12:33:18 +01:00
7843e930d5 chore: update versions
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Has been skipped
2024-01-21 12:27:08 +01:00
22ef756a2d feat: Add a link to copy the feed on the banner (close #41)
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-01-21 12:16:59 +01:00
ff23be4f91 feat: change rate to .1 steps and fix floating (close #40)
All checks were successful
repod / xml (push) Successful in 2m40s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Has been skipped
2024-01-21 11:33:32 +01:00
9f9fdf4cf0 chore: update version
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 48s
repod / nodejs (push) Successful in 2m0s
repod / release (push) Successful in 2m55s
2024-01-20 10:20:49 +01:00
387100e928 doc: update changelog
Some checks failed
repod / xml (push) Has been cancelled
repod / php (push) Has been cancelled
repod / release (push) Has been cancelled
repod / nodejs (push) Has been cancelled
2024-01-20 10:18:41 +01:00
ccb1c72ad3 fix: ended still didn't show up well
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Has been skipped
2024-01-20 09:58:08 +01:00
2934935886 doc: update versions and changelog
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m56s
repod / release (push) Successful in 2m40s
2024-01-19 22:12:57 +01:00
a5289651bd fix: if DELETED on GPodder, it show not ended on RePod
All checks were successful
repod / xml (push) Successful in 1m54s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 2m33s
repod / release (push) Has been skipped
2024-01-19 22:06:35 +01:00
4da4e6a3a1 style: add padding to make easier to scroll on tops on desktop
All checks were successful
repod / xml (push) Successful in 2m4s
repod / php (push) Successful in 1m2s
repod / nodejs (push) Successful in 2m56s
repod / release (push) Has been skipped
2024-01-19 11:45:10 +01:00
a480d70faf doc: update README
All checks were successful
repod / xml (push) Successful in 39s
repod / php (push) Successful in 53s
repod / nodejs (push) Successful in 2m8s
repod / release (push) Successful in 2m50s
2024-01-18 17:58:51 +01:00
e2b4cb546f chore: update changelog
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m6s
repod / nodejs (push) Successful in 2m20s
repod / release (push) Has been skipped
2024-01-18 17:54:26 +01:00
676a91f69d chore: update versions
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m8s
repod / release (push) Has been skipped
2024-01-18 17:42:29 +01:00
b40f480975 fix: psalm update 2024-01-18 17:42:20 +01:00
46cd766cac fix: translations updates
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 2m9s
repod / release (push) Has been skipped
2024-01-18 17:24:06 +01:00
751c3c1e01 feat: import subscriptions
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m11s
repod / release (push) Has been skipped
2024-01-18 17:06:26 +01:00
c28abc7564 feat: add export opml
All checks were successful
repod / xml (push) Successful in 28s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 1m58s
repod / release (push) Has been skipped
2024-01-18 13:28:06 +01:00
2ed16a316e style: align volume to the right
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m59s
repod / release (push) Successful in 2m30s
2024-01-18 11:55:12 +01:00
3b460f620b chore: update version
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 2m16s
repod / release (push) Has been skipped
2024-01-18 11:49:13 +01:00
c951a93b8c feat: add unified search integration
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 2m8s
repod / release (push) Has been skipped
2024-01-18 11:43:58 +01:00
d6a9eb0c31 style: center error of gpodder
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 2m11s
repod / release (push) Has been skipped
2024-01-18 11:27:47 +01:00
409bd429eb fix: add sqlite3 to docker dev
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 1m13s
repod / nodejs (push) Successful in 1m59s
repod / release (push) Has been skipped
2024-01-18 11:19:09 +01:00
8045dadf9f fix: install gpodder directly on docker without downloading first
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 1m56s
repod / release (push) Has been skipped
2024-01-18 11:06:51 +01:00
b69516031a fix: perf issue with modal
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 54s
repod / nodejs (push) Successful in 1m51s
repod / release (push) Has been skipped
2024-01-18 10:12:55 +01:00
f26c7fcc70 chore: update version (oups)
All checks were successful
repod / xml (push) Successful in 39s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 2m4s
repod / release (push) Successful in 2m51s
2024-01-17 23:56:53 +01:00
c63176db9b chore: update versions and changelog
All checks were successful
repod / xml (push) Successful in 34s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m15s
repod / release (push) Successful in 2m57s
2024-01-17 23:45:43 +01:00
606a769246 style: use pointer class everywhere
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-01-17 23:16:59 +01:00
2047470555 fix: better background for fixing player text color #38 2024-01-17 23:16:46 +01:00
a90368fa2e style: little css ajustments
All checks were successful
repod / xml (push) Successful in 17s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m22s
repod / release (push) Has been skipped
2024-01-17 22:58:17 +01:00
37d264d717 refacto: simplify tops wordings
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 1m1s
repod / nodejs (push) Successful in 2m22s
repod / release (push) Has been skipped
2024-01-17 22:38:47 +01:00
b784040b69 feat: add modal to episode bar
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m40s
repod / release (push) Has been skipped
2024-01-17 22:18:32 +01:00
5f0b43c26f style: add a size to the playback speed icons
All checks were successful
repod / xml (push) Successful in 21s
repod / php (push) Successful in 1m5s
repod / nodejs (push) Successful in 2m35s
repod / release (push) Has been skipped
2024-01-17 20:16:15 +01:00
87294d1881 style: add pointer to + and - button on playback speed
All checks were successful
repod / xml (push) Successful in 2m36s
repod / php (push) Successful in 1m4s
repod / nodejs (push) Successful in 3m5s
repod / release (push) Has been skipped
2024-01-17 17:45:24 +01:00
c101588eaf style: add icon to the playback speed setting
All checks were successful
repod / xml (push) Successful in 35s
repod / php (push) Successful in 1m8s
repod / nodejs (push) Successful in 2m17s
repod / release (push) Has been skipped
2024-01-17 17:40:26 +01:00
ce5408395d chore: update versions and changelog
All checks were successful
repod / xml (push) Successful in 30s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m53s
repod / release (push) Successful in 2m41s
2024-01-16 23:15:23 +01:00
f4fc4b52e3 fix: started state and decodeUrl 2024-01-16 23:13:07 +01:00
9dc09c2185 fix: episode could show not ended because of started at 0
All checks were successful
repod / xml (push) Successful in 18s
repod / php (push) Successful in 57s
repod / nodejs (push) Successful in 2m16s
repod / release (push) Has been skipped
2024-01-16 22:46:27 +01:00
1d65481be8 fix: handle started action
All checks were successful
repod / xml (push) Successful in 23s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m20s
repod / release (push) Has been skipped
2024-01-16 22:36:01 +01:00
9ebd96cec1 feat: add playback speed setting (close #39)
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 1m7s
repod / nodejs (push) Successful in 2m11s
repod / release (push) Has been skipped
2024-01-16 22:12:07 +01:00
31bf193543 fix: add same image background style to player bar to address light mode text issue (closes #38)
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 55s
repod / nodejs (push) Successful in 2m6s
repod / release (push) Has been skipped
2024-01-16 21:15:12 +01:00
2d6f2cb5e7 fix: duration wrongly displayed
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 52s
repod / nodejs (push) Successful in 1m47s
repod / release (push) Has been skipped
2024-01-16 19:46:02 +01:00
c399a20de3 chore: need to include CHANGELOG.md to see modifications on the appstore
All checks were successful
repod / xml (push) Successful in 1m53s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 1m53s
repod / release (push) Has been skipped
2024-01-16 19:31:42 +01:00
e29f735ca4 ci: no need quotes here
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Has been skipped
2024-01-16 15:38:46 +01:00
7137d2cd34 ci: test
All checks were successful
repod / xml (push) Successful in 31s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 1m57s
repod / release (push) Successful in 2m37s
2024-01-16 15:28:48 +01:00
46beb6ebfa ci: ooops
Some checks failed
repod / xml (push) Successful in 30s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 1m59s
repod / release (push) Failing after 2m37s
2024-01-16 15:18:37 +01:00
01ecab3cb5 ci: signature must be base64
Some checks failed
repod / xml (push) Successful in 15s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 2m1s
repod / release (push) Failing after 2m39s
2024-01-16 15:07:49 +01:00
28ff127a86 Update version
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 1m0s
repod / nodejs (push) Successful in 2m9s
repod / release (push) Has been skipped
2024-01-16 14:57:56 +01:00
5ef0a9612a ci: retry automation
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m1s
repod / release (push) Has been skipped
2024-01-16 14:51:06 +01:00
25c6c515e0 feat: sort subscriptions
All checks were successful
repod / xml (push) Successful in 15s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 2m3s
repod / release (push) Has been skipped
2024-01-16 14:36:51 +01:00
61f865da52 fix: xsd error on psalm
All checks were successful
repod / xml (push) Successful in 14s
repod / php (push) Successful in 51s
repod / nodejs (push) Successful in 1m49s
repod / release (push) Has been skipped
2024-01-16 14:28:41 +01:00
540c5df7e5 refacto: remove atomlink that leads to weird bugs
All checks were successful
repod / xml (push) Successful in 22s
repod / php (push) Successful in 56s
repod / nodejs (push) Successful in 2m5s
repod / release (push) Has been skipped
2024-01-16 14:21:35 +01:00
c48432c0b5 ci: remote automate publishing
All checks were successful
repod / xml (push) Successful in 16s
repod / php (push) Successful in 50s
repod / nodejs (push) Successful in 2m7s
repod / release (push) Has been skipped
2024-01-16 11:14:52 +01:00
114 changed files with 11779 additions and 12859 deletions

View File

@ -1,8 +1,13 @@
*.iml
.idea
/.php-cs-fixer.cache
/.php_cs.cache
/build/
/.idea/
/*.iml
/vendor/
js/
node_modules/
/vendor-bin/*/vendor/
/.php-cs-fixer.cache
/tests/.phpunit.cache
/node_modules/
/js/
/build/

View File

@ -1,9 +0,0 @@
*.iml
.idea
/.php-cs-fixer.cache
/.php_cs.cache
/build/
/vendor/
js/
node_modules/
l10n/

15
.eslintrc.cjs Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
extends: [
'@nextcloud',
'@vue/eslint-config-typescript/recommended',
'plugin:pinia/recommended',
'plugin:prettier/recommended',
],
parser: 'vue-eslint-parser',
rules: {
'jsdoc/require-jsdoc': 'off',
'vue/first-attribute-linebreak': 'off',
'sort-imports': 'error',
'vue/attributes-order': ['error', { alphabetical: true }],
},
}

View File

@ -1,9 +0,0 @@
module.exports = {
extends: [
'@nextcloud',
],
rules: {
'sort-imports': 'error',
'vue/attributes-order': ['error', { alphabetical: true }],
},
}

1
.gitattributes vendored
View File

@ -1 +0,0 @@
/js/* binary

View File

@ -14,7 +14,7 @@ jobs:
php:
runs-on: ubuntu-latest
container: nextcloud:28
container: nextcloud:29
steps:
- run: apt-get update
- run: apt-get install -y git nodejs
@ -24,17 +24,17 @@ jobs:
- run: composer install
- run: composer run lint
- run: composer run cs:check
- run: composer run psalm:check
- run: composer run psalm
nodejs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: skjnldsv/read-package-engines-version-actions@v2
- uses: skjnldsv/read-package-engines-version-actions@v3
id: versions
with:
fallbackNode: '^20.0.0'
fallbackNpm: '^9.0.0'
fallbackNode: '^20'
fallbackNpm: '^10'
- uses: actions/setup-node@v4
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}
@ -47,38 +47,41 @@ jobs:
release:
if: gitea.ref_type == 'tag'
runs-on: ubuntu-latest
container: nextcloud:28
container: nextcloud:29
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@v2
- uses: skjnldsv/read-package-engines-version-actions@v3
id: versions
with:
fallbackNode: '^20.0.0'
fallbackNpm: '^9.0.0'
fallbackNode: '^20'
fallbackNpm: '^10'
- uses: actions/setup-node@v4
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}
- run: npm i -g npm@${{ steps.versions.outputs.npmVersion }}
- id: dist
name: dist
run: |
make dist
echo "$KEYFILE" > /tmp/repod.key
echo "SIGNATURE=$(openssl dgst -sha512 -sign /tmp/repod.key build/artifacts/repod.tar.gz | openssl base64)" >> $GITHUB_OUTPUT
env:
KEYFILE: ${{ secrets.KEYFILE }}
- run: make dist
- uses: akkuman/gitea-release-action@v1
with:
files: |
build/artifacts/repod.tar.gz
- uses: FKLC/sign-files-action@v1.0.0
with:
privateKey: ${{ secrets.PRIVATEKEY }}
algorithm: RSA-SHA512
extension: .sig
outputFolder: build/artifacts
files: |
build/artifacts/repod.tar.gz
- id: sign
run: echo "SIGNATURE=$(cat build/artifacts/repod.tar.gz.sig | openssl base64 -A)" >> $GITHUB_OUTPUT
- uses: actionsflow/axios@v1
with:
url: https://apps.nextcloud.com/api/v1/apps/releases
method: POST
accept: 200,201
headers: '{ "Authorization": "Token <<<${{ secrets.TOKEN }}>>>" }'
data: '{ "download": "https://git.crystalyx.net/Xefir/repod/releases/download/<<<${{ gitea.ref_name }}>>>/repod.tar.gz", "signature": "<<<${{ steps.dist.outputs.SIGNATURE }}>>>" }'
data: '{ "download": "https://git.crystalyx.net/Xefir/repod/releases/download/<<<${{ gitea.ref_name }}>>>/repod.tar.gz", "signature": "<<<${{ steps.sign.outputs.SIGNATURE }}>>>" }'

19
.gitignore vendored
View File

@ -1,8 +1,13 @@
*.iml
.idea
/.php-cs-fixer.cache
/.php_cs.cache
/build/
/.idea/
/*.iml
/vendor/
js/
node_modules/
/vendor-bin/*/vendor/
/.php-cs-fixer.cache
/tests/.phpunit.cache
/node_modules/
/js/
/build/

View File

@ -1,8 +1,13 @@
.idea/
*.iml
.idea
/.php-cs-fixer.cache
/.php_cs.cache
build/
vendor/
js/
vendor-bin/*/vendor/
.php-cs-fixer.cache
tests/.phpunit.cache
node_modules/
js/
build/

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
20

View File

@ -23,10 +23,11 @@ class MyConfig extends Config
$config = new MyConfig();
$config
->getFinder()
->ignoreVCSIgnored(true)
->notPath('build')
->notPath('l10n')
->notPath('node_modules')
->notPath('src')
->notPath('vendor')
->in(__DIR__);
return $config;

View File

@ -1,3 +1,287 @@
## 3.2.0 - Typing fast - 2024-09-15
### Added
- 📝 Add Cardo to list of compatible clients
[#176](https://github.com/thrillfall/nextcloud-gpodder/pull/176) reported by @n0vella
### Changed
- 🧑‍💻 Switch entiere project to TypeScript
### Fixed
- 💄 Missing icon on home when aren't any favorites
- 💄 Tweaks spacing in several spaces on Home and banners
- 💩 Leverage the available space between the episode title and the play button (but hacky way for now)
[#59](https://git.crystalyx.net/Xefir/repod/issues/59#issuecomment-6246) reported by @W_LL_M
## 3.1.0 - Above the stars - 2024-09-02
### Added
- ⭐ You can now add favorites subscriptions !
It will show's up on the homepage instead of the recommendations witch appear only when you add a new subscription.
[#59](https://git.crystalyx.net/Xefir/repod/issues/59) suggested by @W_LL_M, @Jaunty and @Satalink
### Changed
- 💥 Use html5 routing instead of hashes. All the URLs has changed removing the `#/` part.
### Fixed
- 🐛 Regression on 3.0 that prevent seeking player to episode last listened position
[#136](https://git.crystalyx.net/Xefir/repod/issues/136) reported by @randomuser1967
- ⚡ Improve the detection off mis-installed or mis-enabled gpodder app
## 3.0.0 - What a vue - 2024-08-17
### Added
- 🌐 Add german translation
Thanks to @OiledAmoeba [#120](https://git.crystalyx.net/Xefir/repod/issues/120)
### Changed
- 🎉 Migrate to Vue 3
- 🔖 Support Nextcloud 30
- 🏗️ Switch from Vuex to Pinia
### Fixed
- 💄 Use iTunes image first for episode if available
- 💄 Displaying styles and proper HTML on episode's modal descriptions
### Removed
- 🗑️ Temporary replacing @nextcloud/dialogs to toastyjs
## 2.3.3 - The Cake is a Lie - 2024-06-14
### Changed
- ⬆️ Update @nextcloud/dialogs to 5.3.2
### Fixed
- 🐛 App crashed when no cache system available
[#107](https://git.crystalyx.net/Xefir/repod/issues/107) reported by @skvaller and @PhilTraere
## 2.3.2 - Young Youth - 2024-05-31
### Fixed
- 🐛 New subscribe button on search not disapearing if subscribed
- ♿ Missing accessibility label on this button as well
## 2.3.1 - Powerwash the Universe - 2024-05-29
### Changed
- ⚡ Reduce app size by not shipping sourcemap
## 2.3.0 - Star Align - 2024-05-29
### Added
- Ability to subscribe to podcast from search list
[#105](https://git.crystalyx.net/Xefir/repod/issues/105) suggested by @crystalyz
### Changed
- 🔖 Full support for Nextcloud 29
- ⬆️ Update @nextcloud/vue to 8.12.0
- 📄 Use only AGPL licence
- ♻️ Refacto based on the new app template from Nextcloud devs
### Removed
- 💀 Drop support for Nextcloud 26
- ⚰️ Drop support for PHP 8.0
- 🌐 Removed babel
## 2.2.1 - Shami was here - 2024-05-18
### Removed
- ♻️ Rollback: Hide unreadable episodes because of insecure sources
## 2.2.0 - Moving in and out - 2024-05-18
### Added
- 🚨 Linting the code with ESLint
- 🎨 Prettierify the code
### Changed
- ⬆️ Update all dependancies
### Fixed
- 🔓 Hide unreadable episodes because of insecure sources
## 2.1.0 - Pocket Gundams - 2024-03-16
### Added
- 🔍 Add CTA for rating the app on the store
### Changed
- ⬆️ Update @nextcloud/dialogs to 5.2.0
- ⬆️ Update @nextcloud/vue to 8.11.0
- 🔖 Set compatibility with Nextcloud 29
### Fixed
- 🔒 App wasn't working for non admin users
[#76](https://git.crystalyx.net/Xefir/repod/issues/76) reported by @devasservice
## 2.0.0 - Taking Actions - 2024-03-05
### Added
- 🍪 Saving filters preference
[#66](https://git.crystalyx.net/Xefir/repod/issues/66) suggested by @jeef
- 📋 Add several options on each episode :
- Mark as read
- Open the webpage of the episode
- Download the episode
- ↪️ Any actions will be reflected on the episode's list
### Changed
- ⬆️ Update @nextcloud/vue to 8.8.1
### Fixed
- ❤️‍🔥 Better handling ended episodes
## 1.5.9 - Just According to Keikaku - 2024-02-21
### Changed
- 🧑‍💻 Change some endpoints to match gPodder.net "specifications"
- ⬆️ Update @nextcloud/vue to 8.7.0
## 1.5.8 - Goblet of Eonothem - 2024-02-11
### Fixed
- Fyyd API sometime send empty feeds, ignoring them
## 1.5.7 - 2024-02-08
### Removed
- Proxy episodes when they are behind an unsecure http server
## 1.5.6 - 2024-02-07
### Added
- Proxy episodes when they are behind an unsecure http server
### Changed
- Update @nextcloud/vue to v8.6.2
## 1.5.5 - Hide and seek - 2024-02-04
### Fixed
- Can't open podcast details if cache missing or misconfigured
[#58](https://git.crystalyx.net/Xefir/repod/issues/58) reported by @raxventus
## 1.5.4 - In search of the truth - 2024-02-03
### Fixed
- Nextcloud search engine didn't work on Nextcloud 26 and 27
[#57](https://git.crystalyx.net/Xefir/repod/issues/57) reported by @JonOfUs
## 1.5.3 - The date where it all ends - 2024-02-01
### Changed
- Update @nextcloud/vue to v8.6.1
### Fixed
- Fix episode listing crashing if an invalid publication date is present in the RSS
## 1.5.2 - A little to the top - 2024-02-01
### Changed
- Update @nextcloud/router to v3.0.0
### Fixed
- Fix player alignment off by a couple of pixels
## 1.5.1 - Play on the PlayHead - 2024-01-30
### Changed
- Update @nextcloud/vue to v8.6.0
- Change the player progress bar to the native browser component
[#52](https://git.crystalyx.net/Xefir/repod/issues/52) suggested by @W_LL_M
### Fixed
- Force the placement of the filter settings to the top
## 1.5.0 - Featuring the filtering - 2024-01-30
### Added
- Filtering options for each podcast section
[#50](https://git.crystalyx.net/Xefir/repod/issues/50) suggested by @W_LL_M
### Changed
- Update @nextcloud/router to v2.2.1
- Update @nextcloud/dialogs to v5.1.1
- Update @nextcloud/vue to v8.5.1
- Update vue-material-deisgn-icons to v5.3.0
- Displaying episode publication as "dd mmm yyyy" instead of xyz ago
[#48](https://git.crystalyx.net/Xefir/repod/issues/48) suggested by @W_LL_M
- Better display the reading status for episodes
[#51](https://git.crystalyx.net/Xefir/repod/issues/51) suggested by @W_LL_M
### Fixed
- When exporting feeds, if the RSS server fails, the export continue
### Removed
- Remove @nextcloud/moment
## 1.4.4 - 2024-01-24
### Changed
- Update @nextcloud/vue to v8.5.0
## 1.4.3 - 2024-01-21
### Added
- Expose the feed URL
[#41](https://git.crystalyx.net/Xefir/repod/issues/41) suggested by @SteveDinn
### Fixed
- More granular playback speed adustment by steps of 0.1
[#40](https://git.crystalyx.net/Xefir/repod/issues/40) reported by @SteveDinn
## 1.4.2 - 2024-01-20
### Fixed
- Ended episodes still didn't show well, should be fixed now hopefully
## 1.4.1 - 2024-01-19
### Fixed
- When deleting an episode on AntennaPod or on GPodder, it shows ended as expected
- Add space in the bottom of tops to allow catching the scrollbar
## 1.4.0 - 2024-01-18
### Added
- Import subscriptions
- Export subscriptions
## 1.3.0 - 2024-01-18
### Added
- Unified search integration
## 1.2.1 - 2024-01-18
### Changed
- When click on the title of the podcast on the player bar, it now opens the description modal
- Add icon on the playback speed setting
### Fixed
- Better fix for the background color of player bar on light theme
[#38](https://git.crystalyx.net/Xefir/repod/issues/38)
## 1.2.0 - 2024-01-17
### Added
- Add a playback speed setting
[#39](https://git.crystalyx.net/Xefir/repod/issues/39) suggested by @joezimjs
### Fixed
- Duration wrongly displayed
- Fix background color of player bar on light theme
[#38](https://git.crystalyx.net/Xefir/repod/issues/38) reported by @joezimjs
- Fix case of episodes not showing ended
## 1.1.2 - 2024-01-16
### Changed
- Sort subscriptions by listened time
### Removed
- Custom handler for redirections based on atom:link
## 1.1.1 - 2024-01-16
### Added

View File

@ -1,25 +1,22 @@
FROM nextcloud:28
FROM nextcloud:29
ENV NEXTCLOUD_UPDATE 1
ENV NEXTCLOUD_ADMIN_USER repod
ENV NEXTCLOUD_ADMIN_PASSWORD repod
ENV NEXTCLOUD_INIT_HTACCESS 1
ENV SQLITE_DATABASE repod
ENV GPODDERSYNC_VERSION 3.8.2
ENV NEXTCLOUD_UPDATE=1
ENV NEXTCLOUD_ADMIN_USER=repod
ENV NEXTCLOUD_ADMIN_PASSWORD=repod
ENV NEXTCLOUD_INIT_HTACCESS=1
ENV SQLITE_DATABASE=repod
RUN apt-get update && \
apt-get install -y nodejs npm && \
apt-get install -y nodejs npm sqlite3 && \
rm -f /usr/local/etc/php/conf.d/opcache-recommended.ini && \
/entrypoint.sh true
USER www-data
COPY --chown=www-data:www-data . apps/repod
RUN curl -sSLo /tmp/gpoddersync.tar.gz https://github.com/thrillfall/nextcloud-gpodder/releases/download/${GPODDERSYNC_VERSION}/gpoddersync.tar.gz && \
tar xvzf /tmp/gpoddersync.tar.gz -C apps && \
rm /tmp/gpoddersync.tar.gz && \
cd apps/repod && make build && cd - && \
php occ app:enable gpoddersync repod && \
RUN cd apps/repod && make build && cd - && \
php occ app:install gpoddersync && \
php occ app:enable repod && \
php occ config:system:set debug --value=true
USER root

View File

@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,

View File

@ -1,3 +1,4 @@
# https://github.com/nextcloud/appstore/blob/fixed-templates/nextcloudappstore/scaffolding/app-templates/26/app/Makefile
# Generic Makefile for building and packaging a Nextcloud app which uses npm and
# Composer.
#
@ -102,14 +103,14 @@ dist: build
source:
rm -rf $(source_build_directory)
mkdir -p $(source_build_directory)
tar cvzf $(source_package_name).tar.gz \
tar -C .. -cvzf $(source_package_name).tar.gz \
--exclude-vcs \
--exclude="../$(app_name)/build" \
--exclude="../$(app_name)/js/node_modules" \
--exclude="../$(app_name)/node_modules" \
--exclude="../$(app_name)/*.log" \
--exclude="../$(app_name)/js/*.log" \
../$(app_name)
--exclude="$(app_name)/build" \
--exclude="$(app_name)/js/node_modules" \
--exclude="$(app_name)/node_modules" \
--exclude="$(app_name)/*.log" \
--exclude="$(app_name)/js/*.log" \
$(app_name)
# Builds the source package for the app store, ignores php tests, js tests
# and build related folders that are unnecessary for an appstore release
@ -117,45 +118,43 @@ source:
appstore:
rm -rf $(appstore_build_directory)
mkdir -p $(appstore_build_directory)
tar cvzf $(appstore_package_name).tar.gz \
--exclude-vcs \
--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)/webpack.config.js" \
--exclude="../$(app_name)/stylelint.config.js" \
--exclude="../$(app_name)/CHANGELOG.md" \
--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)/babel.config.js" \
--exclude="../$(app_name)/Dockerfile" \
--exclude="../$(app_name)/psalm.xml" \
--exclude="../$(app_name)/renovate.json" \
../$(app_name)
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)
# Start a nextcloud server on Docker to kickstart developement
.PHONY: dev

View File

@ -6,19 +6,42 @@ You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) inst
## Features
- [x] Browse podcasts and play them directly in Nextcloud
- [x] Keep track of subscribed shows and episodes
- [x] Sync them with GPodderSync compatible clients
- [ ] Import and export subscriptions
- [x] Mobile friendly interface
- [ ] Unified search integration
- [x] Interface in multiple languages
- Browse podcasts and play them directly in Nextcloud
- Keep track of subscribed shows and episodes
- Sync them with GPodderSync compatible clients
- Import and export subscriptions
- Mobile friendly interface
- Unified search integration
## Comparaison with similar apps for Nextcloud
| | [RePod](https://apps.nextcloud.com/apps/repod) | [NextPod](https://apps.nextcloud.com/apps/nextpod) | [Music](https://apps.nextcloud.com/apps/music) | [Podcast](https://apps.nextcloud.com/apps/podcast) |
| --- | --- | --- | --- | --- |
| Actively maintened | ✅ | ✅ | ✅ | ❌ |
| Play your local music files | ❌ | ❌ | ✅ | ❌ |
| Sync with [GPodder clients](#clients-supporting-sync-of-gpoddersync) | ✅ | ✅ | ❌ | ❌ |
| Add and manage subscriptions | ✅ | ❌ | ✅ | ✅ |
| Listen synced episodes by another clients | ✅ | ✅ | ❌ | ❌ |
| Fetch and listen new epidodes | ✅ | ❌ | ✅ | ✅ |
| Keep track of listened episodes | ✅ | ✅ | ❌ | ✅ |
| Download epidodes | ✅ | ✅ | ❌ | ✅ |
| Import and export subscriptions | ✅ | ❌ | ❌ | ❌ |
| Search and discover new podcasts | ✅ | ❌ | ❌ | ✅ |
| Open episode website and RSS feed | ✅ | ✅ | ❌ | ✅ |
| Integrate with Nextcloud search engine | ✅ | ❌ | ❌ | ✅ |
| Integrate with [Nextcloud Notes](https://apps.nextcloud.com/apps/notes) | ❌ | ✅ | ❌ | ❌ |
| Mobile friendly interface | ✅ | ❌ | ✅ | ✅ |
| Support chapters | ❌ | ❌ | ❌ | ✅ |
| Available in multiple languages | ⭕ (en/fr/de) | ❌ | ✅ | ⭕ (en/de) |
## Screenshots
### Homepage
![homepage](./screens/index.png)
### Discover
![homepage](./screens/discover.png)
### Search
![search](./screens/search.png)
@ -35,10 +58,11 @@ You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) inst
| [AntennaPod](https://antennapod.org) | Initial purpose for this project, as a synchronization endpoint for this client.<br> Support is available [as of version 2.5.1](https://github.com/AntennaPod/AntennaPod/pull/5243/). |
| [KDE Kasts](https://apps.kde.org/de/kasts/) | Supported since version 21.12 |
| [Podcast Merlin](https://github.com/yoyoooooooooo/Podcast-Merlin--Nextcloud-Gpodder-Client-For-Windows) | Full sync support podcast client for Windows |
| [Cardo](https://n0vella.github.io/#/cardo) | Podcast client with sync support, for Windows, Mac and Linux |
## Installation
Either from the official Nextcloud [app store](https://apps.nextcloud.com/apps/repod) or by downloading the [latest release](https://git.crystalyx.net/Xefir/RePod/releases/latest) and extracting it into your Nextcloud `apps/` directory.
Either from the official Nextcloud [app store](https://apps.nextcloud.com/apps/repod) or by downloading the [latest release](https://git.crystalyx.net/Xefir/repod/releases/latest) and extracting it into your Nextcloud `apps/` directory.
## Credits

View File

@ -7,25 +7,29 @@
<description><![CDATA[## Features
- 🔍 Browse and subscribe huge collection of podcasts
- 🔊 Listen to episodes directly in Nextcloud
- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/)
- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/) and [other apps](https://git.crystalyx.net/Xefir/repod#clients-supporting-sync-of-gpoddersync)
- 📱 Mobile friendly interface
- 📡 Import and export your subscriptions
- ➡️ Full features comparison [here](https://git.crystalyx.net/Xefir/repod#comparaison-with-similar-apps-for-nextcloud)
## Requirements
You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!]]></description>
<version>1.1.1</version>
<version>3.2.0</version>
<licence>agpl</licence>
<author mail="xefir@crystalyx.net" homepage="https://crystalyx.net">Xéfir Destiny</author>
<author mail="xefir@crystalyx.net" homepage="https://crystalyx.net">Michel Roux</author>
<namespace>RePod</namespace>
<category>integration</category>
<category>multimedia</category>
<website>https://git.crystalyx.net/Xefir/RePod</website>
<bugs>https://git.crystalyx.net/Xefir/RePod/issues</bugs>
<screenshot>https://git.crystalyx.net/Xefir/RePod/raw/branch/main/screens/index.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/RePod/raw/branch/main/screens/search.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/RePod/raw/branch/main/screens/episodes.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/RePod/raw/branch/main/screens/modal.png</screenshot>
<website>https://git.crystalyx.net/Xefir/repod</website>
<bugs>https://git.crystalyx.net/Xefir/repod/issues</bugs>
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/index.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/discover.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/search.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/episodes.png</screenshot>
<screenshot>https://git.crystalyx.net/Xefir/repod/raw/branch/main/screens/modal.png</screenshot>
<dependencies>
<php min-version="8.0"/>
<nextcloud min-version="26" max-version="28"/>
<php min-version="8.1"/>
<nextcloud min-version="27" max-version="30"/>
</dependencies>
<navigations>
<navigation>

View File

@ -13,8 +13,12 @@ declare(strict_types=1);
return [
'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'page#feed', 'url' => '/feed/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.+']],
['name' => 'page#discover', 'url' => '/discover', 'verb' => 'GET'],
['name' => 'episodes#action', 'url' => '/episodes/action', 'verb' => 'GET'],
['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'],
['name' => 'opml#export', 'url' => '/opml/export', 'verb' => 'GET'],
['name' => 'opml#import', 'url' => '/opml/import', 'verb' => 'POST'],
['name' => 'podcast#index', 'url' => '/podcast', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'],
['name' => 'toplist#hot', 'url' => '/toplist/hot', 'verb' => 'GET'],

View File

@ -1,3 +0,0 @@
const babelConfig = require('@nextcloud/babel-config')
module.exports = babelConfig

View File

@ -1,29 +1,30 @@
{
"name": "nextcloud/repod",
"description": "🔊 Browse, manage and listen to podcasts",
"type": "project",
"license": "AGPL-3.0-or-later",
"require-dev": {
"nextcloud/ocp": "^28.0.1",
"psalm/phar": "^5.19.0",
"nextcloud/coding-standard": "^1.1.1"
},
"scripts": {
"lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"psalm:check": "psalm.phar --threads=1 --no-cache --show-info=true",
"psalm:fix": "psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType"
},
"autoload": {
"psr-4": {
"OCA\\RePod\\": "lib/",
"OCA\\GPodderSync\\": "stubs/OCA/GPodderSync/"
}
},
"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"
},
"require-dev": {
"nextcloud/ocp": "^30.0.0",
"roave/security-advisories": "dev-latest",
"nextcloud/coding-standard": "^1.2.3",
"vimeo/psalm": "^5.26.1"
},
"config": {
"optimize-autoloader": true,
"sort-packages": true,
"platform": {
"php": "8.0"
"php": "8.1"
}
}
}

2855
composer.lock generated

File diff suppressed because it is too large Load Diff

48
l10n/de.js Normal file
View File

@ -0,0 +1,48 @@
OC.L10N.register(
"repod",
{
"RePod Subscriptions" : "RePod Abonnements",
"Podcast" : "Podcast",
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Suchen, Verwalten und Anhören von 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!" : "## 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- 📱 Mobile-freundliche Schnittstelle\n- 📡 Importieren und Exportieren Ihrer Abonnements\n\n## Voraussetzungen\nDu musst [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installiert haben, um diese App zu benutzen!",
"Download" : "Herunterladen",
"Add a RSS link" : "Einen RSS-Link hinzufügen",
"Subscribe" : "Abonnieren",
"Error while adding the feed" : "Fehler beim Hinzufügen des Feeds",
"Could not fetch search results" : "Suchergebnisse können nicht geladen werden",
"New podcasts" : "Neue Podcasts",
"Hot podcasts" : "Beliebte Podcasts",
"Could not fetch tops" : "Titel können nicht abgerufen werden",
"Copy feed" : "Feed kopieren",
"Link copied to the clipboard" : "Der Link des Feeds wurde in die Zwischenablage kopiert",
"Play" : "Abspielen",
"Stop" : "Stopp",
"Read" : "Gelesen",
"Open website" : "Webseite aufrufen",
"Could not change the status of the episode" : "Kann den Status der Folge nicht ändern",
"Could not fetch episodes" : "Folgen können nicht abgerufen werden",
"Export subscriptions" : "Abonnements exportieren",
"Filtering episodes" : "Folgen filtern",
"Show all" : "Zeige alles",
"Listened" : "Gehört",
"Listening" : "Läuft",
"Unlistened" : "Nicht angehört",
"Import subscriptions" : "Importiere Abonnements",
"Import OPML file" : "Importiere OPML-Datei",
"Rate RePod ❤️" : "Bewerte RePod ❤️",
"Playback speed" : "Wiedergabegeschwindigkeit",
"Favorite" : "Favorit",
"Are you sure you want to delete this subscription?" : "Bist Du sicher, dass Du das Abonnement löschen möchtest?",
"Error while removing the feed" : "Fehler beim Löschen des Feeds",
"You can only have 10 favorites" : "Du kannst nur 10 Favoriten haben",
"Add a podcast" : "Einen Podcast hinzufügen",
"Could not fetch subscriptions" : "Abonnements können nicht abgerufen werden",
"Find a podcast" : "Finde einen Podcast",
"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",
"No favorites" : "Keine Favoriten"
},
"");

46
l10n/de.json Normal file
View File

@ -0,0 +1,46 @@
{ "translations": {
"RePod Subscriptions" : "RePod Abonnements",
"Podcast" : "Podcast",
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Suchen, Verwalten und Anhören von 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!" : "## 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- 📱 Mobile-freundliche Schnittstelle\n- 📡 Importieren und Exportieren Ihrer Abonnements\n\n## Voraussetzungen\nDu musst [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installiert haben, um diese App zu benutzen!",
"Download" : "Herunterladen",
"Add a RSS link" : "Einen RSS-Link hinzufügen",
"Subscribe" : "Abonnieren",
"Error while adding the feed" : "Fehler beim Hinzufügen des Feeds",
"Could not fetch search results" : "Suchergebnisse können nicht geladen werden",
"New podcasts" : "Neue Podcasts",
"Hot podcasts" : "Beliebte Podcasts",
"Could not fetch tops" : "Titel können nicht abgerufen werden",
"Copy feed" : "Feed kopieren",
"Link copied to the clipboard" : "Der Link des Feeds wurde in die Zwischenablage kopiert",
"Play" : "Abspielen",
"Stop" : "Stopp",
"Read" : "Gelesen",
"Open website" : "Webseite aufrufen",
"Could not change the status of the episode" : "Kann den Status der Folge nicht ändern",
"Could not fetch episodes" : "Folgen können nicht abgerufen werden",
"Export subscriptions" : "Abonnements exportieren",
"Filtering episodes" : "Folgen filtern",
"Show all" : "Zeige alles",
"Listened" : "Gehört",
"Listening" : "Läuft",
"Unlistened" : "Nicht angehört",
"Import subscriptions" : "Importiere Abonnements",
"Import OPML file" : "Importiere OPML-Datei",
"Rate RePod ❤️" : "Bewerte RePod ❤️",
"Playback speed" : "Wiedergabegeschwindigkeit",
"Favorite" : "Favorit",
"Are you sure you want to delete this subscription?" : "Bist Du sicher, dass Du das Abonnement löschen möchtest?",
"Error while removing the feed" : "Fehler beim Löschen des Feeds",
"You can only have 10 favorites" : "Du kannst nur 10 Favoriten haben",
"Add a podcast" : "Einen Podcast hinzufügen",
"Could not fetch subscriptions" : "Abonnements können nicht abgerufen werden",
"Find a podcast" : "Finde einen Podcast",
"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",
"No favorites" : "Keine Favoriten"
},"pluralForm" :""
}

View File

@ -1,29 +1,48 @@
OC.L10N.register(
"repod",
{
"RePod" : "RePod",
"RePod Subscriptions" : "Abonnements sur RePod",
"Podcast" : "Podcast",
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Parcourir, gérer et écouter vos 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/)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/)\n\n## Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"## 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!" : "## Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/) et d'autres [applications](https://git.crystalyx.net/Xefir/repod#clients-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\n## Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"Download" : "Télécharger",
"Add a RSS link" : "Ajouter un lien RSS",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"Hot podcasts" : "Tendances",
"New podcasts" : "Nouveautés",
"Could not fetch tops" : "Impossible de récupérer les tops",
"Subscribe" : "S'abonner",
"Error while adding the feed" : "Erreur lors de l'ajout du flux",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"New podcasts" : "Nouveautés",
"Hot podcasts" : "Tendances",
"Could not fetch tops" : "Impossible de récupérer les tops",
"Copy feed" : "Copier le flux",
"Link copied to the clipboard" : "Lien vers le flux copié dans le presse-papiers",
"Play" : "Lecture",
"Stop" : "Arrêter",
"Read" : "Lu",
"Open website" : "Ouvrir le site web",
"Could not change the status of the episode" : "Impossible de changer le status de l'épisode",
"Could not fetch episodes" : "Impossible de récuprer les épisodes",
"Download" : "Télécharger",
"Delete" : "Supprimer",
"Export subscriptions" : "Exporter les abonnements",
"Filtering episodes" : "Filtrage des épisodes",
"Show all" : "Montrer tout",
"Listened" : "Écoutés",
"Listening" : "En cours",
"Unlistened" : "Non lus",
"Import subscriptions" : "Importer les abonnements",
"Import OPML file" : "Importer un fichier OPML",
"Rate RePod ❤️" : "Donnez votre avis ❤️",
"Playback speed" : "Vitesse de lecture",
"Favorite" : "Favori",
"Are you sure you want to delete this subscription?" : "Êtes-vous sûr de vouloir supprimer ce flux ?",
"Error while removing the feed" : "Erreur lors de la suppression du flux",
"You can only have 10 favorites" : "Vous ne pouvez avoir que 10 favoris",
"Add a podcast" : "Ajouter un podcast",
"Could not fetch subscriptions" : "Impossible de récupérer les flux",
"Find a podcast" : "Chercher un podcast",
"Error loading feed" : "Erreur lors du chargement du flux",
"Missing required app" : "Une application requise est manquante",
"Install GPodder Sync" : "Installer GPodder Sync"
"Install GPodder Sync" : "Installer GPodder Sync",
"Pin some subscriptions to see their latest updates" : "Ajoutez des abonnements en favoris pour obtenir les dernières nouvelles ici",
"No favorites" : "Aucun favoris"
},
"");

View File

@ -1,27 +1,46 @@
{ "translations": {
"RePod" : "RePod",
"RePod Subscriptions" : "Abonnements sur RePod",
"Podcast" : "Podcast",
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Parcourir, gérer et écouter vos 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/)\n\n## Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "## Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/)\n\n## Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"## 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!" : "## Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/) et d'autres [applications](https://git.crystalyx.net/Xefir/repod#clients-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\n## Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"Download" : "Télécharger",
"Add a RSS link" : "Ajouter un lien RSS",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"Hot podcasts" : "Tendances",
"New podcasts" : "Nouveautés",
"Could not fetch tops" : "Impossible de récupérer les tops",
"Subscribe" : "S'abonner",
"Error while adding the feed" : "Erreur lors de l'ajout du flux",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"New podcasts" : "Nouveautés",
"Hot podcasts" : "Tendances",
"Could not fetch tops" : "Impossible de récupérer les tops",
"Copy feed" : "Copier le flux",
"Link copied to the clipboard" : "Lien vers le flux copié dans le presse-papiers",
"Play" : "Lecture",
"Stop" : "Arrêter",
"Read" : "Lu",
"Open website" : "Ouvrir le site web",
"Could not change the status of the episode" : "Impossible de changer le status de l'épisode",
"Could not fetch episodes" : "Impossible de récuprer les épisodes",
"Download" : "Télécharger",
"Delete" : "Supprimer",
"Export subscriptions" : "Exporter les abonnements",
"Filtering episodes" : "Filtrage des épisodes",
"Show all" : "Montrer tout",
"Listened" : "Écoutés",
"Listening" : "En cours",
"Unlistened" : "Non lus",
"Import subscriptions" : "Importer les abonnements",
"Import OPML file" : "Importer un fichier OPML",
"Rate RePod ❤️" : "Donnez votre avis ❤️",
"Playback speed" : "Vitesse de lecture",
"Favorite" : "Favori",
"Are you sure you want to delete this subscription?" : "Êtes-vous sûr de vouloir supprimer ce flux ?",
"Error while removing the feed" : "Erreur lors de la suppression du flux",
"You can only have 10 favorites" : "Vous ne pouvez avoir que 10 favoris",
"Add a podcast" : "Ajouter un podcast",
"Could not fetch subscriptions" : "Impossible de récupérer les flux",
"Find a podcast" : "Chercher un podcast",
"Error loading feed" : "Erreur lors du chargement du flux",
"Missing required app" : "Une application requise est manquante",
"Install GPodder Sync" : "Installer GPodder Sync"
"Install GPodder Sync" : "Installer GPodder Sync",
"Pin some subscriptions to see their latest updates" : "Ajoutez des abonnements en favoris pour obtenir les dernières nouvelles ici",
"No favorites" : "Aucun favoris"
},"pluralForm" :""
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OCA\RePod\AppInfo;
use OCA\RePod\Service\SearchProvider;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\App;
@ -31,6 +32,10 @@ class Application extends App implements IBootstrap
/** @var IInitialState $initialState */
$initialState = $appContainer->get(IInitialState::class);
if (null === $appManager->getAppInfo(self::GPODDERSYNC_ID)) {
$appManager->disableApp(self::GPODDERSYNC_ID);
}
$gpoddersync = $appManager->isEnabledForUser(self::GPODDERSYNC_ID);
if (!$gpoddersync) {
try {
@ -43,5 +48,7 @@ class Application extends App implements IBootstrap
$initialState->provideInitialState('gpodder', $gpoddersync);
}
public function register(IRegistrationContext $context): void {}
public function register(IRegistrationContext $context): void {
$context->registerSearchProvider(SearchProvider::class);
}
}

View File

@ -19,26 +19,32 @@ class EpisodesController extends Controller
{
public function __construct(
IRequest $request,
private IClientService $clientService,
private EpisodeActionReader $episodeActionReader,
private EpisodeActionRepository $episodeActionRepository,
private IClientService $clientService,
private UserService $userService
) {
parent::__construct(Application::APP_ID, $request);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function list(string $url): JSONResponse {
$client = $this->clientService->newClient();
$feed = $client->get($url);
$episodes = $this->episodeActionReader->parseRssXml((string) $feed->getBody());
usort($episodes, fn (EpisodeActionExtraData $a, EpisodeActionExtraData $b) => $b->getPubDate() <=> $a->getPubDate());
$episodes = array_values(array_intersect_key($episodes, array_unique(array_map(fn (EpisodeActionExtraData $episode) => $episode->getGuid(), $episodes))));
return new JSONResponse($episodes, $feed->getStatusCode());
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function action(string $url): JSONResponse {
$action = $this->episodeActionRepository->findByEpisodeUrl($url, $this->userService->getUserUID());

View File

@ -0,0 +1,108 @@
<?php
declare(strict_types=1);
namespace OCA\RePod\Controller;
use OCA\GPodderSync\Core\PodcastData\PodcastDataReader;
use OCA\GPodderSync\Core\PodcastData\PodcastMetricsReader;
use OCA\GPodderSync\Core\SubscriptionChange\SubscriptionChangeSaver;
use OCA\RePod\AppInfo\Application;
use OCA\RePod\Service\UserService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\AppFramework\Http\Response;
use OCP\IL10N;
use OCP\IRequest;
class OpmlController extends Controller
{
public function __construct(
IRequest $request,
private IL10N $l10n,
private PodcastDataReader $podcastDataReader,
private PodcastMetricsReader $podcastMetricsReader,
private SubscriptionChangeSaver $subscriptionChangeSaver,
private UserService $userService
) {
parent::__construct(Application::APP_ID, $request);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function export(): DataDownloadResponse {
// 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');
$dateCreated = new \DateTime();
$head = $xml->addChild('head');
if (isset($head)) {
$head->addChild('title', $this->l10n->t('RePod Subscriptions'));
$head->addChild('dateCreated', $dateCreated->format(\DateTime::RFC822));
}
$body = $xml->addChild('body');
if (isset($body)) {
$subscriptions = $this->podcastMetricsReader->metrics($this->userService->getUserUID());
foreach ($subscriptions as $subscription) {
try {
$podcast = $this->podcastDataReader->getCachedOrFetchPodcastData($subscription->getUrl(), $this->userService->getUserUID());
} catch (\Exception $e) {
continue;
}
if ($podcast) {
$outline = $body->addChild('outline');
if (isset($outline)) {
$outline->addAttribute('xmlUrl', $subscription->getUrl());
$title = $podcast->getTitle();
$link = $podcast->getLink();
if (isset($title)) {
$outline->addAttribute('text', $title);
$outline->addAttribute('title', $title);
}
if (isset($link)) {
$outline->addAttribute('htmlUrl', $link);
}
}
}
}
}
return new DataDownloadResponse((string) $xml->asXML(), 'repod-'.$dateCreated->getTimestamp().'.opml', ' application/xml');
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function import(): Response {
$file = $this->request->getUploadedFile('import');
if ($file) {
$xml = new \SimpleXMLElement(file_get_contents((string) $file['tmp_name']));
/** @var \SimpleXMLElement[] $outlines */
$outlines = $xml->body->children();
$toSubscribe = [];
foreach ($outlines as $outline) {
$toSubscribe[] = (string) $outline['xmlUrl'];
}
$this->subscriptionChangeSaver->saveSubscriptionChanges($toSubscribe, [], $this->userService->getUserUID());
}
return new Response();
}
}

View File

@ -14,7 +14,10 @@ use OCP\Util;
class PageController extends Controller
{
public function __construct(IRequest $request, private IConfig $config) {
public function __construct(
IRequest $request,
private IConfig $config
) {
parent::__construct(Application::APP_ID, $request);
}
@ -23,14 +26,15 @@ class PageController extends Controller
* @NoCSRFRequired
*/
public function index(): TemplateResponse {
Util::addScript(Application::APP_ID, 'repod-main');
Util::addScript(Application::APP_ID, Application::APP_ID.'-main');
$csp = new ContentSecurityPolicy();
$csp->addAllowedImageDomain('*');
$csp->addAllowedMediaDomain('*');
if ($this->config->getSystemValueBool('debug')) {
// Unblock HMR requests.
if ($this->config->getSystemValueBool('debug', false)) {
/** @psalm-suppress DeprecatedMethod */
$csp->allowEvalScript();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedScriptDomain('*');
}
@ -40,4 +44,20 @@ class PageController extends Controller
return $response;
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function discover(): TemplateResponse {
return $this->index();
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function feed(): TemplateResponse {
return $this->index();
}
}

View File

@ -4,27 +4,55 @@ declare(strict_types=1);
namespace OCA\RePod\Controller;
use OCA\GPodderSync\Core\PodcastData\PodcastData;
use OCA\GPodderSync\Core\PodcastData\PodcastDataReader;
use OCA\RePod\AppInfo\Application;
use OCA\RePod\Core\PodcastData\PodcastData;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Http\Client\IClientService;
use OCP\ICacheFactory;
use OCP\IRequest;
class PodcastController extends Controller
{
public function __construct(
IRequest $request,
private IClientService $clientService
private ICacheFactory $cacheFactory,
private IClientService $clientService,
private PodcastDataReader $podcastDataReader
) {
parent::__construct(Application::APP_ID, $request);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index(string $url): JSONResponse {
$podcast = null;
if ($this->cacheFactory->isLocalCacheAvailable()) {
try {
$podcast = $this->podcastDataReader->tryGetCachedPodcastData($url);
} catch (\Exception $e) {
}
}
if ($podcast) {
return new JSONResponse($podcast);
}
$client = $this->clientService->newClient();
$feed = $client->get($url);
$podcast = PodcastData::parseRssXml((string) $feed->getBody());
return new JSONResponse($podcast->toArrayWithExtras(), $feed->getStatusCode());
if ($this->cacheFactory->isLocalCacheAvailable()) {
try {
$this->podcastDataReader->trySetCachedPodcastData($url, $podcast);
} catch (\Exception $e) {
}
}
return new JSONResponse($podcast, $feed->getStatusCode());
}
}

View File

@ -4,41 +4,26 @@ 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 OCA\RePod\Service\ItunesService;
use OCA\RePod\Service\MultiPodService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
class SearchController extends Controller
{
public function __construct(
IRequest $request,
private LoggerInterface $logger,
private FyydService $fyydService,
private ItunesService $itunesService
private MultiPodService $multiPodService
) {
parent::__construct(Application::APP_ID, $request);
}
public function index(string $value): JSONResponse {
$podcasts = [];
$providers = [$this->fyydService, $this->itunesService];
foreach ($providers as $provider) {
try {
$podcasts = [...$podcasts, ...$provider->search($value)];
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), $e->getTrace());
}
}
usort($podcasts, fn (PodcastData $a, PodcastData $b) => $b->getFetchedAtUnix() <=> $a->getFetchedAtUnix());
$podcasts = array_values(array_intersect_key($podcasts, array_unique(array_map(fn (PodcastData $feed) => $feed->getLink(), $podcasts))));
return new JSONResponse($podcasts);
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index(string $q): JSONResponse {
return new JSONResponse($this->multiPodService->search($q));
}
}

View File

@ -19,10 +19,18 @@ class ToplistController extends Controller
parent::__construct(Application::APP_ID, $request);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function hot(): JSONResponse {
return new JSONResponse($this->fyydService->hot());
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function new(): JSONResponse {
return new JSONResponse($this->fyydService->latest());
}

View File

@ -24,7 +24,7 @@ use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;
* type: ?string,
* size: ?int,
* pubDate: ?\DateTime,
* duration: ?int,
* duration: ?string,
* action: ?EpisodeActionType
* }
*/
@ -42,7 +42,7 @@ class EpisodeActionExtraData implements \JsonSerializable
private ?string $type,
private ?int $size,
private ?\DateTime $pubDate,
private ?int $duration,
private ?string $duration,
private ?EpisodeAction $action
) {}
@ -94,7 +94,7 @@ class EpisodeActionExtraData implements \JsonSerializable
return $this->pubDate;
}
public function getDuration(): ?int {
public function getDuration(): ?string {
return $this->duration;
}

View File

@ -6,7 +6,6 @@ namespace OCA\RePod\Core\EpisodeAction;
use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader as CoreEpisodeActionReader;
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
use OCA\RePod\Core\PodcastData\PodcastData;
use OCA\RePod\Service\UserService;
class EpisodeActionReader extends CoreEpisodeActionReader
@ -53,60 +52,65 @@ class EpisodeActionReader extends CoreEpisodeActionReader
$name = (string) $item->title;
// Get episode link
$link = PodcastData::stringOrNull($item->link);
$link = $this->stringOrNull($item->link);
// Get episode image
$image = PodcastData::stringOrNull($item->image->url);
if (!$image && $iTunesItemChildren) {
if (isset($iTunesItemChildren)) {
$imageAttributes = $iTunesItemChildren->image->attributes();
$image = PodcastData::stringOrNull($imageAttributes ? (string) $imageAttributes->href : '');
$image = $this->stringOrNull(isset($imageAttributes) ? (string) $imageAttributes->href : '');
}
if (!$image) {
$image = PodcastData::stringOrNull($channel->image->url);
}
if (!$image && $iTunesChannelChildren) {
if (!isset($image) && isset($iTunesChannelChildren)) {
$imageAttributes = $iTunesChannelChildren->image->attributes();
$image = PodcastData::stringOrNull($imageAttributes ? (string) $imageAttributes->href : '');
$image = $this->stringOrNull(isset($imageAttributes) ? (string) $imageAttributes->href : '');
}
if (!$image) {
if (!isset($image)) {
$image = $this->stringOrNull($item->image->url);
}
if (!isset($image)) {
$image = $this->stringOrNull($channel->image->url);
}
if (!isset($image)) {
preg_match('/<itunes:image\s+href="([^"]+)"/', $xmlString, $matches);
$image = PodcastData::stringOrNull($matches[1]);
if (count($matches) > 1) {
$image = $this->stringOrNull($matches[1]);
}
}
// Get episode description
$itemContent = $item->children('content', true);
if ($itemContent) {
$description = PodcastData::stringOrNull($itemContent->encoded);
if (isset($itemContent)) {
$description = $this->stringOrNull($itemContent->encoded);
} else {
$description = PodcastData::stringOrNull($item->description);
$description = $this->stringOrNull($item->description);
}
if (!$description && $iTunesItemChildren) {
$description = PodcastData::stringOrNull($iTunesItemChildren->summary);
if (!isset($description) && isset($iTunesItemChildren)) {
$description = $this->stringOrNull($iTunesItemChildren->summary);
}
// Remove tags
$description = strip_tags(str_replace(['<br>', '<br/>', '<br />'], "\n", $description ?? ''));
// Get episode duration
if ($iTunesItemChildren) {
$rawDuration = PodcastData::stringOrNull($iTunesItemChildren->duration);
if (isset($iTunesItemChildren)) {
$duration = $this->stringOrNull($iTunesItemChildren->duration);
} else {
$rawDuration = PodcastData::stringOrNull($item->duration);
$duration = $this->stringOrNull($item->duration);
}
$splitDuration = array_reverse(explode(':', $rawDuration ?? ''));
$duration = (int) $splitDuration[0];
$duration += !empty($splitDuration[1]) ? (int) $splitDuration[1] * 60 : 0;
$duration += !empty($splitDuration[2]) ? (int) $splitDuration[2] * 60 : 0;
// Get episode pubDate
$rawPubDate = PodcastData::stringOrNull($item->pubDate);
$pubDate = $rawPubDate ? new \DateTime($rawPubDate) : null;
$pubDate = $this->stringOrNull($item->pubDate);
if (isset($pubDate)) {
try {
$pubDate = new \DateTime($pubDate);
} catch (\Exception $e) {
$pubDate = null;
}
}
$episodes[] = new EpisodeActionExtraData(
$title,
@ -127,4 +131,16 @@ class EpisodeActionReader extends CoreEpisodeActionReader
return $episodes;
}
/**
* @param null|\SimpleXMLElement|string $value
*/
private function stringOrNull($value): ?string {
/** @psalm-suppress RiskyTruthyFalsyComparison */
if (!empty($value)) {
return (string) $value;
}
return null;
}
}

View File

@ -1,105 +0,0 @@
<?php
declare(strict_types=1);
namespace OCA\RePod\Core\PodcastData;
use OCA\GPodderSync\Core\PodcastData\PodcastData as CorePodcastData;
/**
* @psalm-type PodcastDataType = array{
* title: ?string,
* author: ?string,
* link: ?string,
* description: ?string,
* imageUrl: ?string,
* fetchedAtUnix: int,
* imageBlob: ?string,
* atomLink: ?string
* }
*/
class PodcastData extends CorePodcastData implements \JsonSerializable
{
public function __construct(
?string $title,
?string $author,
?string $link,
?string $description,
?string $imageUrl,
int $fetchedAtUnix,
?string $imageBlob = null,
private ?string $atomLink
) {
parent::__construct(
$title,
$author,
$link,
$description,
$imageUrl,
$fetchedAtUnix,
$imageBlob
);
}
/**
* @throws \Exception if the XML data could not be parsed
*/
public static function parseRssXml(string $xmlString, ?int $fetchedAtUnix = null): PodcastData {
$xml = new \SimpleXMLElement($xmlString);
$channel = $xml->channel;
return new PodcastData(
self::stringOrNull($channel->title),
self::getXPathContent($xml, '/rss/channel/itunes:author'),
self::stringOrNull($channel->link),
self::stringOrNull($channel->description),
self::getXPathContent($xml, '/rss/channel/image/url')
?? self::getXPathAttribute($xml, '/rss/channel/itunes:image/@href'),
$fetchedAtUnix ?? (new \DateTime())->getTimestamp(),
null,
self::getXPathContent($xml, '/rss/channel/atom:link/@href')
);
}
/**
* @param null|\SimpleXMLElement|string $value
*/
public static function stringOrNull($value): ?string {
if ($value) {
return (string) $value;
}
return null;
}
public function getAtomLink(): ?string {
return $this->atomLink;
}
/**
* @return PodcastDataType
*/
public function toArrayWithExtras() {
return array_merge(parent::toArray(), [
'atomLink' => $this->atomLink,
]);
}
private static function getXPathContent(\SimpleXMLElement $xml, string $xpath): ?string {
$match = $xml->xpath($xpath);
if ($match) {
return (string) $match[0];
}
return null;
}
private static function getXPathAttribute(\SimpleXMLElement $xml, string $xpath): ?string {
$match = $xml->xpath($xpath);
if ($match) {
return (string) $match[0][0];
}
return null;
}
}

View File

@ -6,20 +6,16 @@ namespace OCA\RePod\Service;
use OCA\GPodderSync\Core\PodcastData\PodcastData;
use OCP\Http\Client\IClientService;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use Psr\Log\LoggerInterface;
class FyydService implements IProvider
class FyydService implements IPodProvider
{
private const BASE_URL = 'https://api.fyyd.de/0.2/';
public function __construct(
private UserService $userService,
private IClientService $clientService,
private IFactory $l10n,
private IUserSession $userSession,
private LoggerInterface $logger
private LoggerInterface $logger,
private UserService $userService
) {}
public function search(string $value): array {
@ -38,14 +34,16 @@ class FyydService implements IProvider
if (array_key_exists('data', $json) && is_array($json['data'])) {
/** @var string[] $feed */
foreach ($json['data'] as $feed) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
if ($feed['title']) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
}
}
}
@ -64,14 +62,16 @@ class FyydService implements IProvider
if (array_key_exists('data', $podcastJson) && is_array($podcastJson['data'])) {
/** @var string[] $feed */
foreach ($podcastJson['data'] as $feed) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
if ($feed['title']) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
}
}
}
@ -90,6 +90,7 @@ class FyydService implements IProvider
$langClient = $this->clientService->newClient();
$langResponse = $langClient->get(self::BASE_URL.'feature/podcast/hot/languages');
$langJson = (array) json_decode((string) $langResponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
if (array_key_exists('data', $langJson) && is_array($langJson['data'])) {
$language = in_array($userLang, $langJson['data']) ? $userLang : 'en';
}
@ -109,14 +110,16 @@ class FyydService implements IProvider
if (array_key_exists('data', $postCastJson) && is_array($postCastJson['data'])) {
/** @var string[] $feed */
foreach ($postCastJson['data'] as $feed) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
if ($feed['title']) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
}
}
}

View File

@ -6,7 +6,7 @@ namespace OCA\RePod\Service;
use OCA\GPodderSync\Core\PodcastData\PodcastData;
interface IProvider
interface IPodProvider
{
/**
* @return PodcastData[]

View File

@ -7,7 +7,7 @@ namespace OCA\RePod\Service;
use OCA\GPodderSync\Core\PodcastData\PodcastData;
use OCP\Http\Client\IClientService;
class ItunesService implements IProvider
class ItunesService implements IPodProvider
{
private const BASE_URL = 'https://itunes.apple.com/';

View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace OCA\RePod\Service;
use OCA\GPodderSync\Core\PodcastData\PodcastData;
use Psr\Log\LoggerInterface;
class MultiPodService implements IPodProvider
{
/**
* @var IPodProvider[]
*/
private array $providers = [];
public function __construct(
FyydService $fyydService,
ItunesService $itunesService,
private LoggerInterface $logger
) {
$this->providers = [$fyydService, $itunesService];
}
/**
* @return PodcastData[]
*/
public function search(string $value): array {
$podcasts = [];
foreach ($this->providers as $provider) {
try {
$podcasts = [...$podcasts, ...$provider->search($value)];
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), $e->getTrace());
}
}
usort($podcasts, fn (PodcastData $a, PodcastData $b) => $b->getFetchedAtUnix() <=> $a->getFetchedAtUnix());
return array_values(
array_intersect_key(
$podcasts,
array_unique(
array_map(
fn (PodcastData $feed) => $feed->getLink(),
array_filter($podcasts, fn (PodcastData $feed) => $feed->getLink())
)
)
)
);
}
}

View File

@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace OCA\RePod\Service;
use OCA\RePod\AppInfo\Application;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Search\IProvider;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;
class SearchProvider implements IProvider
{
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private MultiPodService $multiPodService
) {}
public function getId(): string {
return Application::APP_ID;
}
public function getName(): string {
return $this->l10n->t('Podcast');
}
public function getOrder(string $route, array $routeParameters): int {
if (0 === strpos($route, Application::APP_ID.'.')) {
// Active app, prefer my results
return -1;
}
return 25;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
$podcasts = $this->multiPodService->search($query->getTerm());
$searchResults = [];
foreach ($podcasts as $podcast) {
$title = $podcast->getTitle();
$link = $podcast->getLink();
if (isset($title, $link)) {
$searchResults[] = new SearchResultEntry(
$podcast->getImageUrl() ?? $this->urlGenerator->linkTo(Application::APP_ID, 'img/app.svg'),
$title,
$podcast->getAuthor() ?? '',
$this->urlGenerator->linkToRoute('repod.page.index').'/#/'.urlencode(base64_encode($link)),
$this->urlGenerator->linkTo(Application::APP_ID, 'img/app.svg')
);
}
}
return SearchResult::complete(
$this->l10n->t('Podcast'),
$searchResults
);
}
}

16592
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +1,52 @@
{
"name": "repod",
"description": "🔊 Browse, manage and listen to podcasts",
"version": "1.1.1",
"bugs": {
"url": "https://git.crystalyx.net/Xefir/RePod/issues"
},
"license": "agpl",
"private": true,
"license": "AGPL-3.0-or-later",
"type": "module",
"scripts": {
"build": "webpack --node-env production --progress",
"dev": "webpack --node-env development --progress",
"watch": "webpack --node-env development --progress --watch",
"serve": "webpack --node-env development serve --progress",
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --ext .js,.vue src --fix",
"stylelint": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue",
"stylelint:fix": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue --fix"
"build": "vue-tsc && vite build --mode production",
"dev": "vite build --mode development",
"dev:watch": "vite build --mode development --watch",
"watch": "npm run dev:watch",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
"stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix"
},
"prettier": "@nextcloud/prettier-config",
"dependencies": {
"@nextcloud/axios": "^2.4.0",
"@nextcloud/dialogs": "^5.0.3",
"@nextcloud/initial-state": "^2.1.0",
"@nextcloud/l10n": "^2.2.0",
"@nextcloud/moment": "1.2.2",
"@nextcloud/router": "^2.2.0",
"@nextcloud/vue": "^8.4.0",
"vue": "^2",
"vue-material-design-icons": "^5.2.0",
"vue-router": "^3",
"vuex": "^3"
"@nextcloud/axios": "^2.5.0",
"@nextcloud/initial-state": "^2.2.0",
"@nextcloud/l10n": "^3.1.0",
"@nextcloud/router": "^3.0.1",
"@nextcloud/vite-config": "^2.2.2",
"@nextcloud/vue": "9.0.0-alpha.5",
"dompurify": "^3.1.6",
"linkify-html": "^4.1.3",
"pinia": "^2.2.2",
"toastify-js": "^1.12.0",
"vite": "^5.4.5",
"vite-plugin-vue-devtools": "^7.4.5",
"vue": "^3.5.5",
"vue-material-design-icons": "^5.3.0",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@nextcloud/browserslist-config": "^3.0.1",
"@nextcloud/eslint-config": "^8.4.1",
"@nextcloud/prettier-config": "^1.1.0",
"@nextcloud/stylelint-config": "^3.0.1",
"@types/toastify-js": "^1.12.3",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/tsconfig": "^0.5.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-pinia": "^0.4.1",
"eslint-plugin-prettier": "^5.2.1",
"ts-node": "^10.9.2",
"typescript": "5.5",
"vue-eslint-parser": "^9.4.3",
"vue-tsc": "^2.1.6"
},
"browserslist": [
"extends @nextcloud/browserslist-config"
],
"engines": {
"node": "^20.0.0",
"npm": "^9.0.0"
},
"devDependencies": {
"@nextcloud/babel-config": "^1.0.0",
"@nextcloud/browserslist-config": "^3.0.0",
"@nextcloud/eslint-config": "^8.3.0",
"@nextcloud/stylelint-config": "^2.3.1",
"@nextcloud/webpack-vue-config": "^6.0.0"
}
]
}

View File

@ -2,11 +2,12 @@
<psalm
errorLevel="1"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
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" />
@ -17,20 +18,8 @@
</projectFiles>
<extraFiles>
<directory name="vendor" />
<ignoreFiles>
<directory name="vendor/psalm" />
</ignoreFiles>
</extraFiles>
<issueHandlers>
<UndefinedDocblockClass>
<errorLevel type="suppress">
<referencedClass name="OC\AppFramework\OCS\BaseResponse"/>
<referencedClass name="Doctrine\DBAL\Schema\Schema" />
<referencedClass name="Doctrine\DBAL\Schema\SchemaException" />
<referencedClass name="Doctrine\DBAL\Driver\Statement" />
<referencedClass name="Doctrine\DBAL\Schema\Table" />
</errorLevel>
</UndefinedDocblockClass>
<InvalidReturnType>
<errorLevel type="suppress">
<directory name="stubs" />

BIN
screens/discover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

After

Width:  |  Height:  |  Size: 857 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 817 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 961 KiB

View File

@ -7,13 +7,15 @@
</NcContent>
</template>
<script>
import '@nextcloud/dialogs/style.css'
<script lang="ts">
import 'toastify-js/src/toastify.css'
import { mapActions, mapState } from 'pinia'
import Bar from './components/Player/Bar.vue'
import GPodder from './views/GPodder.vue'
import { NcContent } from '@nextcloud/vue'
import Subscriptions from './components/Sidebar/Subscriptions.vue'
import { loadState } from '@nextcloud/initial-state'
import { usePlayer } from './store/player.ts'
export default {
name: 'App',
@ -24,9 +26,22 @@ export default {
Subscriptions,
},
computed: {
...mapState(usePlayer, ['paused']),
gpodder() {
return loadState('repod', 'gpodder', false)
},
},
mounted() {
this.init()
setInterval(this.loop, 40000)
},
methods: {
...mapActions(usePlayer, ['init', 'time']),
loop() {
if (this.paused === false) {
this.time()
}
},
},
}
</script>

View File

@ -1,22 +0,0 @@
<template>
<ul :class="episode ? 'margin' : ''">
<slot />
</ul>
</template>
<script>
export default {
name: 'AdaptativeList',
computed: {
episode() {
return this.$store.state.player.episode
},
},
}
</script>
<style scoped>
.margin {
margin-bottom: 6rem;
}
</style>

View File

@ -0,0 +1,27 @@
<template>
<NcAppContent :class="{ episode }">
<slot />
</NcAppContent>
</template>
<script lang="ts">
import { NcAppContent } from '@nextcloud/vue'
import { mapState } from 'pinia'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'AppContent',
components: {
NcAppContent,
},
computed: {
...mapState(usePlayer, ['episode']),
},
}
</script>
<style scoped>
.episode {
padding-bottom: 6rem;
}
</style>

View File

@ -0,0 +1,33 @@
<template>
<NcAppNavigation :class="{ episode }">
<slot />
<template #list>
<slot name="list" />
</template>
<template #footer>
<slot name="footer" />
</template>
</NcAppNavigation>
</template>
<script lang="ts">
import { NcAppNavigation } from '@nextcloud/vue'
import { mapState } from 'pinia'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'AppNavigation',
components: {
NcAppNavigation,
},
computed: {
...mapState(usePlayer, ['episode']),
},
}
</script>
<style scoped>
.episode {
padding-bottom: 6rem;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<NcEmptyContent class="empty">
<slot />
<template #icon>
<slot name="icon" />
</template>
<template #name>
<slot name="name" />
</template>
<template #description>
<slot name="description" />
</template>
<template #action>
<slot name="action" />
</template>
</NcEmptyContent>
</template>
<script lang="ts">
import { NcEmptyContent } from '@nextcloud/vue'
export default {
name: 'EmptyContent',
components: {
NcEmptyContent,
},
}
</script>
<style scoped>
.empty {
height: 100%;
}
</style>

View File

@ -2,7 +2,7 @@
<NcLoadingIcon class="loading" />
</template>
<script>
<script lang="ts">
import { NcLoadingIcon } from '@nextcloud/vue'
export default {
@ -14,7 +14,7 @@ export default {
</script>
<style scoped>
.loading {
margin: 2rem 0;
}
.loading {
margin: 2rem 0;
}
</style>

View File

@ -0,0 +1,73 @@
<template>
<div class="flex">
<NcAvatar
:display-name="episode.name"
:is-no-user="true"
:size="256"
:url="episode.image" />
<h2>{{ episode.name }}</h2>
<SafeHtml :source="episode.description || ''" />
<div class="flex">
<NcButton v-if="episode.link" :href="episode.link" target="_blank">
<template #icon>
<OpenInNewIcon :size="20" />
</template>
{{ episode.title }}
</NcButton>
<NcButton
v-if="episode.url"
:download="filenameFromUrl(episode.url)"
:href="episode.url"
target="_blank">
<template #icon>
<DownloadIcon :size="20" />
</template>
{{ t('repod', 'Download') }}
{{ episode.size ? `(${humanFileSize(episode.size)})` : '' }}
</NcButton>
</div>
</div>
</template>
<script lang="ts">
import { NcAvatar, NcButton } from '@nextcloud/vue'
import DownloadIcon from 'vue-material-design-icons/Download.vue'
import type { EpisodeInterface } from '../../utils/types.ts'
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
import SafeHtml from './SafeHtml.vue'
import { filenameFromUrl } from '../../utils/url.ts'
import { humanFileSize } from '../../utils/size.ts'
import { t } from '@nextcloud/l10n'
export default {
name: 'Modal',
components: {
DownloadIcon,
NcAvatar,
NcButton,
OpenInNewIcon,
SafeHtml,
},
props: {
episode: {
type: Object as () => EpisodeInterface,
required: true,
},
},
methods: {
filenameFromUrl,
humanFileSize,
t,
},
}
</script>
<style scoped>
.flex {
align-items: center;
display: flex;
flex-direction: column;
gap: 1rem;
margin: 2rem;
}
</style>

View File

@ -0,0 +1,36 @@
<template>
<div v-sanitize="source" class="html" />
</template>
<script lang="ts">
import dompurify from 'dompurify'
import linkifyHtml from 'linkify-html'
export default {
name: 'SafeHtml',
directives: {
sanitize: {
mounted(el, binding) {
el.innerHTML = dompurify.sanitize(
linkifyHtml(binding.value, {
nl2br: true,
target: '_blank',
}),
)
},
},
},
props: {
source: {
type: String,
required: true,
},
},
}
</script>
<style>
.html a {
text-decoration: underline;
}
</style>

View File

@ -1,34 +1,37 @@
<template>
<ul>
<NcAppNavigationNewItem :name="t('repod', 'Add a RSS link')" @new-item="addSubscription">
<NcAppNavigationList class="list">
<NcAppNavigationNewItem
:name="t('repod', 'Add a RSS link')"
@new-item="(url) => $router.push(toFeedUrl(url))">
<template #icon>
<Plus :size="20" />
<PlusIcon :size="20" />
</template>
</NcAppNavigationNewItem>
</ul>
</NcAppNavigationList>
</template>
<script>
import { NcAppNavigationNewItem } from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import { encodeUrl } from '../../utils/url.js'
<script lang="ts">
import { NcAppNavigationList, NcAppNavigationNewItem } from '@nextcloud/vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import { t } from '@nextcloud/l10n'
import { toFeedUrl } from '../../utils/url.ts'
export default {
name: 'AddRss',
components: {
NcAppNavigationList,
NcAppNavigationNewItem,
Plus,
PlusIcon,
},
methods: {
addSubscription(feedUrl) {
this.$router.push(encodeUrl(feedUrl))
},
t,
toFeedUrl,
},
}
</script>
<style scoped>
ul {
margin-top: 2rem;
}
.list {
margin-top: 2rem;
}
</style>

View File

@ -1,43 +1,61 @@
<template>
<div>
<Loading v-if="loading" />
<AdaptativeList v-if="!loading">
<NcListItem v-for="feed in feeds"
<ul v-if="!loading">
<NcListItem
v-for="feed in feeds"
:key="feed.link"
:details="moment(feed.fetchedAtUnix*1000).fromNow()"
:details="formatLocaleDate(new Date(feed.fetchedAtUnix * 1000))"
:name="feed.title"
:to="toUrl(feed.link)">
:to="toFeedUrl(feed.link)">
<template #icon>
<NcAvatar :display-name="feed.author"
<NcAvatar
:display-name="feed.author"
:is-no-user="true"
:url="feed.imageUrl" />
</template>
<template #subname>
{{ feed.author }}
</template>
<template #actions>
<NcActionButton
v-if="!getSubByUrl(feed.link)"
:aria-label="t('repod', 'Subscribe')"
:name="t('repod', 'Subscribe')"
:title="t('repod', 'Subscribe')"
@click="addSubscription(feed.link)">
<template #icon>
<PlusIcon :size="20" />
</template>
</NcActionButton>
</template>
</NcListItem>
</AdaptativeList>
</ul>
</div>
</template>
<script>
import { NcAvatar, NcListItem } from '@nextcloud/vue'
import AdaptativeList from '../Atoms/AdaptativeList.vue'
<script lang="ts">
import { NcActionButton, NcAvatar, NcListItem } from '@nextcloud/vue'
import { mapActions, mapState } from 'pinia'
import Loading from '../Atoms/Loading.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import type { PodcastDataInterface } from '../../utils/types.ts'
import axios from '@nextcloud/axios'
import { debounce } from '../../utils/debounce.js'
import { formatLocaleDate } from '../../utils/time.ts'
import { generateUrl } from '@nextcloud/router'
import moment from '@nextcloud/moment'
import { showError } from '@nextcloud/dialogs'
import { toUrl } from '../../utils/url.js'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { toFeedUrl } from '../../utils/url.ts'
import { useSubscriptions } from '../../store/subscriptions.ts'
export default {
name: 'Search',
components: {
AdaptativeList,
Loading,
NcActionButton,
NcAvatar,
NcListItem,
PlusIcon,
},
props: {
value: {
@ -45,27 +63,55 @@ export default {
required: true,
},
},
data() {
return {
feeds: [],
loading: false,
}
data: () => ({
feeds: [] as PodcastDataInterface[],
loading: false,
timeout: null as NodeJS.Timeout | null,
}),
computed: {
...mapState(useSubscriptions, ['getSubByUrl']),
},
watch: {
value() {
this.search()
if (this.timeout) {
clearTimeout(this.timeout)
}
this.timeout = setTimeout(this.search, 200)
},
},
methods: {
moment,
toUrl,
search: debounce(async function value() {
...mapActions(useSubscriptions, ['fetch']),
formatLocaleDate,
t,
toFeedUrl,
async addSubscription(url: string) {
try {
await axios.post(
generateUrl('/apps/gpoddersync/subscription_change/create'),
{
add: [url],
remove: [],
},
)
} catch (e) {
console.error(e)
showError(t('repod', 'Error while adding the feed'))
}
this.fetch()
},
async search() {
try {
this.loading = true
const currentSearch = this.value
const feeds = await axios.get(generateUrl('/apps/repod/search?value={value}', { value: currentSearch }))
const feeds = await axios.get<PodcastDataInterface[]>(
generateUrl('/apps/repod/search?q={value}', {
value: currentSearch,
}),
)
if (currentSearch === this.value) {
this.feeds = [...feeds.data].sort((a, b) => b.fetchedAtUnix - a.fetchedAtUnix)
this.feeds = [...feeds.data].sort(
(a, b) => b.fetchedAtUnix - a.fetchedAtUnix,
)
}
} catch (e) {
console.error(e)
@ -75,7 +121,7 @@ export default {
this.loading = false
}
}
}, 200),
},
},
}
</script>

View File

@ -0,0 +1,92 @@
<template>
<div>
<h2>{{ title }}</h2>
<Loading v-if="loading" />
<ul v-if="!loading">
<li v-for="top in tops" :key="top.link">
<router-link :to="toFeedUrl(top.link)">
<img :src="top.imageUrl" :title="top.author" />
</router-link>
</li>
</ul>
</div>
</template>
<script lang="ts">
import Loading from '../Atoms/Loading.vue'
import type { PodcastDataInterface } from '../../utils/types.ts'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { toFeedUrl } from '../../utils/url.ts'
export default {
name: 'Toplist',
components: {
Loading,
},
props: {
type: {
type: String,
required: true,
},
},
data: () => ({
loading: true,
tops: [] as PodcastDataInterface[],
}),
computed: {
title() {
switch (this.type) {
case 'new':
return t('repod', 'New podcasts')
case 'hot':
return t('repod', 'Hot podcasts')
default:
return this.type
}
},
},
async mounted() {
try {
this.loading = true
const tops = await axios.get<PodcastDataInterface[]>(
generateUrl('/apps/repod/toplist/{type}', { type: this.type }),
)
this.tops = tops.data
} catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch tops'))
} finally {
this.loading = false
}
},
methods: {
toFeedUrl,
},
}
</script>
<style scoped>
h2 {
margin: 1rem 0;
}
img {
height: 100%;
width: 100%;
}
li {
flex-basis: 10rem;
flex-shrink: 0;
}
ul {
display: flex;
gap: 2rem;
overflow: scroll hidden;
padding-bottom: 0.5rem;
}
</style>

View File

@ -1,93 +0,0 @@
<template>
<div>
<h2>{{ title }}</h2>
<Loading v-if="loading" />
<ul v-if="!loading">
<li v-for="top in items" :key="top.link">
<router-link :to="toUrl(top.link)">
<img :src="top.imageUrl" :title="top.author">
</router-link>
</li>
</ul>
</div>
</template>
<script>
import Loading from '../Atoms/Loading.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import { toUrl } from '../../utils/url.js'
export default {
name: 'Tops',
components: {
Loading,
},
props: {
type: {
type: String,
required: true,
},
},
data() {
return {
items: [],
loading: true,
}
},
computed: {
title() {
switch (this.type) {
case 'new':
return t('repod', 'New podcasts')
case 'hot':
return t('repod', 'Hot podcasts')
default:
return this.type
}
},
},
async mounted() {
this.loadList()
},
methods: {
toUrl,
async loadList() {
try {
this.loading = true
const toplist = await axios.get(generateUrl(`/apps/repod/toplist/${this.type}`))
this.items = toplist.data
} catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch tops'))
} finally {
this.loading = false
}
},
},
}
</script>
<style scoped>
h2 {
margin: 1rem 0;
}
img {
height: 100%;
width: 100%;
}
li {
flex-basis: 10rem;
flex-shrink: 0;
}
ul {
display: flex;
gap: 2rem;
overflow: scroll hidden;
padding: .5rem;
}
</style>

View File

@ -1,29 +1,33 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<div class="header">
<img class="background" :src="imageUrl">
<img class="background" :src="feed.imageUrl" />
<div class="content">
<NcAvatar class="avatar"
:display-name="author || title"
:is-no-user="true"
:size="128"
:url="imageUrl" />
<div>
<NcAvatar
:display-name="feed.author || feed.title"
:is-no-user="true"
:size="128"
:url="feed.imageUrl" />
<a class="feed" :href="url" @click.prevent="copyFeed">
<RssIcon :size="20" />
<i>{{ t('repod', 'Copy feed') }}</i>
</a>
</div>
<div class="inner">
<div class="infos">
<h2>{{ title }}</h2>
<a :href="link" target="_blank">
<i>{{ author }}</i>
<h2>{{ feed.title }}</h2>
<a :href="feed.link" target="_blank">
<i>{{ feed.author }}</i>
</a>
<br><br>
<p>
<small v-html="strippedDescription" />
</p>
<br /><br />
<SafeHtml :source="feed.description || ''" />
</div>
<NcAppNavigationNew v-if="!isSubscribed"
<NcAppNavigationNew
v-if="!getSubByUrl(url)"
:text="t('repod', 'Subscribe')"
@click="addSubscription">
<template #icon>
<Plus :size="20" />
<PlusIcon :size="20" />
</template>
</NcAppNavigationNew>
</div>
@ -31,111 +35,112 @@
</div>
</template>
<script>
<script lang="ts">
import { NcAppNavigationNew, NcAvatar } from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import { mapActions, mapState } from 'pinia'
import { showError, showSuccess } from '../../utils/toast.ts'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import type { PodcastDataInterface } from '../../utils/types.ts'
import RssIcon from 'vue-material-design-icons/Rss.vue'
import SafeHtml from '../Atoms/SafeHtml.vue'
import axios from '@nextcloud/axios'
import { cleanHtml } from '../../utils/text.js'
import { decodeUrl } from '../../utils/url.js'
import { decodeUrl } from '../../utils/url.ts'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { useSubscriptions } from '../../store/subscriptions.ts'
export default {
name: 'Banner',
components: {
NcAvatar,
NcAppNavigationNew,
Plus,
PlusIcon,
RssIcon,
SafeHtml,
},
props: {
author: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
imageUrl: {
type: String,
required: true,
},
link: {
type: String,
required: true,
},
title: {
type: String,
feed: {
type: Object as () => PodcastDataInterface,
required: true,
},
},
computed: {
...mapState(useSubscriptions, ['getSubByUrl']),
url() {
return decodeUrl(this.$route.params.url)
},
isSubscribed() {
return this.$store.state.subscriptions.subscriptions.includes(this.url)
},
strippedDescription() {
return cleanHtml(this.description)
return decodeUrl(this.$route.params.url as string)
},
},
methods: {
...mapActions(useSubscriptions, ['fetch']),
t,
async addSubscription() {
try {
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [this.url], remove: [] })
await axios.post(
generateUrl('/apps/gpoddersync/subscription_change/create'),
{
add: [this.url],
remove: [],
},
)
} catch (e) {
console.error(e)
showError(t('repod', 'Error while adding the feed'))
}
this.$store.dispatch('subscriptions/fetch')
this.fetch()
},
copyFeed() {
window.navigator.clipboard.writeText(this.url)
showSuccess(t('repod', 'Link copied to the clipboard'))
},
},
}
</script>
<style scoped>
.avatar {
height: 8rem;
width: 8rem;
}
.background {
filter: blur(1rem) brightness(50%);
height: auto;
left: 0;
opacity: 0.4;
position: absolute;
top: 0;
width: 100%;
z-index: -1;
}
.background {
filter: blur(1rem) brightness(50%);
height: auto;
left: 0;
opacity: .4;
position: absolute;
top: 0;
width: 100%;
}
.content {
display: flex;
gap: 1rem;
height: 10rem;
position: relative;
}
.content {
display: flex;
gap: 2rem;
height: 10rem;
position: relative;
}
.feed {
display: flex;
gap: 0.2rem;
margin: 0.5rem;
}
.header {
height: 14rem;
overflow: hidden;
padding: 2rem;
position: relative;
}
.header {
height: 14rem;
overflow: hidden;
padding: 2rem;
position: relative;
}
.infos {
overflow: auto;
}
.infos {
flex: 1;
overflow: auto;
}
.inner {
display: flex;
flex: 1;
}
@media only screen and (max-width: 768px) {
.inner {
display: flex;
}
@media only screen and (max-width: 768px) {
.inner {
flex-direction: column;
}
flex-direction: column;
}
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<NcListItem
:active="isCurrentEpisode(episode)"
class="episode"
:details="
!oneLine && episode.pubDate
? formatLocaleDate(new Date(episode.pubDate?.date))
: ''
"
:force-display-actions="true"
:name="episode.name"
:one-line="oneLine"
:style="{ opacity: hasEnded(episode) ? 0.4 : 1 }"
:title="episode.description"
@click="modalEpisode = episode">
<template #actions>
<NcActionButton
v-if="!isCurrentEpisode(episode)"
:aria-label="t('repod', 'Play')"
:title="t('repod', 'Play')"
@click="load(episode, url)">
<template #icon>
<PlayIcon :size="20" />
</template>
</NcActionButton>
<NcActionButton
v-if="isCurrentEpisode(episode)"
:aria-label="t('repod', 'Stop')"
:title="t('repod', 'Stop')"
@click="load(null)">
<template #icon>
<StopIcon :size="20" />
</template>
</NcActionButton>
</template>
<template #extra>
<NcActions>
<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="markAs(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">
<Modal :episode="episode" />
</NcModal>
</template>
<template #icon>
<NcAvatar
:display-name="episode.name"
:is-no-user="true"
:url="episode.image" />
</template>
<template #indicator>
<NcProgressBar
v-if="episode.action && isListening(episode) && !oneLine"
class="progress"
:value="(episode.action.position * 100) / episode.action.total" />
</template>
<template #subname>
{{ episode.duration }}
</template>
</NcListItem>
</template>
<script lang="ts">
import {
NcActionButton,
NcActionLink,
NcActions,
NcAvatar,
NcListItem,
NcModal,
NcProgressBar,
} from '@nextcloud/vue'
import {
durationToSeconds,
formatEpisodeTimestamp,
formatLocaleDate,
} from '../../utils/time.ts'
import { hasEnded, isListening } from '../../utils/status.ts'
import { mapActions, mapState } from 'pinia'
import DownloadIcon from 'vue-material-design-icons/Download.vue'
import type { EpisodeInterface } from '../../utils/types.ts'
import Modal from '../Atoms/Modal.vue'
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
import PlayIcon from 'vue-material-design-icons/Play.vue'
import PlaylistPlayIcon from 'vue-material-design-icons/PlaylistPlay.vue'
import PlaylistRemoveIcon from 'vue-material-design-icons/PlaylistRemove.vue'
import StopIcon from 'vue-material-design-icons/Stop.vue'
import axios from '@nextcloud/axios'
import { filenameFromUrl } from '../../utils/url.ts'
import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Episode',
components: {
DownloadIcon,
Modal,
NcActionButton,
NcActionLink,
NcActions,
NcAvatar,
NcListItem,
NcModal,
NcProgressBar,
OpenInNewIcon,
PlayIcon,
PlaylistPlayIcon,
PlaylistRemoveIcon,
StopIcon,
},
props: {
episode: {
type: Object as () => EpisodeInterface,
required: true,
},
oneLine: {
type: Boolean,
default: false,
},
url: {
type: String,
required: true,
},
},
data: () => ({
loading: false,
modalEpisode: null as EpisodeInterface | null,
}),
computed: {
...mapState(usePlayer, { playerEpisode: 'episode' }),
},
methods: {
...mapActions(usePlayer, ['load']),
filenameFromUrl,
formatLocaleDate,
hasEnded,
isListening,
t,
isCurrentEpisode(episode: EpisodeInterface) {
return this.playerEpisode?.url === episode.url
},
async markAs(episode: EpisodeInterface, read: boolean) {
try {
this.loading = true
episode.action = {
podcast: this.url,
episode: episode.url,
guid: episode.guid,
action: 'play',
timestamp: formatEpisodeTimestamp(new Date()),
started: episode.action?.started || 0,
position: read ? durationToSeconds(episode.duration || '') : 0,
total: durationToSeconds(episode.duration || ''),
}
await axios.post(
generateUrl('/apps/gpoddersync/episode_action/create'),
[episode.action],
)
if (read && this.isCurrentEpisode(episode)) {
this.load(null)
}
} catch (e) {
console.error(e)
showError(t('repod', 'Could not change the status of the episode'))
} finally {
this.loading = false
}
},
},
}
</script>
<style scoped>
.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;
}
</style>

View File

@ -1,99 +1,83 @@
<template>
<div>
<Loading v-if="loading" />
<AdaptativeList v-if="!loading">
<NcListItem v-for="episode in episodes"
<ul v-if="!loading">
<Episode
v-for="episode in filteredEpisodes"
:key="episode.guid"
:active="isCurrentEpisode(episode)"
:class="hasEnded(episode) ? 'ended': ''"
:details="moment(episode.pubDate.date).fromNow()"
:force-display-actions="true"
:name="episode.name"
:title="episode.description"
@click="modalEpisode = episode">
<template #icon>
<NcAvatar :display-name="episode.name"
:is-no-user="true"
:url="episode.image" />
</template>
<template #subname>
{{ episode.duration > 0 ? formatTimer(new Date(episode.duration*1000)) : '' }}
</template>
<template #actions>
<NcActionButton v-if="!isCurrentEpisode(episode)" @click="load(episode)">
<template #icon>
<PlayButton :size="20" />
</template>
{{ t('repod', 'Play') }}
</NcActionButton>
<NcActionButton v-if="isCurrentEpisode(episode)" @click="load(null)">
<template #icon>
<StopButton :size="20" />
</template>
{{ t('repod', 'Stop') }}
</NcActionButton>
</template>
</NcListItem>
</AdaptativeList>
<NcModal v-if="modalEpisode" @close="closeModal">
<Modal :description="modalEpisode.description"
:image="modalEpisode.image"
:link="modalEpisode.link"
:name="modalEpisode.name"
:size="modalEpisode.size"
:title="modalEpisode.title"
:url="modalEpisode.url" />
</NcModal>
:episode="episode"
:url="url" />
</ul>
</div>
</template>
<script>
import { NcActionButton, NcAvatar, NcListItem, NcModal } from '@nextcloud/vue'
import { decodeUrl, encodeUrl } from '../../utils/url.js'
import AdaptativeList from '../Atoms/AdaptativeList.vue'
<script lang="ts">
import { hasEnded, isListening } from '../../utils/status.ts'
import Episode from './Episode.vue'
import type { EpisodeInterface } from '../../utils/types.ts'
import Loading from '../Atoms/Loading.vue'
import Modal from './Modal.vue'
import PlayButton from 'vue-material-design-icons/Play.vue'
import StopButton from 'vue-material-design-icons/Stop.vue'
import axios from '@nextcloud/axios'
import { formatTimer } from '../../utils/time.js'
import { decodeUrl } from '../../utils/url.ts'
import { generateUrl } from '@nextcloud/router'
import moment from '@nextcloud/moment'
import { showError } from '@nextcloud/dialogs'
import { mapState } from 'pinia'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { usePlayer } from '../../store/player.ts'
import { useSettings } from '../../store/settings.ts'
export default {
name: 'Episodes',
components: {
AdaptativeList,
Episode,
Loading,
Modal,
NcActionButton,
NcAvatar,
NcListItem,
NcModal,
PlayButton,
StopButton,
},
data() {
return {
episodes: [],
loading: true,
modalEpisode: null,
}
},
data: () => ({
episodes: [] as EpisodeInterface[],
loading: true,
}),
computed: {
currentEpisode() {
return this.$store.state.player.episode
...mapState(usePlayer, ['episode']),
...mapState(useSettings, ['filters']),
filteredEpisodes() {
return this.episodes.filter((episode) => {
if (!this.filters.listened && this.hasEnded(episode)) {
return false
}
if (!this.filters.listening && this.isListening(episode)) {
return false
}
if (!this.filters.unlistened && !this.isListening(episode)) {
return false
}
return true
})
},
url() {
return decodeUrl(this.$route.params.url)
return decodeUrl(this.$route.params.url as string)
},
},
watch: {
episode() {
if (this.episode) {
this.episodes = this.episodes.map((e) =>
e.url === this.episode?.url ? this.episode : e,
)
}
},
},
async mounted() {
try {
this.loading = true
const episodes = await axios.get(generateUrl('/apps/repod/episodes/list?url={url}', { url: this.url }))
this.episodes = [...episodes.data].sort((a, b) => new Date(b.pubDate.date) - new Date(a.pubDate.date))
const episodes = await axios.get<EpisodeInterface[]>(
generateUrl('/apps/repod/episodes/list?url={url}', {
url: this.url,
}),
)
this.episodes = [...episodes.data].sort(
(a, b) =>
new Date(b.pubDate?.date || '').getTime() -
new Date(a.pubDate?.date || '').getTime(),
)
} catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch episodes'))
@ -102,31 +86,8 @@ export default {
}
},
methods: {
formatTimer,
moment,
hasEnded(episode) {
return episode.action
&& episode.action.position > 0
&& episode.action.started > 0
&& episode.action.total > 0
&& episode.action.position >= episode.action.total
},
isCurrentEpisode(episode) {
return this.currentEpisode && this.currentEpisode.url === episode.url
},
load(episode) {
this.$store.dispatch('player/load', episode)
},
closeModal() {
this.modalEpisode = null
this.$router.push(encodeUrl(this.url))
},
hasEnded,
isListening,
},
}
</script>
<style scoped>
.ended {
opacity: .5;
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<NcGuestContent class="guest">
<Loading v-if="!feed.data" />
<NcAvatar
v-if="feed.data"
class="avatar"
:display-name="feed.data.author || feed.data.title"
:is-no-user="true"
:size="222"
:url="feed.data.imageUrl" />
<div v-if="feed.data" class="list">
<h2 class="title">{{ feed.data.title }}</h2>
<Loading v-if="loading" />
<ul v-if="!loading">
<Episode
v-for="episode in episodes"
:key="episode.guid"
:episode="episode"
:one-line="true"
:url="feed.metrics.url" />
</ul>
</div>
</NcGuestContent>
</template>
<script lang="ts">
import type { EpisodeInterface, SubscriptionInterface } from '../../utils/types.ts'
import { NcAvatar, NcGuestContent } from '@nextcloud/vue'
import Episode from './Episode.vue'
import Loading from '../Atoms/Loading.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { hasEnded } from '../../utils/status.ts'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
export default {
name: 'Favorite',
components: {
Episode,
Loading,
NcAvatar,
NcGuestContent,
},
props: {
feed: {
type: Object as () => SubscriptionInterface,
required: true,
},
},
data: () => ({
episodes: [] as EpisodeInterface[],
loading: true,
}),
async mounted() {
try {
this.loading = true
const episodes = await axios.get<EpisodeInterface[]>(
generateUrl('/apps/repod/episodes/list?url={url}', {
url: this.feed.metrics.url,
}),
)
this.episodes = [...episodes.data]
.sort(
(a, b) =>
new Date(b.pubDate?.date || '').getTime() -
new Date(a.pubDate?.date || '').getTime(),
)
.filter((episode) => !this.hasEnded(episode))
.slice(0, 4)
} catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch episodes'))
} finally {
this.loading = false
}
},
methods: {
hasEnded,
},
}
</script>
<style scoped>
.guest {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin: 20px !important;
}
.list {
flex: 1;
}
.title {
text-align: center;
}
@media only screen and (max-width: 768px) {
.avatar {
display: none;
}
}
</style>

View File

@ -1,95 +0,0 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<div>
<NcAvatar :display-name="name"
:is-no-user="true"
:size="256"
:url="image" />
<h2>{{ name }}</h2>
<p v-html="strippedDescription" />
<div>
<NcButton v-if="link"
:href="link"
target="_blank">
<template #icon>
<OpenInNew :size="20" />
</template>
{{ title }}
</NcButton>
<NcButton v-if="url"
:href="url"
target="_blank">
<template #icon>
<Download :size="20" />
</template>
{{ t('repod', 'Download') }} {{ size ? `(${episodeFileSize})` : '' }}
</NcButton>
</div>
</div>
</template>
<script>
import { NcAvatar, NcButton } from '@nextcloud/vue'
import Download from 'vue-material-design-icons/Download.vue'
import OpenInNew from 'vue-material-design-icons/OpenInNew.vue'
import { cleanHtml } from '../../utils/text.js'
import { humanFileSize } from '../../utils/size.js'
export default {
name: 'Modal',
components: {
Download,
NcAvatar,
NcButton,
OpenInNew,
},
props: {
name: {
type: String,
required: true,
},
image: {
type: String,
required: true,
},
description: {
type: String,
default: '',
},
url: {
type: String,
required: true,
},
link: {
type: String,
default: null,
},
title: {
type: String,
required: true,
},
size: {
type: Number,
default: null,
},
},
computed: {
episodeFileSize() {
return humanFileSize(this.size)
},
strippedDescription() {
return cleanHtml(this.description)
},
},
}
</script>
<style scoped>
div {
align-items: center;
display: flex;
flex-direction: column;
gap: 1rem;
margin: 2rem;
}
</style>

View File

@ -1,9 +1,10 @@
<template>
<div v-if="player.episode" class="footer">
<Loading v-if="!player.loaded" />
<ProgressBar v-if="player.loaded" />
<div v-if="player.loaded" class="player">
<img :src="player.episode.image">
<div v-if="episode" class="footer">
<img class="background" :src="episode.image" />
<Loading v-if="!loaded" />
<ProgressBar v-if="loaded" />
<div v-if="loaded" class="player">
<img :src="episode.image" />
<Infos class="infos" />
<Controls class="controls" />
<Timer class="timer" />
@ -12,13 +13,15 @@
</div>
</template>
<script>
<script lang="ts">
import Controls from './Controls.vue'
import Infos from './Infos.vue'
import Loading from '../Atoms/Loading.vue'
import ProgressBar from './ProgressBar.vue'
import Timer from './Timer.vue'
import Volume from './Volume.vue'
import { mapState } from 'pinia'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Bar',
@ -31,46 +34,56 @@ export default {
Volume,
},
computed: {
player() {
return this.$store.state.player
},
...mapState(usePlayer, ['episode', 'loaded']),
},
}
</script>
<style scoped>
.footer {
background-color: rgba(66, 66, 66, .9);
bottom: 0;
height: 6rem;
right: 0;
position: absolute;
width: 100%;
z-index: 2000;
}
.player {
display: flex;
gap: 1rem;
height: calc(6rem - 6px);
justify-content: space-between;
}
.timer {
width: 30%;
.background {
filter: blur(1rem) brightness(50%);
height: auto;
left: 0;
opacity: 0.4;
position: absolute;
top: 0;
width: 100%;
z-index: -1;
}
.footer {
background-color: var(--color-main-background);
bottom: 0;
height: 6rem;
right: 0;
position: absolute;
width: 100%;
z-index: 2000;
}
.player {
display: flex;
gap: 1rem;
height: 6rem;
justify-content: space-between;
}
.timer {
width: 30%;
}
.volume {
width: 10%;
}
@media only screen and (max-width: 768px) {
.infos {
flex: 1;
}
.timer,
.volume {
width: 10%;
}
@media only screen and (max-width: 768px) {
.infos {
flex: 2;
}
.timer, .volume {
display: none;
}
display: none;
}
}
</style>

View File

@ -1,40 +1,37 @@
<template>
<div class="controls">
<PauseButton v-if="!player.paused"
class="pointer"
:size="50"
@click="$store.dispatch('player/pause')" />
<PlayButton v-if="player.paused"
class="pointer"
:size="50"
@click="$store.dispatch('player/play')" />
<PauseIcon v-if="!paused" class="pointer" :size="50" @click="pause" />
<PlayIcon v-if="paused" class="pointer" :size="50" @click="play" />
</div>
</template>
<script>
import PauseButton from 'vue-material-design-icons/Pause.vue'
import PlayButton from 'vue-material-design-icons/Play.vue'
<script lang="ts">
import { mapActions, mapState } from 'pinia'
import PauseIcon from 'vue-material-design-icons/Pause.vue'
import PlayIcon from 'vue-material-design-icons/Play.vue'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Controls',
components: {
PauseButton,
PlayButton,
PauseIcon,
PlayIcon,
},
computed: {
player() {
return this.$store.state.player
},
...mapState(usePlayer, ['paused']),
},
methods: {
...mapActions(usePlayer, ['play', 'pause']),
},
}
</script>
<style scoped>
.controls {
display: flex;
}
.controls {
display: flex;
}
.pointer {
cursor: pointer;
}
.pointer {
cursor: pointer;
}
</style>

View File

@ -1,35 +1,51 @@
<template>
<div>
<a :href="player.episode.link" target="_blank">
<strong>{{ player.episode.name }}</strong>
</a>
<router-link :to="hash">
<i>{{ player.episode.title }}</i>
<div v-if="episode && podcastUrl" class="root">
<strong class="pointer" @click="modal = true">
{{ episode.name }}
</strong>
<router-link :to="toFeedUrl(podcastUrl)">
<i>{{ episode.title }}</i>
</router-link>
<NcModal v-if="modal" @close="modal = false">
<Modal :episode="episode" />
</NcModal>
</div>
</template>
<script>
import { toUrl } from '../../utils/url.js'
<script lang="ts">
import Modal from '../Atoms/Modal.vue'
import { NcModal } from '@nextcloud/vue'
import { mapState } from 'pinia'
import { toFeedUrl } from '../../utils/url.ts'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Infos',
components: {
Modal,
NcModal,
},
data: () => ({
modal: false,
}),
computed: {
player() {
return this.$store.state.player
},
hash() {
return toUrl(this.player.podcastUrl)
},
...mapState(usePlayer, ['episode', 'podcastUrl']),
},
methods: {
toFeedUrl,
},
}
</script>
<style scoped>
div {
display: flex;
flex-direction: column;
justify-content: center;
width: 40%;
}
.pointer {
cursor: pointer;
}
.root {
display: flex;
flex-direction: column;
justify-content: center;
width: 40%;
}
</style>

View File

@ -1,27 +1,37 @@
<template>
<div @click="(event) => $store.dispatch('player/seek', event.x * player.duration / event.target.offsetWidth)">
<NcProgressBar size="medium" :value="player.currentTime * 100 / player.duration" />
</div>
<input
v-if="duration"
class="progress"
:max="duration"
min="0"
type="range"
:value="currentTime"
@change="
(event) => seek(parseInt((event.target as HTMLInputElement).value))
" />
</template>
<script>
import { NcProgressBar } from '@nextcloud/vue'
<script lang="ts">
import { mapActions, mapState } from 'pinia'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'ProgressBar',
components: {
NcProgressBar,
},
computed: {
player() {
return this.$store.state.player
},
...mapState(usePlayer, ['duration', 'currentTime']),
},
methods: {
...mapActions(usePlayer, ['seek']),
},
}
</script>
<style scoped>
div {
cursor: pointer;
}
.progress {
height: 4px;
min-height: 4px;
position: absolute;
top: -2px;
width: 99%;
}
</style>

View File

@ -1,20 +1,20 @@
<template>
<div>
<span>{{ formatTimer(new Date(player.currentTime*1000)) }}</span>
<div v-if="currentTime && duration" class="root">
<span>{{ formatTimer(new Date(currentTime * 1000)) }}</span>
<span>/</span>
<span>{{ formatTimer(new Date(player.duration*1000)) }}</span>
<span>{{ formatTimer(new Date(duration * 1000)) }}</span>
</div>
</template>
<script>
import { formatTimer } from '../../utils/time.js'
<script lang="ts">
import { formatTimer } from '../../utils/time.ts'
import { mapState } from 'pinia'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Timer',
computed: {
player() {
return this.$store.state.player
},
...mapState(usePlayer, ['duration', 'currentTime']),
},
methods: {
formatTimer,
@ -23,10 +23,10 @@ export default {
</script>
<style scoped>
div {
align-items: center;
display: flex;
gap: 5px;
justify-content: center;
}
.root {
align-items: center;
display: flex;
gap: 5px;
justify-content: center;
}
</style>

View File

@ -1,80 +1,84 @@
<template>
<div>
<VolumeHigh v-if="player.volume > 0.7"
<VolumeHighIcon
v-if="volume > 0.7"
class="pointer"
:size="30"
@click="mute" />
<VolumeLow v-if="player.volume > 0 && player.volume <= 0.3"
<VolumeLowIcon
v-if="volume > 0 && volume <= 0.3"
class="pointer"
:size="30"
@click="mute" />
<VolumeMedium v-if="player.volume > 0.3 && player.volume <= 0.7"
<VolumeMediumIcon
v-if="volume > 0.3 && volume <= 0.7"
class="pointer"
:size="30"
@click="mute" />
<VolumeMute v-if="player.volume === 0"
<VolumeMuteIcon
v-if="volume === 0"
class="pointer"
:size="30"
@click="unmute" />
<input max="1"
@click="setVolume(volumeMuted)" />
<input
max="1"
min="0"
step="0.1"
type="range"
:value="player.volume"
@change="(event) => $store.dispatch('player/volume', event.target.value)">
:value="volume"
@change="
(event) =>
setVolume(parseInt((event.target as HTMLInputElement).value))
" />
</div>
</template>
<script>
import VolumeHigh from 'vue-material-design-icons/VolumeHigh.vue'
import VolumeLow from 'vue-material-design-icons/VolumeLow.vue'
import VolumeMedium from 'vue-material-design-icons/VolumeMedium.vue'
import VolumeMute from 'vue-material-design-icons/VolumeMute.vue'
<script lang="ts">
import { mapActions, mapState } from 'pinia'
import VolumeHighIcon from 'vue-material-design-icons/VolumeHigh.vue'
import VolumeLowIcon from 'vue-material-design-icons/VolumeLow.vue'
import VolumeMediumIcon from 'vue-material-design-icons/VolumeMedium.vue'
import VolumeMuteIcon from 'vue-material-design-icons/VolumeMute.vue'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Volume',
components: {
VolumeHigh,
VolumeLow,
VolumeMedium,
VolumeMute,
},
data() {
return {
volumeMuted: 0,
}
VolumeHighIcon,
VolumeLowIcon,
VolumeMediumIcon,
VolumeMuteIcon,
},
data: () => ({
volumeMuted: 0,
}),
computed: {
player() {
return this.$store.state.player
},
...mapState(usePlayer, ['volume']),
},
methods: {
...mapActions(usePlayer, ['setVolume']),
mute() {
this.volumeMuted = this.player.volume
this.$store.dispatch('player/volume', 0)
},
unmute() {
this.$store.dispatch('player/volume', this.volumeMuted)
this.volumeMuted = this.volume
this.setVolume(0)
},
},
}
</script>
<style scoped>
div {
align-items: center;
display: flex;
gap: 5px;
justify-content: center;
}
div {
align-items: center;
display: flex;
gap: 5px;
justify-content: flex-end;
}
input {
transform: rotate(270deg);
width: 4rem;
}
input {
transform: rotate(270deg);
width: 4rem;
}
.pointer {
cursor: pointer;
}
.pointer {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<NcAppNavigationItem
:href="generateUrl('/apps/repod/opml/export')"
:name="t('repod', 'Export subscriptions')">
<template #icon>
<ExportIcon :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import ExportIcon from 'vue-material-design-icons/Export.vue'
import { NcAppNavigationItem } from '@nextcloud/vue'
import { generateUrl } from '@nextcloud/router'
import { t } from '@nextcloud/l10n'
export default {
name: 'Export',
components: {
ExportIcon,
NcAppNavigationItem,
},
methods: {
generateUrl,
t,
},
}
</script>

View File

@ -0,0 +1,73 @@
<template>
<NcAppNavigationItem
:allow-collapse="true"
menu-placement="top"
:name="t('repod', 'Filtering episodes')">
<template #actions>
<NcActionCheckbox
:disabled="all"
:model-value="all"
@change="
setFilters({
listened: true,
listening: true,
unlistened: true,
})
">
{{ t('repod', 'Show all') }}
</NcActionCheckbox>
<NcActionCheckbox
:model-value="filters.listened"
@change="setFilters({ listened: !filters.listened })">
{{ t('repod', 'Listened') }}
</NcActionCheckbox>
<NcActionCheckbox
:model-value="filters.listening"
@change="setFilters({ listening: !filters.listening })">
{{ t('repod', 'Listening') }}
</NcActionCheckbox>
<NcActionCheckbox
:model-value="filters.unlistened"
@change="setFilters({ unlistened: !filters.unlistened })">
{{ t('repod', 'Unlistened') }}
</NcActionCheckbox>
</template>
<template #icon>
<FilterIcon v-if="all" :size="20" />
<FilterSettingsIcon v-if="!all" :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import { NcActionCheckbox, NcAppNavigationItem } from '@nextcloud/vue'
import { mapActions, mapState } from 'pinia'
import FilterIcon from 'vue-material-design-icons/Filter.vue'
import FilterSettingsIcon from 'vue-material-design-icons/FilterSettings.vue'
import { t } from '@nextcloud/l10n'
import { useSettings } from '../../store/settings.ts'
export default {
name: 'Filters',
components: {
FilterIcon,
FilterSettingsIcon,
NcAppNavigationItem,
NcActionCheckbox,
},
computed: {
...mapState(useSettings, ['filters']),
all() {
return (
this.filters.listened &&
this.filters.listening &&
this.filters.unlistened
)
},
},
methods: {
...mapActions(useSettings, ['setFilters']),
t,
},
}
</script>

View File

@ -0,0 +1,78 @@
<template>
<NcAppNavigationItem
:name="t('repod', 'Import subscriptions')"
@click="modal = true">
<template #extra>
<NcModal v-if="modal" @close="modal = false">
<div class="modal">
<h2>{{ t('repod', 'Import OPML file') }}</h2>
<form
v-if="!loading"
:action="generateUrl('/apps/repod/opml/import')"
enctype="multipart/form-data"
method="post"
@submit.prevent="importOpml">
<input
accept="application/xml,.opml"
name="import"
required
type="file" />
<input type="submit" />
</form>
<Loading v-if="loading" />
</div>
</NcModal>
</template>
<template #icon>
<ImportIcon :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import { NcAppNavigationItem, NcModal } from '@nextcloud/vue'
import ImportIcon from 'vue-material-design-icons/Import.vue'
import Loading from '../Atoms/Loading.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { t } from '@nextcloud/l10n'
export default {
name: 'Import',
components: {
ImportIcon,
Loading,
NcAppNavigationItem,
NcModal,
},
data: () => ({
loading: false,
modal: false,
}),
methods: {
generateUrl,
t,
async importOpml(event: Event) {
try {
const target = event.target as HTMLFormElement
const formData = new FormData(target)
this.loading = true
await axios.post(target.action, formData)
} catch (e) {
console.error(e)
} finally {
location.reload()
}
},
},
}
</script>
<style scoped>
.modal {
align-items: center;
display: flex;
flex-direction: column;
margin: 2rem;
}
</style>

View File

@ -0,0 +1,26 @@
<template>
<NcAppNavigationItem
href="https://apps.nextcloud.com/apps/repod#comments"
:name="t('repod', 'Rate RePod ❤️')">
<template #icon>
<StarIcon :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import { NcAppNavigationItem } from '@nextcloud/vue'
import StarIcon from 'vue-material-design-icons/Star.vue'
import { t } from '@nextcloud/l10n'
export default {
name: 'Rate',
components: {
NcAppNavigationItem,
StarIcon,
},
methods: {
t,
},
}
</script>

View File

@ -0,0 +1,30 @@
<template>
<NcAppNavigationSettings>
<Filters />
<Speed />
<Import />
<Export />
<Rate />
</NcAppNavigationSettings>
</template>
<script lang="ts">
import Export from './Export.vue'
import Filters from './Filters.vue'
import Import from './Import.vue'
import { NcAppNavigationSettings } from '@nextcloud/vue'
import Rate from './Rate.vue'
import Speed from './Speed.vue'
export default {
name: 'Settings',
components: {
Export,
Filters,
Import,
NcAppNavigationSettings,
Rate,
Speed,
},
}
</script>

View File

@ -0,0 +1,68 @@
<template>
<NcAppNavigationItem :name="t('repod', 'Playback speed')">
<template #extra>
<div class="extra">
<MinusIcon class="pointer" :size="20" @click="changeRate(-0.1)" />
<NcCounterBubble class="counter">x{{ rate }}</NcCounterBubble>
<PlusIcon class="pointer" :size="20" @click="changeRate(0.1)" />
</div>
</template>
<template #icon>
<SpeedometerSlowIcon v-if="rate < 1" :size="20" />
<SpeedometerMediumIcon v-if="rate === 1" :size="20" />
<SpeedometerIcon v-if="rate > 1" :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import { NcAppNavigationItem, NcCounterBubble } from '@nextcloud/vue'
import { mapActions, mapState } from 'pinia'
import MinusIcon from 'vue-material-design-icons/Minus.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import SpeedometerIcon from 'vue-material-design-icons/Speedometer.vue'
import SpeedometerMediumIcon from 'vue-material-design-icons/SpeedometerMedium.vue'
import SpeedometerSlowIcon from 'vue-material-design-icons/SpeedometerSlow.vue'
import { t } from '@nextcloud/l10n'
import { usePlayer } from '../../store/player.ts'
export default {
name: 'Speed',
components: {
NcAppNavigationItem,
NcCounterBubble,
MinusIcon,
PlusIcon,
SpeedometerIcon,
SpeedometerMediumIcon,
SpeedometerSlowIcon,
},
computed: {
...mapState(usePlayer, ['rate']),
},
methods: {
...mapActions(usePlayer, ['setRate']),
t,
changeRate(diff: number) {
const newRate = parseFloat((this.rate + diff).toPrecision(2))
this.setRate(newRate > 0 ? newRate : this.rate)
},
},
}
</script>
<style scoped>
.counter {
height: 20px;
}
.extra {
align-items: center;
display: flex;
gap: 0.5rem;
}
.pointer {
cursor: pointer;
}
</style>

View File

@ -1,87 +0,0 @@
<template>
<NcAppNavigationItem :loading="loading"
:name="feed ? feed.title : url"
:to="hash">
<template #icon>
<NcAvatar v-if="feed"
:display-name="feed.author || feed.title"
:is-no-user="true"
:url="feed.imageUrl" />
<Alert v-if="failed" />
</template>
<template #actions>
<NcActionButton @click="deleteSubscription">
<template #icon>
<Delete :size="20" />
</template>
{{ t('repod', 'Delete') }}
</NcActionButton>
</template>
</NcAppNavigationItem>
</template>
<script>
import { NcActionButton, NcAppNavigationItem, NcAvatar } from '@nextcloud/vue'
import Alert from 'vue-material-design-icons/Alert.vue'
import Delete from 'vue-material-design-icons/Delete.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import { toUrl } from '../../utils/url.js'
export default {
name: 'Item',
components: {
Alert,
Delete,
NcActionButton,
NcAppNavigationItem,
NcAvatar,
},
props: {
url: {
type: String,
required: true,
},
},
data() {
return {
failed: false,
loading: true,
feed: null,
}
},
computed: {
hash() {
return toUrl(this.url)
},
},
async mounted() {
try {
const podcastData = await axios.get(generateUrl('/apps/gpoddersync/personal_settings/podcast_data?url={url}', { url: this.url }))
this.feed = podcastData.data.data
} catch (e) {
this.failed = true
console.error(e)
} finally {
this.loading = false
}
},
methods: {
async deleteSubscription() {
if (confirm(t('repod', 'Are you sure you want to delete this subscription?'))) {
try {
this.loading = true
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [], remove: [this.url] })
} catch (e) {
console.error(e)
showError(t('repod', 'Error while removing the feed'))
} finally {
this.loading = false
this.$store.dispatch('subscriptions/fetch')
}
}
},
},
}
</script>

View File

@ -0,0 +1,148 @@
<template>
<NcAppNavigationItem
:loading="loading"
:name="feed?.data?.title || url"
:to="toFeedUrl(url)">
<template #actions>
<NcActionButton
:aria-label="t('repod', 'Favorite')"
:model-value="feed?.isFavorite"
:name="t('repod', 'Favorite')"
:title="t('repod', 'Favorite')"
@update:modelValue="switchFavorite($event)">
<template #icon>
<StarPlusIcon v-if="!feed?.isFavorite" :size="20" />
<StarRemoveIcon v-if="feed?.isFavorite" :size="20" />
</template>
</NcActionButton>
<NcActionButton
:aria-label="t(`core`, 'Delete')"
:name="t(`core`, 'Delete')"
:title="t(`core`, 'Delete')"
@click="deleteSubscription">
<template #icon>
<DeleteIcon :size="20" />
</template>
</NcActionButton>
</template>
<template #icon>
<NcAvatar
:display-name="feed?.data?.author || feed?.data?.title"
:is-no-user="true"
:url="feed?.data?.imageUrl" />
<StarIcon v-if="feed?.isFavorite" class="star" :size="20" />
<AlertIcon v-if="failed" />
</template>
</NcAppNavigationItem>
</template>
<script lang="ts">
import { NcActionButton, NcAppNavigationItem, NcAvatar } from '@nextcloud/vue'
import { mapActions, mapState } from 'pinia'
import AlertIcon from 'vue-material-design-icons/Alert.vue'
import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import type { PersonalSettingsPodcastDataInterface } from '../../utils/types.ts'
import StarIcon from 'vue-material-design-icons/Star.vue'
import StarPlusIcon from 'vue-material-design-icons/StarPlus.vue'
import StarRemoveIcon from 'vue-material-design-icons/StarRemove.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { toFeedUrl } from '../../utils/url.ts'
import { useSubscriptions } from '../../store/subscriptions.ts'
export default {
name: 'Subscription',
components: {
AlertIcon,
DeleteIcon,
NcActionButton,
NcAppNavigationItem,
NcAvatar,
StarIcon,
StarPlusIcon,
StarRemoveIcon,
},
props: {
url: {
type: String,
required: true,
},
},
data: () => ({
failed: false,
loading: true,
}),
computed: {
...mapState(useSubscriptions, ['subs']),
feed() {
return this.subs.find((sub) => sub.metrics.url === this.url)
},
},
async mounted() {
try {
const podcastData =
await axios.get<PersonalSettingsPodcastDataInterface>(
generateUrl(
'/apps/gpoddersync/personal_settings/podcast_data?url={url}',
{
url: this.url,
},
),
)
this.addMetadatas(this.url, podcastData.data.data)
} catch (e) {
this.failed = true
console.error(e)
} finally {
this.loading = false
}
},
methods: {
...mapActions(useSubscriptions, ['fetch', 'addMetadatas', 'setFavorite']),
t,
toFeedUrl,
async deleteSubscription() {
if (
confirm(
t('repod', 'Are you sure you want to delete this subscription?'),
)
) {
try {
this.loading = true
await axios.post(
generateUrl('/apps/gpoddersync/subscription_change/create'),
{ add: [], remove: [this.url] },
)
} catch (e) {
console.error(e)
showError(t('repod', 'Error while removing the feed'))
} finally {
this.setFavorite(this.url, false)
this.loading = false
this.fetch()
}
}
},
switchFavorite(value: boolean) {
if (value) {
if (this.subs.filter((sub) => sub.isFavorite).length >= 10) {
showError(t('repod', 'You can only have 10 favorites'))
return
}
}
this.setFavorite(this.url, value)
},
},
}
</script>
<style scoped>
.star {
bottom: 2px;
color: yellow;
left: 22px;
position: absolute;
}
</style>

View File

@ -1,58 +1,70 @@
<template>
<NcAppNavigation>
<NcAppContentList>
<router-link to="/">
<NcAppNavigationNew :text="t('repod', 'Add a podcast')">
<template #icon>
<Plus :size="20" />
</template>
</NcAppNavigationNew>
</router-link>
<Loading v-if="loading" />
<AdaptativeList v-if="!loading">
<Item v-for="subscriptionUrl of subscriptions"
:key="subscriptionUrl"
:url="subscriptionUrl" />
</AdaptativeList>
</NcAppContentList>
</NcAppNavigation>
<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>
</template>
<template #footer>
<Settings />
</template>
</AppNavigation>
</template>
<script>
import { NcAppContentList, NcAppNavigation, NcAppNavigationNew } from '@nextcloud/vue'
import AdaptativeList from '../Atoms/AdaptativeList.vue'
import Item from './Item.vue'
<script lang="ts">
import {
NcAppContentList,
NcAppNavigationList,
NcAppNavigationNew,
} from '@nextcloud/vue'
import { mapActions, mapState } from 'pinia'
import AppNavigation from '../Atoms/AppNavigation.vue'
import Loading from '../Atoms/Loading.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import { showError } from '@nextcloud/dialogs'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import Settings from '../Settings/Settings.vue'
import Subscription from './Subscription.vue'
import { showError } from '../../utils/toast.ts'
import { t } from '@nextcloud/l10n'
import { useSubscriptions } from '../../store/subscriptions.ts'
export default {
name: 'Subscriptions',
components: {
AdaptativeList,
Item,
AppNavigation,
Loading,
NcAppContentList,
NcAppNavigation,
NcAppNavigationList,
NcAppNavigationNew,
Plus,
},
data() {
return {
loading: true,
}
PlusIcon,
Settings,
Subscription,
},
data: () => ({
loading: true,
}),
computed: {
currentEpisode() {
return this.$store.state.player.episode
},
subscriptions() {
return this.$store.state.subscriptions.subscriptions
},
...mapState(useSubscriptions, ['subs']),
},
async mounted() {
try {
await this.$store.dispatch('subscriptions/fetch')
await this.fetch()
} catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch subscriptions'))
@ -60,5 +72,9 @@ export default {
this.loading = false
}
},
methods: {
...mapActions(useSubscriptions, ['fetch']),
t,
},
}
</script>

View File

@ -1,18 +0,0 @@
import { translatePlural as n, translate as t } from '@nextcloud/l10n'
import App from './App.vue'
import Vue from 'vue'
import { generateFilePath } from '@nextcloud/router'
import router from './router.js'
import store from './store/main.js'
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath(appName, '', 'js/')
Vue.mixin({ methods: { t, n } })
export default new Vue({
el: '#content',
router,
store,
render: h => h(App),
})

11
src/main.ts Normal file
View File

@ -0,0 +1,11 @@
import App from './App.vue'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router.ts'
const Vue = createApp(App)
const pinia = createPinia()
Vue.use(pinia)
Vue.use(router)
Vue.mount('#content')

View File

@ -1,23 +0,0 @@
import Discover from './views/Discover.vue'
import Feed from './views/Feed.vue'
import Router from 'vue-router'
import Vue from 'vue'
import { generateUrl } from '@nextcloud/router'
Vue.use(Router)
const router = new Router({
base: generateUrl('apps/repod'),
routes: [
{
path: '/',
component: Discover,
},
{
path: '/:url',
component: Feed,
},
],
})
export default router

25
src/router.ts Normal file
View File

@ -0,0 +1,25 @@
import { createRouter, createWebHistory } from 'vue-router'
import Discover from './views/Discover.vue'
import Feed from './views/Feed.vue'
import Home from './views/Home.vue'
import { generateUrl } from '@nextcloud/router'
const router = createRouter({
history: createWebHistory(generateUrl('apps/repod')),
routes: [
{
path: '/',
component: Home,
},
{
path: '/discover',
component: Discover,
},
{
path: '/feed/:url',
component: Feed,
},
],
})
export default router

View File

@ -1,15 +0,0 @@
import Vuex, { Store } from 'vuex'
import Vue from 'vue'
import { player } from './player.js'
import { subscriptions } from './subscriptions.js'
Vue.use(Vuex)
const store = new Store({
modules: {
player,
subscriptions,
},
})
export default store

View File

@ -1,111 +0,0 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import moment from '@nextcloud/moment'
import router from '../router.js'
import store from './main.js'
const audio = new Audio()
audio.ondurationchange = () => store.commit('player/duration', audio.duration)
audio.onended = () => store.dispatch('player/stop')
audio.onloadeddata = () => store.commit('player/loaded', true)
audio.onplay = () => store.commit('player/paused', false)
audio.onpause = () => store.commit('player/paused', true)
audio.onseeked = () => store.commit('player/currentTime', audio.currentTime)
audio.ontimeupdate = () => store.commit('player/currentTime', audio.currentTime)
audio.onvolumechange = () => store.commit('player/volume', audio.volume)
export const player = {
namespaced: true,
state: {
currentTime: null,
duration: null,
episode: null,
loaded: false,
paused: null,
podcastUrl: null,
volume: 1,
},
mutations: {
action: (state, action) => {
state.episode.action = action
if (action && action.position && action.position < action.total) {
audio.currentTime = action.position
}
},
currentTime: (state, currentTime) => {
state.currentTime = currentTime
},
duration: (state, duration) => {
state.duration = duration
},
episode: (state, episode) => {
state.episode = episode
if (episode) {
state.podcastUrl = atob(router.currentRoute.params.url)
audio.src = episode.url
audio.load()
audio.play()
if (episode.action && episode.action.position && episode.action.position < episode.action.total) {
audio.currentTime = episode.action.position
}
} else {
state.loaded = false
state.podcastUrl = null
audio.src = ''
}
},
loaded: (state, loaded) => {
state.loaded = loaded
},
paused: (state, paused) => {
state.paused = paused
},
volume: (state, volume) => {
state.volume = volume
},
},
actions: {
load: async (context, episode) => {
context.commit('episode', episode)
try {
const action = await axios.get(generateUrl('/apps/repod/episodes/action?url={url}', { url: episode.url }))
context.commit('action', action.data)
} catch {}
},
pause: (context) => {
audio.pause()
context.dispatch('time')
},
play: () => audio.play(),
seek: (context, currentTime) => {
audio.currentTime = currentTime
context.dispatch('time')
},
stop: (context) => {
context.dispatch('pause')
context.commit('episode', null)
},
time: async (context) => axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [{
podcast: context.state.podcastUrl,
episode: context.state.episode.url,
guid: context.state.episode.guid,
action: 'play',
timestamp: moment().format('YYYY-MM-DD[T]HH:mm:ss'),
started: Math.round(context.state.action ? context.state.action.started : 0),
position: Math.round(audio.currentTime),
total: Math.round(audio.duration),
}]),
volume: (_, volume) => {
audio.volume = volume
},
},
}
setInterval(() => {
if (player.state.paused === false) {
store.dispatch('player/time')
}
}, 40000)

111
src/store/player.ts Normal file
View File

@ -0,0 +1,111 @@
import type { EpisodeActionInterface, EpisodeInterface } from '../utils/types.ts'
import axios from '@nextcloud/axios'
import { defineStore } from 'pinia'
import { formatEpisodeTimestamp } from '../utils/time.ts'
import { generateUrl } from '@nextcloud/router'
const audio = new Audio()
export const usePlayer = defineStore('player', {
state: () => ({
currentTime: null as number | null,
duration: null as number | null,
episode: null as EpisodeInterface | null,
loaded: false,
paused: true,
podcastUrl: null as string | null,
volume: 1,
rate: 1,
started: 0,
}),
actions: {
init() {
audio.ondurationchange = () => (this.duration = audio.duration)
audio.onended = () => this.stop()
audio.onloadeddata = () => (this.loaded = true)
audio.onpause = () => this.pause()
audio.onplay = () => this.play()
audio.onratechange = () => (this.rate = audio.playbackRate)
audio.onseeked = () => (this.currentTime = audio.currentTime)
audio.ontimeupdate = () => (this.currentTime = audio.currentTime)
audio.onvolumechange = () => (this.volume = audio.volume)
},
async load(episode: EpisodeInterface | null, podcastUrl?: string) {
this.episode = episode
this.podcastUrl = podcastUrl || null
if (this.episode?.url) {
audio.src = this.episode.url
audio.load()
try {
const action = await axios.get<EpisodeActionInterface>(
generateUrl('/apps/repod/episodes/action?url={url}', {
url: this.episode.url,
}),
)
this.episode.action = action.data
} catch {}
if (
this.episode.action &&
this.episode.action.position < this.episode.action.total
) {
audio.currentTime = this.episode.action.position
this.started = audio.currentTime
}
audio.play()
} else {
this.loaded = false
this.podcastUrl = null
audio.src = ''
}
},
pause() {
audio.pause()
this.paused = true
this.time()
},
play() {
audio.play()
this.paused = false
this.started = audio.currentTime
},
seek(currentTime: number) {
audio.currentTime = currentTime
this.time()
},
stop() {
this.pause()
this.episode = null
},
time() {
if (!this.podcastUrl || !this.episode?.url) {
return
}
this.episode.action = {
podcast: this.podcastUrl,
episode: this.episode.url,
guid: this.episode.guid,
action: 'play',
timestamp: formatEpisodeTimestamp(new Date()),
started: Math.round(this.started),
position: Math.round(audio.currentTime),
total: Math.round(audio.duration),
}
axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [
this.episode.action,
])
},
setVolume(volume: number) {
audio.volume = volume
},
setRate(rate: number) {
audio.playbackRate = rate
},
},
})

37
src/store/settings.ts Normal file
View File

@ -0,0 +1,37 @@
import { getCookie, setCookie } from '../utils/cookies.ts'
import type { FiltersInterface } from '../utils/types.ts'
import { defineStore } from 'pinia'
export const useSettings = defineStore('settings', {
state: () => {
try {
const filters = JSON.parse(getCookie('repod.filters') || '{}') || {}
if (!filters.length) {
throw new Error('Empty cookie')
}
return {
filters: {
listened: filters.listened,
listening: filters.listening,
unlistened: filters.unlistened,
},
}
} catch {
return {
filters: {
listened: true,
listening: true,
unlistened: true,
},
}
}
},
actions: {
setFilters(filters: Partial<FiltersInterface>) {
this.filters = { ...this.filters, ...filters }
setCookie('repod.filters', JSON.stringify(this.filters), 365)
},
},
})

View File

@ -1,20 +0,0 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export const subscriptions = {
namespaced: true,
state: {
subscriptions: [],
},
mutations: {
set: (state, subscriptions) => {
state.subscriptions = subscriptions
},
},
actions: {
fetch: async (context) => {
const metrics = await axios.get(generateUrl('/apps/gpoddersync/personal_settings/metrics'))
context.commit('set', metrics.data.subscriptions.map(sub => sub.url))
},
},
}

View File

@ -0,0 +1,59 @@
import type {
PersonalSettingsMetricsInterface,
PodcastDataInterface,
SubscriptionInterface,
} from '../utils/types.ts'
import { getCookie, setCookie } from '../utils/cookies.ts'
import axios from '@nextcloud/axios'
import { defineStore } from 'pinia'
import { generateUrl } from '@nextcloud/router'
export const useSubscriptions = defineStore('subscriptions', {
state: () => ({
subs: [] as SubscriptionInterface[],
}),
getters: {
getSubByUrl: (state) => (url: string) =>
state.subs.find((sub) => sub.metrics.url === url),
},
actions: {
async fetch() {
let favorites: string[] = []
try {
favorites = JSON.parse(getCookie('repod.favorites') || '[]') || []
} catch {}
const metrics = await axios.get<PersonalSettingsMetricsInterface>(
generateUrl('/apps/gpoddersync/personal_settings/metrics'),
)
this.subs = [...metrics.data.subscriptions]
.sort((a, b) => b.listenedSeconds - a.listenedSeconds)
.map((sub) => ({
metrics: sub,
isFavorite: favorites.includes(sub.url),
data: this.subs.find((s) => s.metrics.url === sub.url)?.data,
}))
},
addMetadatas(link: string, data: PodcastDataInterface) {
this.subs = this.subs.map((sub) =>
sub.metrics.url === link ? { ...sub, data } : sub,
)
},
setFavorite(link: string, isFavorite: boolean) {
this.subs = this.subs.map((sub) =>
sub.metrics.url === link ? { ...sub, isFavorite } : sub,
)
setCookie(
'repod.favorites',
JSON.stringify(
this.subs
.filter((sub) => sub.isFavorite)
.map((sub) => sub.metrics.url),
),
365,
)
},
},
})

26
src/utils/cookies.ts Normal file
View File

@ -0,0 +1,26 @@
// https://grafikart.fr/tutoriels/javascript-cookies-2079
/**
* Récupère les données associées à un cookie
* @param {string} name Nom du cookie à récupérer
* @return {string|null}
*/
export const getCookie = (name: string): string | null => {
const cookies = document.cookie.split('; ')
const value = cookies.find((c) => c.startsWith(name + '='))?.split('=')[1]
if (value === undefined) {
return null
}
return decodeURIComponent(value)
}
/**
* Créer ou modifie la valeur d'un cookie avec une durée spécifique
* @param {string} name Nom du cookie
* @param {string} value Value du cookie
* @param {number} days Durée de vie du cookie (en jours)
*/
export const setCookie = (name: string, value: string, days: number) => {
const date = new Date()
date.setDate(date.getDate() + days)
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${date.toUTCString()}; SameSite=Strict;`
}

View File

@ -1,12 +0,0 @@
// https://stackoverflow.com/a/53486112
export const debounce = (fn, delay) => {
let timeoutID = null
return function() {
clearTimeout(timeoutID)
const args = arguments
const that = this
timeoutID = setTimeout(function() {
fn.apply(that, args)
}, delay)
}
}

View File

@ -1,5 +0,0 @@
// https://stackoverflow.com/a/20732091
export const humanFileSize = (size) => {
const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024))
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]
}

9
src/utils/size.ts Normal file
View File

@ -0,0 +1,9 @@
// https://stackoverflow.com/a/20732091
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]
)
}

16
src/utils/status.ts Normal file
View File

@ -0,0 +1,16 @@
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))
export const isListening = (episode: EpisodeInterface) =>
episode.action &&
episode.action.action &&
episode.action.action.toLowerCase() === 'play' &&
episode.action.position > 0 &&
!hasEnded(episode)

View File

@ -1,6 +0,0 @@
export const cleanHtml = (text) => {
const pre = document.createElement('pre')
pre.innerHTML = text.replace(/<br\s*\/?>/mg, '\n')
const strippedText = pre.textContent || pre.innerText || ''
return strippedText.replace(/\n/mg, '<br>')
}

View File

@ -1,11 +0,0 @@
export const formatTimer = (date) => {
const minutes = date.getUTCMinutes().toString().padStart(2, 0)
const seconds = date.getUTCSeconds().toString().padStart(2, 0)
let timer = `${minutes}:${seconds}`
if (date.getUTCHours()) {
timer = `${date.getUTCHours()}:${timer}`
}
return timer
}

53
src/utils/time.ts Normal file
View File

@ -0,0 +1,53 @@
/**
* Format a date to a timer
* @param {Date} date The date
* @return {string}
*/
export const formatTimer = (date: Date): string => {
const minutes = date.getUTCMinutes().toString().padStart(2, '0')
const seconds = date.getUTCSeconds().toString().padStart(2, '0')
let timer = `${minutes}:${seconds}`
if (date.getUTCHours()) {
timer = `${date.getUTCHours()}:${timer}`
}
return timer
}
/**
* Format a date to a usefull timestamp string for the gPodder API
* @param {Date} date The date
* @return {string}
*/
export const formatEpisodeTimestamp = (date: Date): string => {
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hours = date.getHours().toString().padStart(2, '0')
const mins = date.getMinutes().toString().padStart(2, '0')
const secs = date.getSeconds().toString().padStart(2, '0')
return `${year}-${month}-${day}T${hours}:${mins}:${secs}`
}
/**
* Format a date to a localized date string
* @param {Date} date The date
* @return {string}
*/
export const formatLocaleDate = (date: Date): string =>
date.toLocaleDateString(undefined, { dateStyle: 'medium' })
/**
* Returns the number of seconds from a duration feed's entry
* @param {string} duration The duration feed's entry
* @return {number}
*/
export const durationToSeconds = (duration: string): number => {
const splitDuration = duration.split(':').reverse()
let seconds = parseInt(splitDuration[0])
seconds += splitDuration.length > 1 ? parseInt(splitDuration[1]) * 60 : 0
seconds += splitDuration.length > 2 ? parseInt(splitDuration[2]) * 60 * 60 : 0
return seconds
}

14
src/utils/toast.ts Normal file
View File

@ -0,0 +1,14 @@
import toastify from 'toastify-js'
export const showMessage = (text: string, backgroundColor: string) =>
toastify({
text,
backgroundColor,
}).showToast()
export const showError = (text: string) => showMessage(text, 'var(--color-error)')
export const showWarning = (text: string) =>
showMessage(text, 'var(--color-warning)')
export const showInfo = (text: string) => showMessage(text, 'var(--color-primary)')
export const showSuccess = (text: string) =>
showMessage(text, 'var(--color-success)')

73
src/utils/types.ts Normal file
View File

@ -0,0 +1,73 @@
export interface EpisodeActionInterface {
podcast: string
episode: string
action: string
timestamp: string
started: number
position: number
total: number
guid?: string
id?: number
}
export interface EpisodeInterface {
title: string
url: string
name: string
link?: string
image?: string
description?: string
fetchedAtUnix: number
guid: string
type?: string
size?: number
pubDate?: {
date: string
timezone_type: number
timezone: string
}
duration?: string
action?: EpisodeActionInterface
}
export interface FiltersInterface {
listened: boolean
listening: boolean
unlistened: boolean
}
export interface PodcastDataInterface {
title: string
author?: string
link: string
description?: string
imageUrl?: string
fetchedAtUnix: number
imageBlob?: string | null
}
export interface PodcastMetricsInterface {
url: string
listenedSeconds: number
actionCounts: {
delete: number
download: number
flattr: number
new: number
play: number
}
}
export interface SubscriptionInterface {
data?: PodcastDataInterface
isFavorite: boolean
metrics: PodcastMetricsInterface
}
export interface PersonalSettingsMetricsInterface {
subscriptions: PodcastMetricsInterface[]
}
export interface PersonalSettingsPodcastDataInterface {
data: PodcastDataInterface
}

View File

@ -1,3 +0,0 @@
export const encodeUrl = (url) => encodeURIComponent(btoa(url))
export const decodeUrl = (url) => atob(decodeURIComponent(url))
export const toUrl = (url) => `/${encodeUrl(url)}`

Some files were not shown because too many files have changed in this diff Show More