@saooti/octopus-sdk 0.28.16 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/README.md +188 -2
  2. package/index.ts +45 -11
  3. package/package.json +46 -48
  4. package/public/config.ts +4 -0
  5. package/public/css/fonts/icomoon.eot +0 -0
  6. package/public/css/fonts/icomoon.svg +129 -0
  7. package/public/css/fonts/icomoon.ttf +0 -0
  8. package/public/css/fonts/icomoon.woff +0 -0
  9. package/public/css/fonts/style.css +185 -1266
  10. package/public/img/403.jpeg +0 -0
  11. package/public/img/404.svg +242 -0
  12. package/public/img/ouest_france_logo.svg +12 -0
  13. package/src/App.vue +45 -24
  14. package/src/api/classicCrud.ts +34 -0
  15. package/src/api/initialize.ts +4 -2
  16. package/src/assets/bootstrap-diff.scss +197 -0
  17. package/src/assets/form.scss +77 -77
  18. package/src/assets/general.scss +287 -301
  19. package/src/assets/live.scss +39 -0
  20. package/src/assets/modal.scss +43 -50
  21. package/src/assets/multiselect.scss +522 -590
  22. package/src/assets/octopus-library.scss +17 -4
  23. package/src/assets/share.scss +150 -250
  24. package/src/assets/transition.scss +98 -2
  25. package/src/components/display/aggregator/RssSection.vue +4 -6
  26. package/src/components/display/categories/CategoryChooser.vue +100 -79
  27. package/src/components/display/categories/CategoryFilter.vue +117 -37
  28. package/src/components/display/categories/CategoryList.vue +121 -108
  29. package/src/components/display/comments/AddCommentModal.vue +98 -94
  30. package/src/components/display/comments/CommentBasicView.vue +95 -0
  31. package/src/components/display/comments/CommentInput.vue +175 -155
  32. package/src/components/display/comments/CommentItem.vue +152 -168
  33. package/src/components/display/comments/CommentList.vue +123 -229
  34. package/src/components/display/comments/CommentParentInfo.vue +26 -58
  35. package/src/components/display/comments/CommentPlayer.vue +51 -49
  36. package/src/components/display/comments/CommentSection.vue +44 -67
  37. package/src/components/display/edit/EditBox.vue +11 -5
  38. package/src/components/display/edit/EditCommentBox.vue +121 -29
  39. package/src/components/display/emission/EmissionChooser.vue +73 -81
  40. package/src/components/display/emission/EmissionInlineList.vue +130 -128
  41. package/src/components/display/emission/EmissionItem.vue +68 -109
  42. package/src/components/display/emission/EmissionList.vue +140 -146
  43. package/src/components/display/emission/EmissionPlayerItem.vue +186 -148
  44. package/src/components/display/filter/AdvancedSearch.vue +192 -273
  45. package/src/components/display/filter/CategoryFilter.vue +51 -59
  46. package/src/components/display/filter/MonetizableFilter.vue +17 -16
  47. package/src/components/display/filter/ProductorSearch.vue +149 -149
  48. package/src/components/display/filter/RubriqueChoice.vue +33 -37
  49. package/src/components/display/filter/RubriqueFilter.vue +132 -122
  50. package/src/components/display/list/ListPaginate.vue +145 -0
  51. package/src/components/display/list/Paginate.vue +218 -0
  52. package/src/components/display/live/CountDown.vue +19 -12
  53. package/src/components/display/live/LiveHorizontalList.vue +78 -55
  54. package/src/components/display/live/LiveItem.vue +136 -121
  55. package/src/components/display/live/LiveList.vue +172 -276
  56. package/src/components/display/organisation/OrganisationChooser.vue +104 -122
  57. package/src/components/display/organisation/OrganisationChooserLight.vue +46 -37
  58. package/src/components/display/participant/ParticipantItem.vue +91 -115
  59. package/src/components/display/participant/ParticipantList.vue +131 -117
  60. package/src/components/display/playlist/PlaylistItem.vue +54 -78
  61. package/src/components/display/playlist/PlaylistList.vue +91 -83
  62. package/src/components/display/playlist/PodcastList.vue +113 -128
  63. package/src/components/display/playlist/PodcastPlaylistInlineList.vue +191 -0
  64. package/src/components/display/podcasts/AnimatorsItem.vue +28 -39
  65. package/src/components/display/podcasts/ParticipantDescription.vue +62 -74
  66. package/src/components/display/podcasts/PodcastFilterList.vue +47 -89
  67. package/src/components/display/podcasts/PodcastImage.vue +195 -229
  68. package/src/components/display/podcasts/PodcastInlineList.vue +64 -282
  69. package/src/components/display/podcasts/PodcastInlineListClassic.vue +240 -0
  70. package/src/components/display/podcasts/PodcastInlineListTemplate.vue +167 -0
  71. package/src/components/display/podcasts/PodcastItem.vue +93 -227
  72. package/src/components/display/podcasts/PodcastItemInfo.vue +166 -0
  73. package/src/components/display/podcasts/PodcastList.vue +115 -134
  74. package/src/components/display/podcasts/PodcastModuleBox.vue +234 -0
  75. package/src/components/display/podcasts/PodcastPlayBar.vue +101 -0
  76. package/src/components/display/podcasts/PodcastSwiperList.vue +204 -0
  77. package/src/components/display/podcasts/TagList.vue +60 -39
  78. package/src/components/display/rubriques/RubriqueChooser.vue +114 -95
  79. package/src/components/display/rubriques/RubriqueList.vue +111 -106
  80. package/src/components/display/sharing/PlayerParameters.vue +90 -151
  81. package/src/components/display/sharing/QrCode.vue +40 -27
  82. package/src/components/display/sharing/ShareButtons.vue +64 -299
  83. package/src/components/display/sharing/ShareButtonsIntern.vue +225 -0
  84. package/src/components/display/sharing/ShareDistribution.vue +99 -140
  85. package/src/components/display/sharing/SharePlayer.vue +155 -370
  86. package/src/components/display/sharing/SharePlayerColors.vue +78 -0
  87. package/src/components/display/sharing/SharePlayerTypes.vue +112 -0
  88. package/src/components/display/sharing/SplitButton.vue +42 -0
  89. package/src/components/display/sharing/SubscribeButtons.vue +62 -179
  90. package/src/components/display/studio/RecordingItemButton.vue +4 -6
  91. package/src/components/form/ClassicCheckbox.vue +66 -0
  92. package/src/components/form/ClassicLoading.vue +28 -0
  93. package/src/components/form/ClassicRadio.vue +66 -0
  94. package/src/components/form/ClassicSearch.vue +86 -0
  95. package/src/components/form/ClassicSelect.vue +65 -0
  96. package/src/components/misc/ErrorMessage.vue +27 -14
  97. package/src/components/misc/Footer.vue +132 -127
  98. package/src/components/misc/HomeDropdown.vue +93 -150
  99. package/src/components/misc/LeftMenu.vue +121 -192
  100. package/src/components/misc/Popover.vue +118 -0
  101. package/src/components/misc/Snackbar.vue +70 -35
  102. package/src/components/misc/TopBar.vue +192 -308
  103. package/src/components/misc/modal/ClipboardModal.vue +35 -50
  104. package/src/components/misc/modal/MessageModal.vue +71 -48
  105. package/src/components/misc/modal/NewsletterModal.vue +260 -231
  106. package/src/components/misc/modal/QrCodeModal.vue +42 -60
  107. package/src/components/misc/modal/ShareModalPlayer.vue +136 -70
  108. package/src/components/misc/player/Player.vue +146 -0
  109. package/src/components/misc/player/PlayerCompact.vue +154 -0
  110. package/src/components/misc/player/PlayerLarge.vue +166 -0
  111. package/src/components/misc/player/PlayerProgressBar.vue +112 -0
  112. package/src/components/misc/player/PlayerTimeline.vue +61 -0
  113. package/src/components/mixins/functions.ts +11 -43
  114. package/src/components/mixins/handle403.ts +17 -0
  115. package/src/components/mixins/init.ts +8 -6
  116. package/src/components/mixins/orgaComputed.ts +15 -0
  117. package/src/components/mixins/organisationFilter.ts +35 -18
  118. package/src/components/mixins/player/playerComment.ts +98 -0
  119. package/src/components/mixins/player/playerDisplay.ts +113 -0
  120. package/src/components/mixins/player/playerLive.ts +111 -0
  121. package/src/components/mixins/player/playerLogic.ts +225 -0
  122. package/src/components/mixins/tagOfMixins.ts +19 -0
  123. package/src/components/pages/Category.vue +21 -26
  124. package/src/components/pages/Emission.vue +136 -162
  125. package/src/components/pages/Emissions.vue +60 -93
  126. package/src/components/pages/Error403Page.vue +60 -0
  127. package/src/components/pages/Home.vue +32 -39
  128. package/src/components/pages/Lives.vue +40 -46
  129. package/src/components/pages/PageNotFound.vue +55 -0
  130. package/src/components/pages/Participant.vue +110 -113
  131. package/src/components/pages/Participants.vue +21 -45
  132. package/src/components/pages/Playlist.vue +84 -75
  133. package/src/components/pages/Playlists.vue +29 -47
  134. package/src/components/pages/Podcast.vue +203 -434
  135. package/src/components/pages/Podcasts.vue +75 -134
  136. package/src/components/pages/Rubrique.vue +21 -29
  137. package/src/components/pages/Search.vue +33 -79
  138. package/src/helper/dom.ts +1 -1
  139. package/src/helper/duration.ts +1 -1
  140. package/src/helper/useEventListener.ts +18 -0
  141. package/src/i18n.ts +36 -0
  142. package/src/locale/de.ts +309 -0
  143. package/src/locale/educationen.ts +1 -1
  144. package/src/locale/educationfr.ts +1 -1
  145. package/src/locale/en.ts +45 -28
  146. package/src/locale/es.ts +309 -0
  147. package/src/locale/fr.ts +25 -8
  148. package/src/locale/it.ts +307 -0
  149. package/src/locale/messages.ts +9 -2
  150. package/src/locale/sl.ts +309 -0
  151. package/src/main.ts +59 -85
  152. package/src/router/router.ts +60 -39
  153. package/src/sass/_variables.scss +10 -8
  154. package/src/shims-tsx.d.ts +2 -0
  155. package/src/shims-vue-recaptcha-v3.d.ts +9 -0
  156. package/src/shims-vue.d.ts +5 -4
  157. package/src/store/AppStore.ts +8 -9
  158. package/src/store/class/adserver/adserverConfig.ts +9 -0
  159. package/src/store/class/adserver/adserverOtherEmission.ts +13 -0
  160. package/src/store/class/adserver/adserverTiming.ts +10 -0
  161. package/src/store/class/cartouchier/cartouche.ts +15 -0
  162. package/src/store/class/cartouchier/cartouchier.ts +9 -0
  163. package/src/store/class/conference/conference.ts +35 -0
  164. package/src/store/class/conference/conferenceMessage.ts +10 -0
  165. package/src/store/class/conference/conferenceParticipant.ts +18 -0
  166. package/src/store/class/conference/pad.ts +15 -0
  167. package/src/store/class/conference/studioCall.ts +7 -0
  168. package/src/store/class/contract/contract.ts +7 -0
  169. package/src/store/class/contract/contractOrganisation.ts +7 -0
  170. package/src/store/class/ftp/ftpEmission.ts +41 -0
  171. package/src/store/class/ftp/ftpParam.ts +12 -0
  172. package/src/store/class/ftp/testFtpEmission.ts +5 -0
  173. package/src/store/class/general/audioView.ts +21 -0
  174. package/src/store/class/general/category.ts +10 -0
  175. package/src/store/class/general/comment.ts +16 -0
  176. package/src/store/class/general/customPlayer.ts +9 -0
  177. package/src/store/class/general/emission.ts +23 -0
  178. package/src/store/class/general/fetchParam.ts +3 -0
  179. package/src/store/class/general/initState.ts +25 -0
  180. package/src/store/class/general/interfacePageable.ts +16 -0
  181. package/src/store/class/general/ituneCategory.ts +5 -0
  182. package/src/store/class/general/media.ts +14 -0
  183. package/src/store/class/general/organisation.ts +20 -0
  184. package/src/store/class/general/pageable.ts +13 -0
  185. package/src/store/class/general/participant.ts +12 -0
  186. package/src/store/class/{player.ts → general/player.ts} +5 -3
  187. package/src/store/class/general/playlist.ts +13 -0
  188. package/src/store/class/general/podcast.ts +43 -0
  189. package/src/store/class/general/sortPageable.ts +5 -0
  190. package/src/store/class/general/soundcastCategory.ts +8 -0
  191. package/src/store/class/ouestFrance/ofTag.ts +36 -0
  192. package/src/store/class/ouestFrance/ofTagInfo.ts +9 -0
  193. package/src/store/class/ouestFrance/ofTagPage.ts +7 -0
  194. package/src/store/class/ouestFrance/ofTagSeo.ts +7 -0
  195. package/src/store/class/ouestFrance/ofTagVente.ts +6 -0
  196. package/src/store/class/ouestFrance/ofTagWithParents.ts +26 -0
  197. package/src/store/class/rss/aggregator.ts +28 -0
  198. package/src/store/class/rss/rssEmission.ts +14 -0
  199. package/src/store/class/rss/rssInfo.ts +8 -0
  200. package/src/store/class/rubrique/rubriquage.ts +10 -0
  201. package/src/store/class/rubrique/rubriquageFilter.ts +6 -0
  202. package/src/store/class/rubrique/rubrique.ts +9 -0
  203. package/src/store/class/stat/statArrayIncome.ts +6 -0
  204. package/src/store/class/stat/statArrayObject.ts +34 -0
  205. package/src/store/class/stat/statGraph.ts +7 -0
  206. package/src/store/class/user/person.ts +15 -0
  207. package/src/store/class/user/profile.ts +12 -0
  208. package/src/store/class/user/userKeycloak.ts +24 -0
  209. package/src/store/paramStore.ts +221 -241
  210. package/src/store/typeAppStore.ts +45 -28
  211. package/src/vuex-shim.d.ts +8 -0
  212. package/tsconfig.json +2 -1
  213. package/vue.config.js +3 -1
  214. package/public/css/fonts/saooti-ui.eot +0 -0
  215. package/public/css/fonts/saooti-ui.svg +0 -840
  216. package/public/css/fonts/saooti-ui.ttf +0 -0
  217. package/public/css/fonts/saooti-ui.woff +0 -0
  218. package/public/css/fonts/stitcher-logo.svg +0 -83
  219. package/public/img/article.png +0 -0
  220. package/src/api/comments.ts +0 -7
  221. package/src/api/emissions.ts +0 -7
  222. package/src/api/podcasts.ts +0 -7
  223. package/src/api/profile.ts +0 -8
  224. package/src/api/studio.ts +0 -8
  225. package/src/assets/bootstrap_scss/_alert.scss +0 -51
  226. package/src/assets/bootstrap_scss/_badge.scss +0 -54
  227. package/src/assets/bootstrap_scss/_breadcrumb.scss +0 -42
  228. package/src/assets/bootstrap_scss/_button-group.scss +0 -164
  229. package/src/assets/bootstrap_scss/_buttons.scss +0 -298
  230. package/src/assets/bootstrap_scss/_card.scss +0 -278
  231. package/src/assets/bootstrap_scss/_carousel.scss +0 -197
  232. package/src/assets/bootstrap_scss/_close.scss +0 -41
  233. package/src/assets/bootstrap_scss/_code.scss +0 -48
  234. package/src/assets/bootstrap_scss/_custom-forms.scss +0 -522
  235. package/src/assets/bootstrap_scss/_dropdown.scss +0 -201
  236. package/src/assets/bootstrap_scss/_forms.scss +0 -352
  237. package/src/assets/bootstrap_scss/_functions.scss +0 -134
  238. package/src/assets/bootstrap_scss/_grid.scss +0 -69
  239. package/src/assets/bootstrap_scss/_images.scss +0 -42
  240. package/src/assets/bootstrap_scss/_input-group.scss +0 -191
  241. package/src/assets/bootstrap_scss/_jumbotron.scss +0 -17
  242. package/src/assets/bootstrap_scss/_list-group.scss +0 -158
  243. package/src/assets/bootstrap_scss/_media.scss +0 -8
  244. package/src/assets/bootstrap_scss/_mixins.scss +0 -47
  245. package/src/assets/bootstrap_scss/_modal.scss +0 -243
  246. package/src/assets/bootstrap_scss/_nav.scss +0 -120
  247. package/src/assets/bootstrap_scss/_navbar.scss +0 -324
  248. package/src/assets/bootstrap_scss/_pagination.scss +0 -74
  249. package/src/assets/bootstrap_scss/_popover.scss +0 -170
  250. package/src/assets/bootstrap_scss/_print.scss +0 -141
  251. package/src/assets/bootstrap_scss/_progress.scss +0 -46
  252. package/src/assets/bootstrap_scss/_reboot.scss +0 -482
  253. package/src/assets/bootstrap_scss/_root.scss +0 -20
  254. package/src/assets/bootstrap_scss/_spinners.scss +0 -55
  255. package/src/assets/bootstrap_scss/_tables.scss +0 -185
  256. package/src/assets/bootstrap_scss/_toasts.scss +0 -44
  257. package/src/assets/bootstrap_scss/_tooltip.scss +0 -115
  258. package/src/assets/bootstrap_scss/_transitions.scss +0 -20
  259. package/src/assets/bootstrap_scss/_type.scss +0 -125
  260. package/src/assets/bootstrap_scss/_utilities.scss +0 -17
  261. package/src/assets/bootstrap_scss/_variables.scss +0 -1145
  262. package/src/assets/bootstrap_scss/bootstrap-grid.scss +0 -29
  263. package/src/assets/bootstrap_scss/bootstrap-reboot.scss +0 -12
  264. package/src/assets/bootstrap_scss/bootstrap.scss +0 -44
  265. package/src/assets/bootstrap_scss/mixins/_alert.scss +0 -13
  266. package/src/assets/bootstrap_scss/mixins/_background-variant.scss +0 -22
  267. package/src/assets/bootstrap_scss/mixins/_badge.scss +0 -17
  268. package/src/assets/bootstrap_scss/mixins/_border-radius.scss +0 -63
  269. package/src/assets/bootstrap_scss/mixins/_box-shadow.scss +0 -20
  270. package/src/assets/bootstrap_scss/mixins/_breakpoints.scss +0 -123
  271. package/src/assets/bootstrap_scss/mixins/_buttons.scss +0 -110
  272. package/src/assets/bootstrap_scss/mixins/_caret.scss +0 -62
  273. package/src/assets/bootstrap_scss/mixins/_clearfix.scss +0 -7
  274. package/src/assets/bootstrap_scss/mixins/_deprecate.scss +0 -10
  275. package/src/assets/bootstrap_scss/mixins/_float.scss +0 -14
  276. package/src/assets/bootstrap_scss/mixins/_forms.scss +0 -177
  277. package/src/assets/bootstrap_scss/mixins/_gradients.scss +0 -45
  278. package/src/assets/bootstrap_scss/mixins/_grid-framework.scss +0 -71
  279. package/src/assets/bootstrap_scss/mixins/_grid.scss +0 -69
  280. package/src/assets/bootstrap_scss/mixins/_hover.scss +0 -37
  281. package/src/assets/bootstrap_scss/mixins/_image.scss +0 -36
  282. package/src/assets/bootstrap_scss/mixins/_list-group.scss +0 -21
  283. package/src/assets/bootstrap_scss/mixins/_lists.scss +0 -7
  284. package/src/assets/bootstrap_scss/mixins/_nav-divider.scss +0 -11
  285. package/src/assets/bootstrap_scss/mixins/_pagination.scss +0 -22
  286. package/src/assets/bootstrap_scss/mixins/_reset-text.scss +0 -17
  287. package/src/assets/bootstrap_scss/mixins/_resize.scss +0 -6
  288. package/src/assets/bootstrap_scss/mixins/_screen-reader.scss +0 -34
  289. package/src/assets/bootstrap_scss/mixins/_size.scss +0 -7
  290. package/src/assets/bootstrap_scss/mixins/_table-row.scss +0 -39
  291. package/src/assets/bootstrap_scss/mixins/_text-emphasis.scss +0 -17
  292. package/src/assets/bootstrap_scss/mixins/_text-hide.scss +0 -11
  293. package/src/assets/bootstrap_scss/mixins/_text-truncate.scss +0 -8
  294. package/src/assets/bootstrap_scss/mixins/_transition.scss +0 -16
  295. package/src/assets/bootstrap_scss/mixins/_visibility.scss +0 -8
  296. package/src/assets/bootstrap_scss/utilities/_align.scss +0 -8
  297. package/src/assets/bootstrap_scss/utilities/_background.scss +0 -19
  298. package/src/assets/bootstrap_scss/utilities/_borders.scss +0 -75
  299. package/src/assets/bootstrap_scss/utilities/_clearfix.scss +0 -3
  300. package/src/assets/bootstrap_scss/utilities/_display.scss +0 -26
  301. package/src/assets/bootstrap_scss/utilities/_embed.scss +0 -39
  302. package/src/assets/bootstrap_scss/utilities/_flex.scss +0 -51
  303. package/src/assets/bootstrap_scss/utilities/_float.scss +0 -11
  304. package/src/assets/bootstrap_scss/utilities/_overflow.scss +0 -5
  305. package/src/assets/bootstrap_scss/utilities/_position.scss +0 -32
  306. package/src/assets/bootstrap_scss/utilities/_screenreaders.scss +0 -11
  307. package/src/assets/bootstrap_scss/utilities/_shadows.scss +0 -6
  308. package/src/assets/bootstrap_scss/utilities/_sizing.scss +0 -20
  309. package/src/assets/bootstrap_scss/utilities/_spacing.scss +0 -73
  310. package/src/assets/bootstrap_scss/utilities/_stretched-link.scss +0 -19
  311. package/src/assets/bootstrap_scss/utilities/_text.scss +0 -72
  312. package/src/assets/bootstrap_scss/utilities/_visibility.scss +0 -13
  313. package/src/assets/bootstrap_scss/vendor/_rfs.scss +0 -204
  314. package/src/components/misc/Player.vue +0 -772
  315. package/src/store/class/category.ts +0 -8
  316. package/src/store/class/comment.ts +0 -17
  317. package/src/store/class/conference.ts +0 -27
  318. package/src/store/class/customPlayer.ts +0 -8
  319. package/src/store/class/emission.ts +0 -20
  320. package/src/store/class/media.ts +0 -13
  321. package/src/store/class/organisation.ts +0 -19
  322. package/src/store/class/participant.ts +0 -12
  323. package/src/store/class/person.ts +0 -13
  324. package/src/store/class/playlist.ts +0 -15
  325. package/src/store/class/podcast.ts +0 -37
  326. package/src/store/class/rubriquage.ts +0 -9
  327. package/src/store/class/rubriquageFilter.ts +0 -5
  328. package/src/store/class/rubrique.ts +0 -8
