@saooti/octopus-sdk 30.0.85 → 30.0.88

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.
package/README.md CHANGED
@@ -581,4 +581,7 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
581
581
  * 30.0.82 Cherry pick Color Qr code
582
582
  * 30.0.83 Locales parlement
583
583
  * 30.0.84 Une émission non visible n'apparaît pas dans la page émission
584
- * 30.0.85 PB en cliquant sur le bouton "tous les épisodes de l'organisation" dans la page d'un épisode
584
+ * 30.0.85 PB en cliquant sur le bouton "tous les épisodes de l'organisation" dans la page d'un épisode
585
+ * 30.0.86 Podcastmaker newest
586
+ * 30.0.87 Podcastmaker newest (swiper list)
587
+ * 30.0.88 Podcastmaker newest (swiper list)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "30.0.85",
3
+ "version": "30.0.88",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
@@ -31,6 +31,7 @@
31
31
  "qrcode.vue": "^3.3.3",
32
32
  "sass": "^1.43.4",
33
33
  "sass-loader": "^12.3.0",
34
+ "swiper": "^8.1.5",
34
35
  "v-calendar": "3.0.0-alpha.6",
35
36
  "vue": "^3.2.21",
36
37
  "vue-i18n": "^9.2.0-beta.17",
@@ -233,6 +233,9 @@ export default defineComponent({
233
233
  'PENDING' === this.fetchConference.status)
234
234
  );
235
235
  },
236
+ clickPlayGoPage():boolean{
237
+ return (state.podcastPage.clickPlayGoPage as boolean);
238
+ },
236
239
  },
