@saooti/octopus-sdk 30.0.86 → 30.0.89

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
@@ -582,4 +582,7 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
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
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
585
+ * 30.0.86 Podcastmaker newest
586
+ * 30.0.87 Podcastmaker newest (swiper list)
587
+ * 30.0.88 Podcastmaker newest (swiper list)
588
+ * 30.0.89 Podcastmaker newest (swiper list)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "30.0.86",
3
+ "version": "30.0.89",
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>
@@ -0,0 +1,208 @@
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
+ >
28
+ <swiper-slide
29
+ v-for="p in allPodcasts"
30
+ :key="p.podcastId"
31
+ >
32
+ <PodcastItem
33
+ class="flex-shrink-0 item-phone-margin"
34
+ :podcast="p"
35
+ />
36
+ </swiper-slide>
37
+ </swiper>
38
+ </template>
39
+ </PodcastInlineListTemplate>
40
+ </template>
41
+
42
+ <script lang="ts">
43
+ import PodcastInlineListTemplate from './PodcastInlineListTemplate.vue';
44
+ import octopusApi from '@saooti/octopus-api';
45
+ import domHelper from '../../../helper/dom';
46
+ import PodcastItem from './PodcastItem.vue';
47
+ import { state } from '../../../store/paramStore';
48
+ import ClassicLoading from '../../form/ClassicLoading.vue';
49
+ import { Swiper, SwiperSlide } from "swiper/vue";
50
+ import { Navigation } from "swiper";
51
+ import "swiper/css";
52
+ import "swiper/css/navigation";
53
+ import { Podcast } from '@/store/class/general/podcast';
54
+ import { defineComponent } from 'vue'
55
+ export default defineComponent({
56
+ name: 'PodcastSwiperList',
57
+
58
+ components: {
59
+ PodcastInlineListTemplate,
60
+ PodcastItem,
61
+ ClassicLoading,
62
+ Swiper,
63
+ SwiperSlide,
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
+ popularSort: false as boolean,
88
+ allPodcasts: [] as Array<Podcast>,
89
+ modules: [Navigation],
90
+ numberItem: 5 as number
91
+ };
92
+ },
93
+ computed: {
94
+ filterOrga(): string {
95
+ return this.$store.state.filter.organisationId;
96
+ },
97
+ organisation(): string|undefined {
98
+ if (this.organisationId) return this.organisationId;
99
+ if (this.filterOrga) return this.filterOrga;
100
+ return undefined;
101
+ },
102
+ watchVariable():string{
103
+ return `${this.emissionId}|${this.organisationId}|${this.filterOrga}|${this.iabId}|${this.rubriqueId}|${this.rubriquageId}|${this.query}`;
104
+ },
105
+ sizeItem(): number {
106
+ return state.generalParameters.podcastItem ? (state.generalParameters.podcastItem as number): 13;
107
+ },
108
+ },
109
+ watch: {
110
+ watchVariable(): void {
111
+ this.reset();
112
+ this.fetchNext();
113
+ },
114
+ },
115
+
116
+ created() {
117
+ if (undefined !== this.requirePopularSort) {
118
+ this.popularSort = this.requirePopularSort;
119
+ }
120
+ if (undefined !== this.isArrow) {
121
+ this.$emit('update:isArrow', true);
122
+ }
123
+ window.addEventListener('resize', this.handleResize);
124
+ },
125
+ unmounted() {
126
+ window.removeEventListener('resize', this.handleResize);
127
+ },
128
+
129
+
130
+ mounted() {
131
+ this.handleResize();
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 + 0.5);
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
+ }
186
+ .swiper-button-next, .swiper-button-prev{
187
+ color: $octopus-primary-color !important;
188
+ height: 100%;
189
+ top: 0;
190
+ bottom: 0;
191
+ margin: 0;
192
+ width: 50px;
193
+ }
194
+ .swiper-button-next{
195
+ background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%,#fafafa 50%, #fafafa 100%);
196
+ right: 0;
197
+ }
198
+ .swiper-button-prev{
199
+ background: linear-gradient(90deg, #fafafa 0%,#fafafa 50%, rgba(255, 255, 255, 0) 100%);
200
+ left: 0;
201
+ }
202
+
203
+ .swiper-slide {
204
+ display: flex;
205
+ justify-content: center;
206
+ align-items: center;
207
+ }
208
+ </style>
@@ -32,7 +32,9 @@ const state:paramStore = {
32
32
  hlsUri: 'https://hls.preprod.saooti.org/',
33
33
  mainRubrique: 0,
34
34
  resourceUrl: undefined,
35
- podcastItemShowEmission: false
35
+ podcastItemShowEmission: false,
36
+ clickPlayGoPage:false,
37
+ listTypeClassic: true,
36
38
  },
37
39
  podcastsPage: {
38
40
  ProductorSearch: true,
@@ -126,6 +128,8 @@ export interface PodcastPage{
126
128
  mainRubrique?: number,
127
129
  resourceUrl?: string |undefined,
128
130
  podcastItemShowEmission?: boolean,
131
+ clickPlayGoPage?:boolean,
132
+ listTypeClassic?:boolean
129
133
  }
130
134
  export interface PodcastsPage{
131
135
  ProductorSearch?: boolean,