@@ -1,144 +1,142 @@
1
1
  <template>
2
- <div class="d-flex flex-column align-items-center">
3
- <div class="d-flex justify-content-center" v-if="loading">
4
- <div class="spinner-border mr-3"></div>
5
- <h3 class="mt-2">{{ $t('Loading podcasts ...') }}</h3>
6
- </div>
7
- <div v-if="loaded && !podcasts.length">
8
- <p>{{ $t('No podcast match your query') }}</p>
9
- </div>
10
- <div
11
- v-if="showCount && loaded && podcasts.length > 1"
12
- class="text-secondary mb-2"
13
- >
14
- {{ $t('Number podcasts', { nb: totalCount }) + sortText }}
15
- </div>
16
- <ul class="podcast-list" v-show="loaded">
17
- <PodcastItem
18
- v-bind:podcast="p"
19
- v-for="p in podcasts"
20
- v-bind:key="p.podcastId"
21
- />
22
- </ul>
23
- <button
24
- class="btn"
25
- :class="buttonPlus ? 'btn-linkPlus mt-3' : 'btn-more'"
26
- @click="displayMore"
27
- :disabled="inFetching"
28
- v-show="!allFetched && loaded"
29
- :aria-label="$t('See more')"
30
- >
31
- <template v-if="buttonPlus">{{ $t('See more') }}</template>
32
- <div class="saooti-plus"></div>
33
- </button>
34
- </div>
2
+ <ListPaginate
3
+ id="podcastListPaginate"
4
+ v-model:first="dfirst"
5
+ v-model:rowsPerPage="dsize"
6
+ v-model:isMobile="isMobile"
7
+ :text-count="showCount && podcasts.length > 1 ? $t('Number podcasts', { nb: totalCount }) + sortText : undefined"
8
+ :total-count="totalCount"
9
+ :loading="loading"
10
+ :loading-text="loading?$t('Loading podcasts ...'):undefined"
11
+ :error-text="!loading && !podcasts.length?$t(`No podcast match your query`):undefined"
12
+ >
13
+ <template #list>
14
+ <ul
15
+ class="podcast-list"
16
+ >
17
+ <template
18
+ v-for="p in displayArray"
19
+ :key="p.podcastId"
20
+ >
21
+ <PodcastItem
22
+ v-if="0!==p.podcastId"
23
+ :podcast="p"
24
+ />
25
+ </template>
26
+ </ul>
27
+ </template>
28
+ </ListPaginate>
35
29
  </template>