237
240
  watch: {
238
241
  arrowDirection(): void {
@@ -261,16 +264,19 @@ export default defineComponent({
261
264
  }
262
265
  if (!this.recordingLive) {
263
266
  this.$store.commit('playerPlayPodcast', this.podcast);
264
- return;
267
+ }else{
268
+ this.$store.commit('playerPlayPodcast', {
269
+ title: this.podcast.title,
270
+ audioUrl: this.podcast.audioUrl,
271
+ duration: this.podcast.duration,
272
+ conferenceId: this.fetchConference ? this.fetchConference.conferenceId : undefined,
273
+ livePodcastId: this.podcast.podcastId,
274
+ organisation: this.podcast.organisation,
275
+ });
276
+ }
277
+ if(this.clickPlayGoPage){
278
+ this.$router.push('/main/pub/podcast/'+this.podcast.podcastId);
265
279
  }
266
- this.$store.commit('playerPlayPodcast', {
267
- title: this.podcast.title,
268
- audioUrl: this.podcast.audioUrl,
269
- duration: this.podcast.duration,
270
- conferenceId: this.fetchConference ? this.fetchConference.conferenceId : undefined,
271
- livePodcastId: this.podcast.podcastId,
272
- organisation: this.podcast.organisation,
273
- });
274
280
  },
275
281
  showDescription(): void {
276
282
  if (this.isDescription) {
@@ -1,102 +1,51 @@
1
1
  <template>
2
- <div
3
- v-if="loading || (!loading && 0 !== allPodcasts.length)"
4
- class="d-flex flex-column p-3"
5
- >
6
- <h2>{{ title }}</h2>
7
- <div class="d-flex justify-content-between">
8
- <div class="d-flex">
9
- <button
10
- class="btn btn-underline"
11
- :class="{ active: !popularSort }"
12
- @click="sortChrono()"
13
- >
14
- {{ $t('Last added') }}
15
- </button>
16
- <button
17
- class="btn btn-underline"
18
- :class="{ active: popularSort }"
19
- @click="sortPopular()"
20
- >
21
- {{ $t('Most popular') }}
22
- </button>
23
- </div>
24
- <div
25
- v-if="!isArrow && !overflowScroll"
26
- class="hide-phone"
27
- >
28
- <button
29
- class="btn admin-button m-1"
30
- :class="{ disabled: !previousAvailable }"
31
- :title="$t('Display previous')"
32
- @click="displayPrevious()"
33
- >
34
- <div class="saooti-left fw-bold" />
35
- </button>
36
- <button
37
- class="btn admin-button m-1"
38
- :class="{ disabled: !nextAvailable }"
39
- :title="$t('Display next')"
40
- @click="displayNext()"
41
- >
42
- <div class="saooti-right fw-bold" />
43
- </button>
44
- </div>
45
- </div>
46
- <ClassicLoading
47
- :loading-text="loading?$t('Loading podcasts ...'):undefined"
48
- />
49
- <transition-group
50
- v-show="loaded"
51
- :name="transitionName"
52
- class="element-list-inline"
53
- tag="ul"
54
- :class="[
55
- alignLeft ? 'justify-content-start' : '',
56
- overflowScroll ? 'overflowScroll' : '',
57
- ]"
58
- :css="isInlineAnimation"
59
- >
60
- <PodcastItem
61
- v-for="p in podcasts"
62
- :key="p.podcastId"
63
- class="flex-shrink-0 item-phone-margin"
64
- :podcast="p"
65
- :class="[alignLeft ? 'me-3' : '']"
66
- />
67
- </transition-group>
68
- <router-link
69
- class="btn btn-link align-self-center width-fit-content m-4"
70
- :to="refTo"
71
- @click="handleSeeMoreButton"
72
- >
73
- {{ buttonText }}
74
- <div
75
- v-if="buttonPlus"
76
- class="ms-1 saooti-more"
77
- />
78
- </router-link>
79
- </div>
2
+ <PodcastInlineListClassic
3
+ v-if="listTypeClassic"
4
+ :organisation-id="organisationId"
5
+ :emission-id="emissionId"
6
+ :iab-id="iabId"
7
+ :title="title"
8
+ :href="href"
9
+ :button-text="buttonText"
10
+ :is-arrow="isArrow"
11
+ :require-popular-sort="requirePopularSort"
12
+ :button-plus="buttonPlus"
13
+ :rubrique-id="rubriqueId"
14
+ :rubriquage-id="rubriquageId"
15
+ :no-rubriquage-id="noRubriquageId"
16
+ :query="query"
17
+ @update:isArrow="$emit('update:isArrow',$event)"
18
+ />
19
+ <PodcastSwiperList
20
+ v-else
21
+ :organisation-id="organisationId"
22
+ :emission-id="emissionId"
23
+ :iab-id="iabId"
24
+ :title="title"
25
+ :href="href"
26
+ :button-text="buttonText"
27
+ :is-arrow="isArrow"
28
+ :require-popular-sort="requirePopularSort"
29
+ :button-plus="buttonPlus"
30
+ :rubrique-id="rubriqueId"
31
+ :rubriquage-id="rubriquageId"
32
+ :no-rubriquage-id="noRubriquageId"
33
+ :query="query"
34
+ @update:isArrow="$emit('update:isArrow',$event)"
35
+ />
80
36
  </template>
81
37
 
82
38
  <script lang="ts">
83
- import octopusApi from '@saooti/octopus-api';
84
- import domHelper from '../../../helper/dom';
85
- import PodcastItem from './PodcastItem.vue';
86
- import ClassicLoading from '../../form/ClassicLoading.vue';
87
- const PHONE_WIDTH = 960;
88
39
  import { state } from '../../../store/paramStore';
89
- import { Podcast } from '@/store/class/general/podcast';
90
- import { RubriquageFilter } from '@/store/class/rubrique/rubriquageFilter';
91
- import { defineComponent } from 'vue'
92
- import { RouteLocationRaw } from 'vue-router';
93
- import { Rubrique } from '@/store/class/rubrique/rubrique';
40
+ import { defineAsyncComponent, defineComponent } from 'vue';
41
+ const PodcastInlineListClassic = defineAsyncComponent(() => import('./PodcastInlineListClassic.vue'));
42
+ const PodcastSwiperList = defineAsyncComponent(() => import('./PodcastSwiperList.vue'));
94
43
  export default defineComponent({
95
44
  name: 'PodcastInlineList',
96
45
 
97
46
  components: {
98
- PodcastItem,
99
- ClassicLoading
47
+ PodcastInlineListClassic,
48
+ PodcastSwiperList,
100
49
  },
101
50
 
102
51
  props: {
@@ -116,217 +65,12 @@ export default defineComponent({
116
65
  },
117
66
  emits: ['update:isArrow'],
118
67
 
119
- data() {
120
- return {
121
- loading: true as boolean,
122
- loaded: true as boolean,
123
- index: 0 as number,
124
- first: 0 as number,
125
- size: 5 as number,
126
- totalCount: 0 as number,
127
- popularSort: false as boolean,
128
- allPodcasts: [] as Array<Podcast>,
129
- direction: 1 as number,
130
- alignLeft: false as boolean,
131
- };
132
- },
133
- computed: {
134
- podcasts(): Array<Podcast> {
135
- return this.allPodcasts.slice(this.index, this.index + this.size);
136
- },
137
- sizeItem(): number {
138
- return state.generalParameters.podcastItem ? (state.generalParameters.podcastItem as number): 13;
139
- },
140
- overflowScroll(): boolean {
141
- return (state.emissionPage.overflowScroll as boolean);
142
- },
143
- isInlineAnimation(): boolean {
144
- return (state.generalParameters.isInlineAnimation as boolean);
145
- },
146
- filterOrga(): string {
147
- return this.$store.state.filter.organisationId;
148
- },
149
- organisation(): string|undefined {
150
- if (this.organisationId) return this.organisationId;
151
- if (this.filterOrga) return this.filterOrga;
152
- return undefined;
153
- },
154
- rubriqueQueryParam(): string|undefined{
155
- if(this.$store.state.filter && this.$store.state.filter.rubriqueFilter && this.$store.state.filter.rubriqueFilter.length){
156
- return this.$store.state.filter.rubriqueFilter.map((value: RubriquageFilter) => value.rubriquageId+':'+value.rubriqueId).join();
157
- }
158
- return undefined;
68
+ computed:{
69
+ listTypeClassic(): boolean {
70
+ return (state.podcastPage.listTypeClassic as boolean);
159
71
  },
160
- refTo(): string | RouteLocationRaw {
161
- if (this.href) return this.href;
162
- if(this.iabId){
163
- return {
164
- name: 'category',
165
- params:{ 'iabId': this.iabId },
166
- query: { productor: this.$store.state.filter.organisationId },
167
- };
168
- }
169
- return {
170
- name: 'podcasts',
171
- query: { productor: this.$store.state.filter.organisationId,
172
- iabId: this.$store.state.filter.iab ? this.$store.state.filter.iab.id : undefined,
173
- rubriquesId: this.rubriqueQueryParam },
174
- };
175
- },
176
- previousAvailable(): boolean {
177
- return this.index > 0;
178
- },
179
- nextAvailable(): boolean {
180
- return this.index + this.size < this.totalCount;
181
- },
182
- transitionName(): string {
183
- return this.direction > 0 ? 'out-left' : 'out-right';
184
- },
185
- watchVariable():string{
186
- return `${this.emissionId}|${this.organisationId}|${this.filterOrga}|${this.iabId}|${this.rubriqueId}|${this.rubriquageId}|${this.query}`;
187
- }
188
- },
189
- watch: {
190
- watchVariable(): void {
191
- this.reset();
192
- this.fetchNext();
193
- },
194
- },
195
-
196
- created() {
197
- if (undefined !== this.requirePopularSort) {
198
- this.popularSort = this.requirePopularSort;
199
- }
200
- if (undefined !== this.isArrow) {
201
- this.$emit('update:isArrow', true);
202
- }
203
- window.addEventListener('resize', this.handleResize);
204
- },
72
+ }
205
73
 
206
- unmounted() {
207
- window.removeEventListener('resize', this.handleResize);
208
- },
209
74
 
210
- mounted() {
211
- this.handleResize();
212
- this.fetchNext();
213
- },
214
- methods: {
215
- handleSeeMoreButton(event: { preventDefault: () => void; }){
216
- if(!this.rubriqueId || 0===this.rubriqueId.length || this.noRubriquageId.length){
217
- return;
218
- }
219
- event.preventDefault();
220
- const rubriqueChosenId = this.rubriqueId[this.rubriqueId.length - 1];
221
- let filterToAdd: RubriquageFilter = {
222
- rubriquageId: 0,
223
- rubriqueId: rubriqueChosenId,
224
- nameRubriquage: '',
225
- nameRubrique: ''
226
- };
227
- if(this.$store.state.filter.rubriquageArray.length){
228
- const rubriqueChosen = this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].rubriques.find((element: Rubrique) => element.rubriqueId === rubriqueChosenId);
229
- filterToAdd = {
230
- rubriquageId: this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].rubriquageId,
231
- rubriqueId: rubriqueChosenId,
232
- nameRubriquage: this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].title,
233
- nameRubrique: rubriqueChosen.name
234
- };
235
- }
236
- const newFilter: Array<RubriquageFilter> = Array.from(this.$store.state.filter.rubriqueFilter);
237
- newFilter.push(filterToAdd);
238
- this.$store.commit('filterRubrique', newFilter);
239
- const queries = this.$route.query;
240
- const queryString = newFilter.map(value => value.rubriquageId+':'+value.rubriqueId).join();
241
- this.$router.push({ name: 'podcasts',query: { ...queries, ...{ rubriquesId: queryString }} });
242
- },
243
- async fetchNext(): Promise<void> {
244
- const data = await octopusApi.fetchPodcasts({
245
- first: this.first,
246
- size: this.size + 1,
247
- organisationId: this.organisation,
248
- emissionId: this.emissionId,
249
- iabId: this.iabId,
250
- rubriqueId: this.rubriqueId.length ?this.rubriqueId:undefined,
251
- rubriquageId: this.rubriquageId.length ?this.rubriquageId : undefined,
252
- noRubriquageId: this.noRubriquageId.length ? this.noRubriquageId : undefined,
253
- sort: this.popularSort ? 'POPULARITY' : 'DATE',
254
- query: this.query,
255
- });
256
- this.loading = false;
257
- this.loaded = true;
258
- this.totalCount = data.count;
259
- if (this.allPodcasts.length + data.result.length < this.totalCount) {
260
- const nexEl = data.result.pop() as Podcast;
261
- if(nexEl){
262
- this.preloadImage(nexEl.imageUrl?nexEl.imageUrl:'');
263
- }
264
- }
265
- this.allPodcasts = this.allPodcasts.concat(
266
- data.result.filter((pod: Podcast|null) => null !== pod)
267
- );
268
- if (this.allPodcasts.length <= 3) {
269
- this.alignLeft = true;
270
- } else {
271
- this.alignLeft = false;
272
- }
273
- this.first += this.size;
274
- },
275
- displayPrevious(): void {
276
- this.direction = -1;
277
- if (this.previousAvailable) {
278
- this.index -= 1;
279
- }
280
- },
281
- displayNext(): void {
282
- this.direction = 1;
283
- if (!this.nextAvailable) return;
284
- if (
285
- this.first - (this.index + this.size) < 2 &&
286
- this.allPodcasts.length < this.totalCount
287
- ) {
288
- this.fetchNext();
289
- }
290
- this.index += 1;
291
- },
292
- handleResize(): void {
293
- if (!this.$el) return;
294
- if (this.overflowScroll) {
295
- this.size = 20;
296
- return;
297
- }
298
- if (window.innerWidth <= PHONE_WIDTH) {
299
- this.size = 10;
300
- return;
301
- }
302
- const width = (this.$el as HTMLElement).offsetWidth;
303
- const sixteen = domHelper.convertRemToPixels(this.sizeItem + 0.7);
304
- this.size = Math.floor(width / sixteen);
305
- },
306
- sortPopular(): void {
307
- if (this.popularSort) return;
308
- this.popularSort = true;
309
- this.reset();
310
- this.fetchNext();
311
- },
312
- sortChrono(): void {
313
- if (!this.popularSort) return;
314
- this.popularSort = false;
315
- this.reset();
316
- this.fetchNext();
317
- },
318
- reset(): void {
319
- this.loading = true;
320
- this.loaded = true;
321
- this.index = 0;
322
- this.first = 0;
323
- this.totalCount = 0;
324
- this.allPodcasts.length = 0;
325
- },
326
- preloadImage(url: string): void {
327
- const img = new Image();
328
- img.src = url;
329
- },
330
- },
331
75
  })
332
76
  </script>
@@ -0,0 +1,246 @@
1
+ <template>
2
+ <PodcastInlineListTemplate
3
+ v-if="loading || (!loading && 0 !== allPodcasts.length)"
4
+ :display-arrow="true"
5
+ :popular-sort="popularSort"
6
+ :button-text="buttonText"
7
+ :button-plus="buttonPlus"
8
+ :title="title"
9
+ :href="href"
10
+ :iab-id="iabId"
11
+ :rubrique-id="rubriqueId"
12
+ :previous-available="previousAvailable"
13
+ :next-available="nextAvailable"
14
+ :no-rubriquage-id="noRubriquageId"
15
+ @sortChrono="sortChrono"
16
+ @sortPopular="sortPopular"
17
+ @displayPrevious="displayPrevious"
18
+ @displayNext="displayNext"
19
+ >
20
+ <template #list-inline>
21
+ <ClassicLoading
22
+ :loading-text="loading?$t('Loading podcasts ...'):undefined"
23
+ />
24
+ <transition-group
25
+ v-show="loaded"
26
+ :name="transitionName"
27
+ class="element-list-inline"
28
+ tag="ul"
29
+ :class="[
30
+ alignLeft ? 'justify-content-start' : '',
31
+ overflowScroll ? 'overflowScroll' : '',
32
+ ]"
33
+ :css="isInlineAnimation"
34
+ >
35
+ <PodcastItem
36
+ v-for="p in podcasts"
37
+ :key="p.podcastId"
38
+ class="flex-shrink-0 item-phone-margin"
39
+ :podcast="p"
40
+ :class="[alignLeft ? 'me-3' : '']"
41
+ />
42
+ </transition-group>
43
+ </template>
44
+ </PodcastInlineListTemplate>
45
+ </template>
46
+
47
+ <script lang="ts">
48
+ import PodcastInlineListTemplate from './PodcastInlineListTemplate.vue';
49
+ import octopusApi from '@saooti/octopus-api';
50
+ import domHelper from '../../../helper/dom';
51
+ import PodcastItem from './PodcastItem.vue';
52
+ import ClassicLoading from '../../form/ClassicLoading.vue';
53
+ const PHONE_WIDTH = 960;
54
+ import { state } from '../../../store/paramStore';
55
+ import { Podcast } from '@/store/class/general/podcast';
56
+ import { defineComponent } from 'vue'
57
+ export default defineComponent({
58
+ name: 'PodcastInlineListClassic',
59
+
60
+ components: {
61
+ PodcastItem,
62
+ ClassicLoading,
63
+ PodcastInlineListTemplate
64
+ },
65
+
66
+ props: {
67
+ organisationId: { default: undefined, type: String},
68
+ emissionId: { default: undefined, type: Number},
69
+ iabId: { default: undefined, type: Number},
70
+ title: { default: '', type: String},
71
+ href: { default: undefined, type: String},
72
+ buttonText: { default: undefined, type: String},
73
+ isArrow: { default: false, type: Boolean},
74
+ requirePopularSort: { default:undefined, type: Boolean},
75
+ buttonPlus: { default:false, type: Boolean},
76
+ rubriqueId: { default: () => [], type: Array as ()=> Array<number> },
77
+ rubriquageId:{ default: () => [], type: Array as ()=> Array<number> },
78
+ noRubriquageId: { default: () => [], type: Array as ()=> Array<number> },
79
+ query: { default: undefined, type: String},
80
+ },
81
+ emits: ['update:isArrow'],
82
+
83
+ data() {
84
+ return {
85
+ loading: true as boolean,
86
+ loaded: true as boolean,
87
+ index: 0 as number,
88
+ first: 0 as number,
89
+ size: 5 as number,
90
+ totalCount: 0 as number,
91
+ popularSort: false as boolean,
92
+ allPodcasts: [] as Array<Podcast>,
93
+ direction: 1 as number,
94
+ alignLeft: false as boolean,
95
+ };
96
+ },
97
+ computed: {
98
+ podcasts(): Array<Podcast> {
99
+ return this.allPodcasts.slice(this.index, this.index + this.size);
100
+ },
101
+ sizeItem(): number {
102
+ return state.generalParameters.podcastItem ? (state.generalParameters.podcastItem as number): 13;
103
+ },
104
+ overflowScroll(): boolean {
105
+ return (state.emissionPage.overflowScroll as boolean);
106
+ },
107
+ isInlineAnimation(): boolean {
108
+ return (state.generalParameters.isInlineAnimation as boolean);
109
+ },
110
+ filterOrga(): string {
111
+ return this.$store.state.filter.organisationId;
112
+ },
113
+ organisation(): string|undefined {
114
+ if (this.organisationId) return this.organisationId;
115
+ if (this.filterOrga) return this.filterOrga;
116
+ return undefined;
117
+ },
118
+ previousAvailable(): boolean {
119
+ return this.index > 0;
120
+ },
121
+ nextAvailable(): boolean {
122
+ return this.index + this.size < this.totalCount;
123
+ },
124
+ transitionName(): string {
125
+ return this.direction > 0 ? 'out-left' : 'out-right';
126
+ },
127
+ watchVariable():string{
128
+ return `${this.emissionId}|${this.organisationId}|${this.filterOrga}|${this.iabId}|${this.rubriqueId}|${this.rubriquageId}|${this.query}`;
129
+ }
130
+ },
131
+ watch: {
132
+ watchVariable(): void {
133
+ this.reset();
134
+ this.fetchNext();
135
+ },
136
+ },
137
+
138
+ created() {
139
+ if (undefined !== this.requirePopularSort) {
140
+ this.popularSort = this.requirePopularSort;
141
+ }
142
+ if (undefined !== this.isArrow) {
143
+ this.$emit('update:isArrow', true);
144
+ }
145
+ window.addEventListener('resize', this.handleResize);
146
+ },
147
+
148
+ unmounted() {
149
+ window.removeEventListener('resize', this.handleResize);
150
+ },
151
+
152
+ mounted() {
153
+ this.handleResize();
154
+ this.fetchNext();
155
+ },
156
+ methods: {
157
+ async fetchNext(): Promise<void> {
158
+ const data = await octopusApi.fetchPodcasts({
159
+ first: this.first,
160
+ size: this.size + 1,
161
+ organisationId: this.organisation,
162
+ emissionId: this.emissionId,
163
+ iabId: this.iabId,
164
+ rubriqueId: this.rubriqueId.length ?this.rubriqueId:undefined,
165
+ rubriquageId: this.rubriquageId.length ?this.rubriquageId : undefined,
166
+ noRubriquageId: this.noRubriquageId.length ? this.noRubriquageId : undefined,
167
+ sort: this.popularSort ? 'POPULARITY' : 'DATE',
168
+ query: this.query,
169
+ });
170
+ this.loading = false;
171
+ this.loaded = true;
172
+ this.totalCount = data.count;
173
+ if (this.allPodcasts.length + data.result.length < this.totalCount) {
174
+ const nexEl = data.result.pop() as Podcast;
175
+ if(nexEl){
176
+ this.preloadImage(nexEl.imageUrl?nexEl.imageUrl:'');
177
+ }
178
+ }
179
+ this.allPodcasts = this.allPodcasts.concat(
180
+ data.result.filter((pod: Podcast|null) => null !== pod)
181
+ );
182
+ if (this.allPodcasts.length <= 3) {
183
+ this.alignLeft = true;
184
+ } else {
185
+ this.alignLeft = false;
186
+ }
187
+ this.first += this.size;
188
+ },
189
+ displayPrevious(): void {
190
+ this.direction = -1;
191
+ if (this.previousAvailable) {
192
+ this.index -= 1;
193
+ }
194
+ },
195
+ displayNext(): void {
196
+ this.direction = 1;
197
+ if (!this.nextAvailable) return;
198
+ if (
199
+ this.first - (this.index + this.size) < 2 &&
200
+ this.allPodcasts.length < this.totalCount
201
+ ) {
202
+ this.fetchNext();
203
+ }
204
+ this.index += 1;
205
+ },
206
+ handleResize(): void {
207
+ if (!this.$el) return;
208
+ if (this.overflowScroll) {
209
+ this.size = 20;
210
+ return;
211
+ }
212
+ if (window.innerWidth <= PHONE_WIDTH) {
213
+ this.size = 10;
214
+ return;
215
+ }
216
+ const width = (this.$el as HTMLElement).offsetWidth;
217
+ const sixteen = domHelper.convertRemToPixels(this.sizeItem + 0.7);
218
+ this.size = Math.floor(width / sixteen);
219
+ },
220
+ sortPopular(): void {
221
+ if (this.popularSort) return;
222
+ this.popularSort = true;
223
+ this.reset();
224
+ this.fetchNext();
225
+ },
226
+ sortChrono(): void {
227
+ if (!this.popularSort) return;
228
+ this.popularSort = false;
229
+ this.reset();
230
+ this.fetchNext();
231
+ },
232
+ reset(): void {
233
+ this.loading = true;
234
+ this.loaded = true;
235
+ this.index = 0;
236
+ this.first = 0;
237
+ this.totalCount = 0;
238
+ this.allPodcasts.length = 0;
239
+ },
240
+ preloadImage(url: string): void {
241
+ const img = new Image();
242
+ img.src = url;
243
+ },
244
+ },
245
+ })
246
+ </script>
@@ -0,0 +1,158 @@
1
+ <template>
2
+ <div
3
+ class="d-flex flex-column p-3"
4
+ >
5
+ <h2>{{ title }}</h2>
6
+ <div class="d-flex justify-content-between">
7
+ <div class="d-flex">
8
+ <button
9
+ class="btn btn-underline"
10
+ :class="{ active: !popularSort }"
11
+ @click="sortChrono()"
12
+ >
13
+ {{ $t('Last added') }}
14
+ </button>
15
+ <button
16
+ class="btn btn-underline"
17
+ :class="{ active: popularSort }"
18
+ @click="sortPopular()"
19
+ >
20
+ {{ $t('Most popular') }}
21
+ </button>
22
+ </div>
23
+ <div
24
+ v-if="displayArrow"
25
+ class="hide-phone"
26
+ >
27
+ <button
28
+ class="btn admin-button m-1"
29
+ :class="{ disabled: !previousAvailable }"
30
+ :title="$t('Display previous')"
31
+ @click="displayPrevious()"
32
+ >
33
+ <div class="saooti-left fw-bold" />
34
+ </button>
35
+ <button
36
+ class="btn admin-button m-1"
37
+ :class="{ disabled: !nextAvailable }"
38
+ :title="$t('Display next')"
39
+ @click="displayNext()"
40
+ >
41
+ <div class="saooti-right fw-bold" />
42
+ </button>
43
+ </div>
44
+ </div>
45
+ <slot name="list-inline" />
46
+ <router-link
47
+ class="btn btn-link align-self-center width-fit-content m-4"
48
+ :to="refTo"
49
+ @click="handleSeeMoreButton"
50
+ >
51
+ {{ buttonText }}
52
+ <div
53
+ v-if="buttonPlus"
54
+ class="ms-1 saooti-more"
55
+ />
56
+ </router-link>
57
+ </div>
58
+ </template>
59
+
60
+ <script lang="ts">
61
+ import { RubriquageFilter } from '@/store/class/rubrique/rubriquageFilter';
62
+ import { defineComponent } from 'vue'
63
+ import { RouteLocationRaw } from 'vue-router';
64
+ import { Rubrique } from '@/store/class/rubrique/rubrique';
65
+ export default defineComponent({
66
+ name: 'PodcastInlineListTemplate',
67
+
68
+ components: {
69
+ },
70
+
71
+ props: {
72
+ displayArrow: { default: true, type: Boolean},
73
+ previousAvailable: { default: false, type: Boolean},
74
+ nextAvailable: { default: false, type: Boolean},
75
+ popularSort: { default: false, type: Boolean},
76
+ buttonText: { default: undefined, type: String},
77
+ buttonPlus: { default:false, type: Boolean},
78
+ title: { default: '', type: String},
79
+ href: { default: undefined, type: String},
80
+ iabId: { default: undefined, type: Number},
81
+ rubriqueId: { default: () => [], type: Array as ()=> Array<number> },
82
+ noRubriquageId: { default: () => [], type: Array as ()=> Array<number> },
83
+ },
84
+ emits:['sortChrono','sortPopular', 'displayPrevious', 'displayNext'],
85
+ data() {
86
+ return {
87
+ };
88
+ },
89
+
90
+ computed: {
91
+ rubriqueQueryParam(): string|undefined{
92
+ if(this.$store.state.filter && this.$store.state.filter.rubriqueFilter && this.$store.state.filter.rubriqueFilter.length){
93
+ return this.$store.state.filter.rubriqueFilter.map((value: RubriquageFilter) => value.rubriquageId+':'+value.rubriqueId).join();
94
+ }
95
+ return undefined;
96
+ },
97
+ refTo(): string | RouteLocationRaw {
98
+ if (this.href) return this.href;
99
+ if(this.iabId){
100
+ return {
101
+ name: 'category',
102
+ params:{ 'iabId': this.iabId },
103
+ query: { productor: this.$store.state.filter.organisationId },
104
+ };
105
+ }
106
+ return {
107
+ name: 'podcasts',
108
+ query: { productor: this.$store.state.filter.organisationId,
109
+ iabId: this.$store.state.filter.iab ? this.$store.state.filter.iab.id : undefined,
110
+ rubriquesId: this.rubriqueQueryParam },
111
+ };
112
+ },
113
+ },
114
+
115
+ methods: {
116
+ sortChrono():void{
117
+ this.$emit('sortChrono');
118
+ },
119
+ sortPopular():void{
120
+ this.$emit('sortPopular');
121
+ },
122
+ displayPrevious():void{
123
+ this.$emit('displayPrevious');
124
+ },
125
+ displayNext():void{
126
+ this.$emit('displayNext');
127
+ },
128
+ handleSeeMoreButton(event: { preventDefault: () => void; }){
129
+ if(!this.rubriqueId || 0===this.rubriqueId.length || this.noRubriquageId.length){
130
+ return;
131
+ }
132
+ event.preventDefault();
133
+ const rubriqueChosenId = this.rubriqueId[this.rubriqueId.length - 1];
134
+ let filterToAdd: RubriquageFilter = {
135
+ rubriquageId: 0,
136
+ rubriqueId: rubriqueChosenId,
137
+ nameRubriquage: '',
138
+ nameRubrique: ''
139
+ };
140
+ if(this.$store.state.filter.rubriquageArray.length){
141
+ const rubriqueChosen = this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].rubriques.find((element: Rubrique) => element.rubriqueId === rubriqueChosenId);
142
+ filterToAdd = {
143
+ rubriquageId: this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].rubriquageId,
144
+ rubriqueId: rubriqueChosenId,
145
+ nameRubriquage: this.$store.state.filter.rubriquageArray[this.rubriqueId.length - 1].title,
146
+ nameRubrique: rubriqueChosen.name
147
+ };
148
+ }
149
+ const newFilter: Array<RubriquageFilter> = Array.from(this.$store.state.filter.rubriqueFilter);
150
+ newFilter.push(filterToAdd);
151
+ this.$store.commit('filterRubrique', newFilter);
152
+ const queries = this.$route.query;
153
+ const queryString = newFilter.map(value => value.rubriquageId+':'+value.rubriqueId).join();
154
+ this.$router.push({ name: 'podcasts',query: { ...queries, ...{ rubriquesId: queryString }} });
155
+ },
156
+ },
157
+ })
158
+ </script>
@@ -47,7 +47,21 @@
47
47
  {{ duration }}
48
48
  </div>
49
49
  </div>
50
- <AnimatorsItem :animators="podcast.animators" />
50
+ <router-link
51
+ v-if="podcastItemShowEmission"
52
+ class="podcast-item-emission"
53
+ :to="{
54
+ name: 'emission',
55
+ params: { emissionId: podcast.emission.emissionId },
56
+ query: { productor: $store.state.filter.organisationId },
57
+ }"
58
+ >
59
+ {{ podcast.emission.name }}
60
+ </router-link>
61
+ <AnimatorsItem
62
+ v-else
63
+ :animators="podcast.animators"
64
+ />
51
65
  <router-link
52
66
  :to="{
53
67
  name: 'podcast',
@@ -65,6 +79,7 @@
65
79
  class="mx-2"
66
80
  />
67
81
  <div class="d-flex justify-content-between">
82
+ <div class="useless-div-for-podcastmaker" />
68
83
  <router-link
69
84
  v-if="!isPodcastmaker"
70
85
  :to="{
@@ -127,6 +142,9 @@ export default defineComponent({
127
142
  podcastBorderBottom(): boolean {
128
143
  return (state.podcastsPage.podcastBorderBottom as boolean);
129
144
  },
145
+ podcastItemShowEmission(): boolean {
146
+ return (state.podcastPage.podcastItemShowEmission as boolean);
147
+ },
130
148
  date(): string {
131
149
  return moment(this.podcast.pubDate).format('D MMMM YYYY, HH[h]mm');
132
150
  },
@@ -0,0 +1,209 @@
1
+ <template>
2
+ <PodcastInlineListTemplate
3
+ v-if="loading || (!loading && 0 !== allPodcasts.length)"
4
+ :display-arrow="false"
5
+ :popular-sort="popularSort"
6
+ :button-text="buttonText"
7
+ :button-plus="buttonPlus"
8
+ :title="title"
9
+ :href="href"
10
+ :iab-id="iabId"
11
+ :rubrique-id="rubriqueId"
12
+ :no-rubriquage-id="noRubriquageId"
13
+ @sortChrono="sortChrono"
14
+ @sortPopular="sortPopular"
15
+ >
16
+ <template #list-inline>
17
+ <ClassicLoading
18
+ :loading-text="loading?$t('Loading podcasts ...'):undefined"
19
+ />
20
+ <swiper
21
+ v-show="loaded"
22
+ :slides-per-view="numberItem"
23
+ :space-between="10"
24
+ :loop="true"
25
+ :navigation="true"
26
+ :modules="modules"
27
+ class="mySwiper"
28
+ >
29
+ <swiper-slide
30
+ v-for="p in allPodcasts"
31
+ :key="p.podcastId"
32
+ >
33
+ <PodcastItem
34
+ class="flex-shrink-0 item-phone-margin"
35
+ :podcast="p"
36
+ />
37
+ </swiper-slide>
38
+ </swiper>
39
+ </template>
40
+ </PodcastInlineListTemplate>
41
+ </template>
42
+
43
+ <script lang="ts">
44
+ import PodcastInlineListTemplate from './PodcastInlineListTemplate.vue';
45
+ import octopusApi from '@saooti/octopus-api';
46
+ import domHelper from '../../../helper/dom';
47
+ import PodcastItem from './PodcastItem.vue';
48
+ import { state } from '../../../store/paramStore';
49
+ import ClassicLoading from '../../form/ClassicLoading.vue';
50
+ import { Swiper, SwiperSlide } from "swiper/vue";
51
+ import { Navigation } from "swiper";
52
+ import "swiper/css";
53
+ import "swiper/css/navigation";
54
+ import { Podcast } from '@/store/class/general/podcast';
55
+ import { defineComponent } from 'vue'
56
+ export default defineComponent({
57
+ name: 'PodcastSwiperList',
58
+
59
+ components: {
60
+ PodcastInlineListTemplate,
61
+ PodcastItem,
62
+ ClassicLoading,
63
+ Swiper,
64
+ SwiperSlide,
65
+ },
66
+
67
+ props: {
68
+ organisationId: { default: undefined, type: String},
69
+ emissionId: { default: undefined, type: Number},
70
+ iabId: { default: undefined, type: Number},
71
+ title: { default: '', type: String},
72
+ href: { default: undefined, type: String},
73
+ buttonText: { default: undefined, type: String},
74
+ isArrow: { default: false, type: Boolean},
75
+ requirePopularSort: { default:undefined, type: Boolean},
76
+ buttonPlus: { default:false, type: Boolean},
77
+ rubriqueId: { default: () => [], type: Array as ()=> Array<number> },
78
+ rubriquageId:{ default: () => [], type: Array as ()=> Array<number> },
79
+ noRubriquageId: { default: () => [], type: Array as ()=> Array<number> },
80
+ query: { default: undefined, type: String},
81
+ },
82
+ emits: ['update:isArrow'],
83
+
84
+ data() {
85
+ return {
86
+ loading: true as boolean,
87
+ loaded: true as boolean,
88
+ popularSort: false as boolean,
89
+ allPodcasts: [] as Array<Podcast>,
90
+ modules: [Navigation],
91
+ numberItem: 5 as number
92
+ };
93
+ },
94
+ computed: {
95
+ filterOrga(): string {
96
+ return this.$store.state.filter.organisationId;
97
+ },
98
+ organisation(): string|undefined {
99
+ if (this.organisationId) return this.organisationId;
100
+ if (this.filterOrga) return this.filterOrga;
101
+ return undefined;
102
+ },
103
+ watchVariable():string{
104
+ return `${this.emissionId}|${this.organisationId}|${this.filterOrga}|${this.iabId}|${this.rubriqueId}|${this.rubriquageId}|${this.query}`;
105
+ },
106
+ sizeItem(): number {
107
+ return state.generalParameters.podcastItem ? (state.generalParameters.podcastItem as number): 13;
108
+ },
109
+ },
110
+ watch: {
111
+ watchVariable(): void {
112
+ this.reset();
113
+ this.fetchNext();
114
+ },
115
+ },
116
+
117
+ created() {
118
+ if (undefined !== this.requirePopularSort) {
119
+ this.popularSort = this.requirePopularSort;
120
+ }
121
+ if (undefined !== this.isArrow) {
122
+ this.$emit('update:isArrow', true);
123
+ }
124
+ window.addEventListener('resize', this.handleResize);
125
+ },
126
+ unmounted() {
127
+ window.removeEventListener('resize', this.handleResize);
128
+ },
129
+
130
+
131
+ mounted() {
132
+ this.fetchNext();
133
+ },
134
+ methods: {
135
+ handleResize(): void {
136
+ if (!this.$el) return;
137
+ const width = (this.$el as HTMLElement).offsetWidth;
138
+ const sixteen = domHelper.convertRemToPixels(this.sizeItem + 2);
139
+ this.numberItem = Math.floor(width / sixteen);
140
+ },
141
+ async fetchNext(): Promise<void> {
142
+ const data = await octopusApi.fetchPodcasts({
143
+ first: 0,
144
+ size: 10,
145
+ organisationId: this.organisation,
146
+ emissionId: this.emissionId,
147
+ iabId: this.iabId,
148
+ rubriqueId: this.rubriqueId.length ?this.rubriqueId:undefined,
149
+ rubriquageId: this.rubriquageId.length ?this.rubriquageId : undefined,
150
+ noRubriquageId: this.noRubriquageId.length ? this.noRubriquageId : undefined,
151
+ sort: this.popularSort ? 'POPULARITY' : 'DATE',
152
+ query: this.query,
153
+ });
154
+ this.loading = false;
155
+ this.loaded = true;
156
+ this.allPodcasts = this.allPodcasts.concat(
157
+ data.result.filter((pod: Podcast|null) => null !== pod)
158
+ );
159
+ },
160
+ sortPopular(): void {
161
+ if (this.popularSort) return;
162
+ this.popularSort = true;
163
+ this.reset();
164
+ this.fetchNext();
165
+ },
166
+ sortChrono(): void {
167
+ if (!this.popularSort) return;
168
+ this.popularSort = false;
169
+ this.reset();
170
+ this.fetchNext();
171
+ },
172
+ reset(): void {
173
+ this.loading = true;
174
+ this.loaded = true;
175
+ this.allPodcasts.length = 0;
176
+ },
177
+ },
178
+ })
179
+ </script>
180
+ <style lang="scss">
181
+ @import '../../../sass/_variables.scss';
182
+ .swiper {
183
+ width: 100%;
184
+ height: 100%;
185
+ padding: 50px 20px;
186
+ }
187
+ .swiper-button-next, .swiper-button-prev{
188
+ color: $octopus-primary-color !important;
189
+ height: 100%;
190
+ top: 0;
191
+ bottom: 0;
192
+ margin: 0;
193
+ width: 50px;
194
+ }
195
+ .swiper-button-next{
196
+ background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%,#fafafa 50%, #fafafa 100%);
197
+ right: 0;
198
+ }
199
+ .swiper-button-prev{
200
+ background: linear-gradient(90deg, #fafafa 0%,#fafafa 50%, rgba(255, 255, 255, 0) 100%);
201
+ left: 0;
202
+ }
203
+
204
+ .swiper-slide {
205
+ display: flex;
206
+ justify-content: center;
207
+ align-items: center;
208
+ }
209
+ </style>
@@ -31,7 +31,10 @@ const state:paramStore = {
31
31
  downloadButton: false,
32
32
  hlsUri: 'https://hls.preprod.saooti.org/',
33
33
  mainRubrique: 0,
34
- resourceUrl: undefined
34
+ resourceUrl: undefined,
35
+ podcastItemShowEmission: false,
36
+ clickPlayGoPage:false,
37
+ listTypeClassic: true,
35
38
  },
36
39
  podcastsPage: {
37
40
  ProductorSearch: true,
@@ -124,6 +127,9 @@ export interface PodcastPage{
124
127
  hlsUri?: string,
125
128
  mainRubrique?: number,
126
129
  resourceUrl?: string |undefined,
130
+ podcastItemShowEmission?: boolean,
131
+ clickPlayGoPage?:boolean,
132
+ listTypeClassic?:boolean
127
133
  }
128
134
  export interface PodcastsPage{
129
135
  ProductorSearch?: boolean,