36
30
 
37
- <style lang="scss"></style>
38
-
39
31
  <script lang="ts">
40
- const octopusApi = require('@saooti/octopus-api');
41
- import podcastApi from '@/api/podcasts';
32
+ import ListPaginate from '../list/ListPaginate.vue';
33
+ import { handle403 } from '../../mixins/handle403';
34
+ import octopusApi from '@saooti/octopus-api';
42
35
  import PodcastItem from './PodcastItem.vue';
43
36
  import { state } from '../../../store/paramStore';
44
-
45
- import Vue from 'vue';
46
- import { Podcast } from '@/store/class/podcast';
47
- export default Vue.extend({
37
+ import { Podcast } from '@/store/class/general/podcast';
38
+ import { defineComponent } from 'vue'
39
+ import { FetchParam } from '@/store/class/general/fetchParam';
40
+ import { AxiosError } from 'axios';
41
+ import { emptyPodcastData } from '@/store/typeAppStore';
42
+ export default defineComponent({
48
43
  name: 'PodcastList',
49
44
 
50
45
  components: {
51
46
  PodcastItem,
47
+ ListPaginate
52
48
  },
53
49
 
50
+ mixins: [handle403],
51
+
54
52
  props: {
55
- first: { default: 0 as number},
56
- size: { default: 12 as number },
57
- organisationId: { default: undefined as string | undefined },
58
- emissionId: { default: undefined as number | undefined },
59
- iabId: { default: undefined as number | undefined },
60
- participantId: { default: undefined as number | undefined },
61
- query: { default: undefined as string | undefined },
62
- monetization: { default: undefined as string | undefined },
63
- popularSort: { default: false as boolean },
64
- reload: { default: false as boolean },
65
- before: { default: undefined as string | undefined },
66
- after: { default: undefined as string | undefined },
67
- includeHidden: { default: false as boolean},
68
- showCount: { default: false as boolean },
69
- sortCriteria: { default: undefined as string | undefined },
70
- notValid: { default: undefined as boolean | undefined },
71
- rubriqueId: { default: () => ([]) as Array<number> },
72
- rubriquageId:{ default: () => ([]) as Array<number> },
73
- noRubriquageId: { default: () => ([]) as Array<number> },
53
+ first: { default: 0, type: Number},
54
+ size: { default: 30, type: Number},
55
+ organisationId: { default: undefined, type: String},
56
+ emissionId: { default: undefined, type: Number},
57
+ iabId: { default: undefined, type: Number},
58
+ participantId: { default: undefined, type: Number},
59
+ query: { default: undefined, type: String},
60
+ monetization: { default: undefined, type: String},
61
+ popularSort: { default: false, type: Boolean},
62
+ reload: { default: false, type: Boolean},
63
+ before: { default: undefined, type: String},
64
+ after: { default: undefined, type: String},
65
+ includeHidden: { default: false, type: Boolean},
66
+ showCount: { default: false, type: Boolean },
67
+ sortCriteria: { default: undefined, type: String},
68
+ notValid: { default: undefined , type: Boolean},
69
+ rubriqueId: { default: () => [], type: Array as ()=>Array<number> },
70
+ rubriquageId:{ default: () => [], type: Array as ()=>Array<number> },
71
+ noRubriquageId: { default: () => [], type: Array as ()=>Array<number> },
74
72
  },
73
+ emits: ['fetch', 'emptyList'],
75
74
 
76
75
  data() {
77
76
  return {
78
77
  loading: true as boolean,
79
- loaded: false as boolean,
80
78
  dfirst: this.first as number,
81
79
  dsize: this.size as number,
82
80
  totalCount: 0 as number,
83
81
  podcasts: [] as Array<Podcast>,
84
- inFetching: false as boolean,
82
+ isMobile: false as boolean,
85
83
  };
86
84
  },
87
-
88
- created() {
89
- this.fetchContent(true);
90
- },
91
-
85
+
92
86
  computed: {
93
- allFetched(): boolean {
94
- return this.dfirst >= this.totalCount;
95
- },
96
- buttonPlus(): boolean {
97
- return state.generalParameters.buttonPlus;
98
- },
87
+ displayArray(): Array<Podcast>{
88
+ if(this.isMobile){
89
+ return this.podcasts;
90
+ }
91
+ return this.podcasts.slice(this.dfirst, Math.min(this.dfirst + this.dsize,this.totalCount));
92
+ },
99
93
  changed(): string {
100
94
  return `${this.first}|${this.size}|${this.organisation}|${this.emissionId}|${this.sortCriteria}|${this.sort}
101
95
  ${this.iabId}|${this.participantId}|${this.query}|${this.monetization}|${this.popularSort}|
102
96
  ${this.rubriqueId}|${this.rubriquageId}|${this.before}|${this.after}|${this.includeHidden}|${this.noRubriquageId}|${this.notValid}`;
103
97
  },
104
- filterOrga(): string {
105
- return this.$store.state.filter.organisationId;
106
- },
107
98
  organisation(): string|undefined {
108
- if (this.organisationId) return this.organisationId;
109
- if (this.filterOrga) return this.filterOrga;
110
- return undefined;
99
+ return this.organisationId ?? this.$store.state.filter.organisationId;
111
100
  },
112
101
  sort(): string {
113
- if (this.popularSort) return 'POPULARITY';
114
- return this.sortCriteria;
102
+ return this.popularSort? "POPULARITY" : this.sortCriteria??'DATE';
115
103
  },
116
104
  sortText(): string {
117
105
  switch (this.sortCriteria) {
118
- case 'SCORE':
119
- return this.$t('sort by score').toString();
120
- case 'DATE':
121
- return this.$t('sort by date').toString();
122
- case 'NAME':
123
- return this.$t('sort by alphabetical').toString();
124
- default:
125
- return this.$t('sort by date').toString();
106
+ case 'SCORE':return " "+this.$t('sort by score');
107
+ case 'DATE':return " "+this.$t('sort by date');
108
+ case 'NAME':return " "+this.$t('sort by alphabetical');
109
+ default:return " "+this.$t('sort by date');
126
110
  }
127
111
  },
128
- isProduction(): boolean {
129
- return state.generalParameters.isProduction;
112
+ },
113
+ watch: {
114
+ changed(): void {
115
+ this.reloadList();
116
+ },
117
+ reload(): void {
118
+ this.reloadList();
130
119
  },
120
+ dsize():void{
121
+ this.reloadList();
122
+ },
123
+ dfirst(): void{
124
+ if(!this.podcasts[this.dfirst] || 0===this.podcasts[this.dfirst].podcastId){
125
+ this.fetchContent(false);
126
+ }
127
+ },
128
+ },
129
+ async created() {
130
+ await this.fetchContent(true);
131
131
  },
132
132
  methods: {
133
+ reloadList(){
134
+ this.dfirst = 0;
135
+ this.fetchContent(true);
136
+ },
133
137
  async fetchContent(reset: boolean): Promise<void> {
134
- this.inFetching = true;
135
- if (reset) {
136
- this.podcasts.length = 0;
137
- this.dfirst = 0;
138
- this.loading = true;
139
- this.loaded = false;
140
- }
141
- const param: any = {
138
+ this.loading = true;
139
+ const param: FetchParam = {
142
140
  first: this.dfirst,
143
141
  size: this.dsize,
144
142
  organisationId: this.organisation,
@@ -153,54 +151,37 @@ export default Vue.extend({
153
151
  noRubriquageId: this.noRubriquageId.length ? this.noRubriquageId : undefined,
154
152
  rubriqueId: this.rubriqueId.length ? this.rubriqueId : undefined,
155
153
  rubriquageId: this.rubriquageId.length ? this.rubriquageId : undefined,
154
+ includeHidden: this.includeHidden,
155
+ validity: undefined !== this.notValid?!this.notValid: undefined,
156
+ publisherId:this.notValid && !(state.generalParameters.isProduction as boolean)?this.$store.state.profile.userId:undefined
156
157
  };
157
- if (undefined !== this.notValid) {
158
- param.validity = !this.notValid;
159
- }
160
- if (this.notValid && !this.isProduction) {
161
- param.publisherId = this.$store.state.profile.userId;
162
- }
163
- if (this.includeHidden) {
164
- param.includeHidden = this.includeHidden;
165
- const data = await podcastApi.fetchPodcastsAdmin(this.$store.state, param);
166
- this.afterFetching(reset, data);
167
- } else {
168
- const data = await octopusApi.fetchPodcasts(param);
158
+ try {
159
+ const data =await octopusApi.fetchDataWithParams<{count: number;result:Array<Podcast>;sort: string;}>(0, 'podcast/search',param, true);
169
160
  this.afterFetching(reset, data);
161
+ } catch (error) {
162
+ this.handle403((error as AxiosError));
170
163
  }
171
164
  },
172
- afterFetching(reset: boolean, data: any): void {
165
+ afterFetching(reset: boolean, data: {count: number, result: Array<Podcast>, sort: string}): void {
173
166
  if (reset) {
174
167
  this.podcasts.length = 0;
175
- this.dfirst = 0;
176
- this.loading = true;
177
- this.loaded = false;
178
168
  }
179
- this.loading = false;
180
- this.loaded = true;
181
- this.podcasts = this.podcasts.concat(data.result).filter((p: Podcast|null) => {
169
+ if(this.dfirst > this.podcasts.length){
170
+ for (let i = this.podcasts.length-1, len = this.dfirst + this.dsize; i < len; i++) {
171
+ this.podcasts.push(emptyPodcastData());
172
+ }
173
+ }
174
+ const responsePodcasts= data.result.filter((p: Podcast|null) => {
182
175
  return null !== p;
183
176
  });
177
+ this.podcasts = this.podcasts.slice(0, this.dfirst).concat(responsePodcasts).concat(this.podcasts.slice(this.dfirst+this.dsize, this.podcasts.length));
184
178
  this.$emit('fetch', this.podcasts);
185
- this.dfirst += this.dsize;
186
179
  this.totalCount = data.count;
187
180
  if (0 === this.podcasts.length) {
188
181
  this.$emit('emptyList');
189
182
  }
190
- this.inFetching = false;
191
- },
192
- displayMore(event: { preventDefault: () => void }): void {
193
- event.preventDefault();
194
- this.fetchContent(false);
195
- },
196
- },
197
- watch: {
198
- changed(): void {
199
- this.fetchContent(true);
200
- },
201
- reload(): void {
202
- this.fetchContent(true);
183
+ this.loading = false;
203
184
  },
204
185
  },
205
- });
206
- </script>
186
+ })
187
+ </script>
@@ -0,0 +1,234 @@
1
+ <template>
2
+ <div class="module-box">
3
+ <div
4
+ class="text-uppercase h4"
5
+ >
6
+ {{ podcast.title }}
7
+ </div>
8
+ <div class="mb-5 mt-3 d-flex">
9
+ <div class="w-100">
10
+ <PodcastImage
11
+ :class="[
12
+ !isLiveReadyToRecord
13
+ ? 'shadow-element'
14
+ : '',
15
+ isLiveReadyToRecord &&
16
+ fetchConference &&
17
+ 'null' !== fetchConference &&
18
+ fetchConference.status
19
+ ? fetchConference.status.toLowerCase() + '-shadow'
20
+ : '',
21
+ ]"
22
+ class="me-3"
23
+ :podcast="podcast"
24
+ :hide-play="!isLiveReadyToRecord"
25
+ :playing-podcast="playingPodcast"
26
+ :fetch-conference="fetchConference"
27
+ :is-animator-live="isOctopusAndAnimator"
28
+ @playPodcast="playPodcast"
29
+ />
30
+ <div
31
+ class="d-flex flex-wrap mb-3"
32
+ :class="isLiveReady ? 'justify-content-between' : ''"
33
+ >
34
+ <div
35
+ v-if="0 !== date.length"
36
+ :class="!isLiveReady ? 'me-5' : ''"
37
+ >
38
+ {{ date }}
39
+ </div>
40
+ <div>
41
+ {{ $t('Duration', { duration: duration }) }}
42
+ </div>
43
+ <div
44
+ v-if="isLiveReady"
45
+ class="text-danger"
46
+ >
47
+ {{ $t('Episode record in live') }}
48
+ </div>
49
+ </div>
50
+ <!-- eslint-disable vue/no-v-html -->
51
+ <div
52
+ class="descriptionText html-wysiwyg-content"
53
+ v-html="urlify(podcast.description)"
54
+ />
55
+ <!-- eslint-enable -->
56
+ <div class="my-3">
57
+ <ParticipantDescription :participants="podcast.animators" />
58
+ <div>
59
+ {{ $t('Emission') + ' : ' }}
60
+ <router-link
61
+ class="fw-bold"
62
+ :to="{
63
+ name: 'emission',
64
+ params: { emissionId: podcast.emission.emissionId },
65
+ query: {
66
+ productor: filterOrga,
67
+ },
68
+ }"
69
+ >
70
+ {{ podcast.emission.name }}
71
+ </router-link>
72
+ </div>
73
+ <div v-if="!isPodcastmaker">
74
+ {{ $t('Producted by : ') }}
75
+ <router-link
76
+ class="fw-bold"
77
+ :to="{
78
+ name: 'productor',
79
+ params: { productorId: podcast.organisation.id },
80
+ query: {
81
+ productor: filterOrga,
82
+ },
83
+ }"
84
+ >
85
+ {{ podcast.organisation.name }}
86
+ </router-link>
87
+ </div>
88
+ <a
89
+ v-if="podcast.article"
90
+ class="btn d-flex align-items-center my-2 width-fit-content"
91
+ :href="podcast.article"
92
+ rel="noopener"
93
+ target="_blank"
94
+ >
95
+ <span class="saooti-newspaper me-1" />
96
+ <div>{{ $t('See associated article') }}</div>
97
+ </a>
98
+ <ParticipantDescription
99
+ :participants="podcast.guests"
100
+ :is-guest="true"
101
+ />
102
+ <PodcastPlayBar
103
+ :podcast="podcast"
104
+ />
105
+ <div v-if="editRight && !isPodcastmaker">
106
+ <div
107
+ v-if="podcast.annotations && podcast.annotations.RSS"
108
+ class="me-5"
109
+ >
110
+ {{ $t('From RSS') }}
111
+ </div>
112
+ <ErrorMessage
113
+ v-if="''!==errorMessage"
114
+ :message="errorMessage"
115
+ />
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ <TagList
121
+ :tag-list="podcast.tags"
122
+ />
123
+ </div>
124
+ </template>
125
+
126
+ <script lang="ts">
127
+ import PodcastPlayBar from './PodcastPlayBar.vue';
128
+ import PodcastImage from './PodcastImage.vue';
129
+ import ParticipantDescription from './ParticipantDescription.vue';
130
+ import TagList from './TagList.vue';
131
+ import { state } from '../../../store/paramStore';
132
+ import moment from 'moment';
133
+ // @ts-ignore
134
+ import humanizeDuration from 'humanize-duration';
135
+ import { displayMethods } from '../../mixins/functions';
136
+ import { orgaComputed } from '../../mixins/orgaComputed';
137
+ import { Podcast } from '@/store/class/general/podcast';
138
+ import { Conference } from '@/store/class/conference/conference';
139
+
140
+ import { defineComponent, defineAsyncComponent } from 'vue';
141
+ const ErrorMessage = defineAsyncComponent(() => import('../../misc/ErrorMessage.vue'));
142
+ export default defineComponent({
143
+ name: "PodcastModuleBox",
144
+ components: {
145
+ PodcastImage,
146
+ ParticipantDescription,
147
+ TagList,
148
+ ErrorMessage,
149
+ PodcastPlayBar
150
+ },
151
+
152
+ mixins:[displayMethods, orgaComputed],
153
+
154
+ props: {
155
+ playingPodcast: { default: undefined, type: Object as ()=> Podcast},
156
+ podcast: { default: undefined, type: Object as ()=> Podcast},
157
+ fetchConference: { default: undefined, type: Object as ()=> Conference},
158
+ },
159
+
160
+ emits: ['playPodcast'],
161
+
162
+ computed: {
163
+ errorMessage(): string{
164
+ if(!this.podcast?.availability.visibility){
165
+ return this.$t('Podcast is not visible for listeners');
166
+ }
167
+ if('ERROR' === this.podcast?.processingStatus){
168
+ return this.$t('Podcast in ERROR, please contact Saooti');
169
+ }
170
+ return this.podcastNotValid ? this.$t('Podcast not validated') : '';
171
+ },
172
+ isPodcastmaker(): boolean {
173
+ return (state.generalParameters.podcastmaker as boolean);
174
+ },
175
+ date(): string {
176
+ if (this.podcast && 1970 !== moment(this.podcast.pubDate).year()){
177
+ return moment(this.podcast.pubDate).format('D MMMM YYYY, HH[h]mm');
178
+ }
179
+ return '';
180
+ },
181
+ duration(): string {
182
+ if (!this.podcast || this.podcast.duration <= 1) return '';
183
+ if (this.podcast.duration > 600000) {
184
+ return humanizeDuration(this.podcast.duration, {
185
+ language: this.$i18n.locale,
186
+ largest: 1,
187
+ round: true,
188
+ });
189
+ }
190
+ return humanizeDuration(this.podcast.duration, {
191
+ language: this.$i18n.locale,
192
+ largest: 2,
193
+ round: true,
194
+ });
195
+ },
196
+ editRight(): boolean {
197
+ return (true===this.authenticated &&
198
+ this.myOrganisationId === this.podcast?.organisation.id) ||true===state.generalParameters.isAdmin
199
+ },
200
+ isLiveReadyToRecord(): boolean {
201
+ return (undefined!==this.podcast && undefined!==this.podcast.conferenceId && 0 !== this.podcast.conferenceId && 'READY_TO_RECORD' === this.podcast.processingStatus);
202
+ },
203
+ isLiveReady(): boolean {
204
+ return (
205
+ undefined!==this.podcast?.conferenceId &&
206
+ 0 !== this.podcast?.conferenceId &&
207
+ 'READY' === this.podcast?.processingStatus
208
+ );
209
+ },
210
+ isNotRecorded(): boolean {
211
+ return (
212
+ this.isLiveReadyToRecord &&
213
+ undefined!==this.fetchConference &&
214
+ 'DEBRIEFING' === this.fetchConference.status
215
+ );
216
+ },
217
+ isOctopusAndAnimator(): boolean {
218
+ return (
219
+ !this.isPodcastmaker &&
220
+ this.editRight &&
221
+ (state.generalParameters.isRoleLive as boolean)
222
+ );
223
+ },
224
+ podcastNotValid(): boolean {
225
+ return undefined!==this.podcast?.availability && false === this.podcast?.valid;
226
+ },
227
+ },
228
+ methods: {
229
+ playPodcast(podcast: Podcast): void {
230
+ this.$emit('playPodcast', podcast);
231
+ },
232
+ },
233
+ })
234
+ </script>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div
3
+ v-if="isProgressBar"
4
+ class="d-flex align-items-center podcast-play-bar"
5
+ >
6
+ <div class="me-2">
7
+ {{ playedTime }}
8
+ </div>
9
+ <div class="position-relative flex-grow-1">
10
+ <div
11
+ class="progress flex-grow-1 c-hand"
12
+ @mouseup="seekTo"
13
+ >
14
+ <div
15
+ class="progress-bar primary-bg"
16
+ role="progressbar"
17
+ aria-valuenow="0"
18
+ aria-valuemin="0"
19
+ aria-valuemax="100"
20
+ :style="'width: ' + percentProgress + '%'"
21
+ />
22
+ <div
23
+ class="progress-bar-cursor"
24
+ :style="'left:' + percentProgress + '%'"
25
+ />
26
+ </div>
27
+ </div>
28
+ <div class="ms-2">
29
+ {{ totalTime }}
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <script lang="ts">
35
+ import DurationHelper from '../../../helper/duration';
36
+ import { displayMethods } from '../../mixins/functions';
37
+ import { state } from '../../../store/paramStore';
38
+ import { defineComponent } from 'vue'
39
+ export default defineComponent({
40
+ name: 'PodcastPlayBar',
41
+ mixins: [displayMethods],
42
+ props: {
43
+ podcastId: { default: undefined, type: Number},
44
+ duration: { default: 0, type: Number},
45
+ },
46
+ computed: {
47
+ isProgressBar(): boolean{
48
+ return (state.emissionsPage.progressBar as boolean);
49
+ },
50
+ percentProgress(): number{
51
+ if(this.podcastId !== this.$store.state.player.podcast?.podcastId){
52
+ return 0;
53
+ }
54
+ return !this.$store.state.player.elapsed ? 0 : this.$store.state.player.elapsed * 100;
55
+ },
56
+ playedTime(): string{
57
+ if(this.podcastId === this.$store.state.player.podcast?.podcastId){
58
+ if (this.$store.state.player.elapsed && this.$store.state.player.elapsed > 0 && this.$store.state.player.total && this.$store.state.player.total > 0) {
59
+ return DurationHelper.formatDuration(
60
+ Math.round(this.$store.state.player.elapsed * this.$store.state.player.total)
61
+ );
62
+ }
63
+ }
64
+ return '00:00';
65
+ },
66
+ totalTime(): string {
67
+ return DurationHelper.formatDuration(Math.round(this.duration/1000));
68
+ },
69
+ },
70
+ methods: {
71
+ seekTo(event: MouseEvent): void {
72
+ if(!this.$store.state.player.podcast || this.podcastId !== this.$store.state.player.podcast.podcastId){return;}
73
+ const rect = (event.currentTarget as Element).getBoundingClientRect();
74
+ const barWidth = (event.currentTarget as Element).clientWidth;
75
+ const x = event.clientX - rect.left;
76
+ const percentPosition = x / barWidth;
77
+ if (percentPosition * 100 >= this.percentLiveProgress) return;
78
+ const seekTime = this.$store.state.player.total * percentPosition;
79
+ this.$store.commit("playerSeekTime", seekTime);
80
+ }
81
+ },
82
+ })
83
+ </script>
84
+
85
+ <style lang="scss">
86
+ .octopus-app{
87
+ .podcast-play-bar {
88
+ .progress{
89
+ height: 6px;
90
+ }
91
+ .progress-bar-cursor{
92
+ width: 10px;
93
+ height: 10px;
94
+ border-radius: 50%;
95
+ background: black;
96
+ align-self: center;
97
+ position: absolute;
98
+ }
99
+ }
100
+ }
101
+ </style>