@saooti/octopus-sdk 36.0.10 → 36.0.11

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 (47) hide show
  1. package/package.json +1 -1
  2. package/public/img/tempRadio.jpg +0 -0
  3. package/src/assets/general.scss +9 -0
  4. package/src/assets/iframe.scss +11 -0
  5. package/src/assets/share.scss +38 -0
  6. package/src/assets/transition.scss +2 -3
  7. package/src/components/display/edit/EditBoxRadio.vue +11 -0
  8. package/src/components/display/list/SwiperList.vue +109 -0
  9. package/src/components/display/live/LiveItem.vue +26 -242
  10. package/src/components/display/live/LiveList.vue +111 -189
  11. package/src/components/display/live/RadioCurrently.vue +108 -0
  12. package/src/components/display/live/RadioImage.vue +84 -0
  13. package/src/components/display/live/RadioItem.vue +44 -0
  14. package/src/components/display/live/RadioList.vue +72 -0
  15. package/src/components/display/playlist/PlaylistList.vue +1 -0
  16. package/src/components/display/podcasts/PodcastImage.vue +15 -48
  17. package/src/components/display/podcasts/PodcastItem.vue +3 -0
  18. package/src/components/display/podcasts/PodcastSwiperList.vue +9 -80
  19. package/src/components/display/sharing/ShareButtons.vue +1 -0
  20. package/src/components/display/sharing/SharePlayer.vue +2 -10
  21. package/src/components/display/sharing/SharePlayerColors.vue +1 -1
  22. package/src/components/display/sharing/SharePlayerRadio.vue +102 -0
  23. package/src/components/misc/LeftMenu.vue +1 -1
  24. package/src/components/misc/TopBar.vue +1 -1
  25. package/src/components/misc/modal/ShareModalPlayer.vue +2 -2
  26. package/src/components/misc/player/PlayerCompact.vue +1 -0
  27. package/src/components/mixins/player/playerDisplay.ts +27 -10
  28. package/src/components/mixins/radio/fetchRadioData.ts +47 -0
  29. package/src/components/pages/Lives.vue +22 -48
  30. package/src/components/pages/Playlist.vue +9 -2
  31. package/src/components/pages/Radio.vue +112 -0
  32. package/src/locale/de.ts +8 -3
  33. package/src/locale/en.ts +10 -5
  34. package/src/locale/es.ts +8 -3
  35. package/src/locale/fr.ts +10 -5
  36. package/src/locale/it.ts +8 -3
  37. package/src/locale/sl.ts +8 -3
  38. package/src/router/router.ts +10 -0
  39. package/src/stores/ParamSdkStore.ts +12 -12
  40. package/src/stores/PlayerStore.ts +8 -0
  41. package/src/stores/class/general/player.ts +9 -7
  42. package/src/stores/class/general/playlist.ts +2 -0
  43. package/src/stores/class/radio/canal.ts +9 -0
  44. package/src/stores/class/radio/live.ts +34 -0
  45. package/src/stores/class/radio/mix.ts +23 -0
  46. package/src/stores/class/radio/playlistMedia.ts +10 -0
  47. package/src/stores/class/radio/recurrence.ts +76 -0
@@ -1,35 +1,45 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="filterOrgaId || organisationId"
4
- class="d-flex flex-column align-items-center"
4
+ class="d-flex flex-column align-items-start mt-3"
5
5
  >
6
+ <div class="d-flex justify-content-between amlign-items-center">
7
+ <h2 class="mb-0 big-h2 mb-3">{{ $t('Live') }}</h2>
8
+ <router-link
9
+ v-if="liveRight && !isPodcastmaker"
10
+ to="/main/priv/edit/live"
11
+ >
12
+ <button class="btn btn-primary">
13
+ {{ $t('Launch a new live') }}
14
+ </button>
15
+ </router-link>
16
+ </div>
17
+ <ClassicSelect
18
+ v-if="lives.length || 'ALL'!==selectedStatus"
19
+ v-model:textInit="selectedStatus"
20
+ id-select="status-live-chooser-select"
21
+ :label="$t('Selection by status')"
22
+ :displayLabel="false"
23
+ :options="statusArraySelect"
24
+ class="mb-3"
25
+ />
6
26
  <ClassicLoading
7
27
  :loading-text="loading?$t('Loading lives...'):undefined"
8
- :error-text="isNoLive?$t('No live currently'):undefined"
28
+ :error-text="0===lives.length?$t('No live currently'):undefined"
9
29
  />
10
- <div v-if="loaded && displayNextLiveMessage">
11
- <h3 class="text-danger">
12
- {{ displayNextLiveMessage }}
13
- </h3>
14
- </div>
15
- <template
16
- v-for="(live, indexLive) in livesArray"
17
- :key="live.status"
18
- >
19
- <template v-if="live.lives.length">
20
- <hr class="w-100">
21
- <p class="live-list-category">
22
- {{ live.title }}
23
- </p>
24
- <LiveItem
25
- v-for="(l, index) in live.lives"
26
- :key="l.podcastId"
27
- class="mt-3"
28
- :fetch-conference="l"
29
- :index="index"
30
- @deleteItem="deleteLive(indexLive, $event)"
31
- />
32
- </template>
30
+ <template v-if="lives.length">
31
+ <SwiperList
32
+ v-if="!loading"
33
+ :listObject="lives"
34
+ >
35
+ <template #octopusSlide="{option, index}">
36
+ <LiveItem
37
+ :fetch-conference="option"
38
+ @deleteItem="deleteLive(index)"
39
+ @updateItem="updateLive($event, index)"
40
+ />
41
+ </template>
42
+ </SwiperList>
33
43
  </template>
34
44
  </div>
35
45
  </template>
@@ -37,12 +47,13 @@
37
47
  <script lang="ts">
38
48
  import ClassicLoading from '../../form/ClassicLoading.vue';
39
49
  import LiveItem from './LiveItem.vue';
50
+ import ClassicSelect from '../../form/ClassicSelect.vue';
51
+ import SwiperList from '../list/SwiperList.vue';
40
52
  import { handle403 } from '../../mixins/handle403';
53
+ import { orgaComputed } from '../../mixins/orgaComputed';
41
54
  import octopusApi from '@saooti/octopus-api';
42
- import dayjs from 'dayjs';
43
- import localizedFormat from 'dayjs/plugin/localizedFormat';
44
- dayjs.extend(localizedFormat);
45
55
  import { useFilterStore } from '@/stores/FilterStore';
56
+ import { useAuthStore } from '@/stores/AuthStore';
46
57
  import { mapState } from 'pinia';
47
58
  import { state } from '../../../stores/ParamSdkStore';
48
59
  import { Conference } from '@/stores/class/conference/conference';
@@ -52,207 +63,118 @@ export default defineComponent({
52
63
  name: 'LiveList',
53
64
  components: {
54
65
  LiveItem,
55
- ClassicLoading
66
+ ClassicLoading,
67
+ SwiperList,
68
+ ClassicSelect
56
69
  },
57
70
 
58
- mixins: [handle403],
71
+ mixins: [handle403, orgaComputed],
59
72
 
60
73
  props: {
61
- conferenceWatched: { default: () => [], type: Array as ()=>Array<Conference>},
62
74
  organisationId: { default: undefined, type: String},
63
75
  },
64
- emits: ['initConferenceIds'],
65
76
  data() {
66
77
  return {
67
78
  loading: true as boolean,
68
79
  loaded: true as boolean,
69
- dataLivesToBe: [] as Array<Conference>
80
+ lives: [] as Array<Conference>,
81
+ isLiveAuthorized: false as boolean,
82
+ statusClassic: ["RECORDING", "PENDING", "PLANNED"] as Array<string>,
83
+ statusAdmin: ["DEBRIEFING", "ERROR", "PUBLISHING"] as Array<string>,
84
+ selectedStatus: "ALL" as string
70
85
  };
71
86
  },
72
87
 
73
88
  computed: {
74
89
  ...mapState(useFilterStore, ['filterOrgaId']),
75
- livesArray(): Array<{status:string, title:string, lives:Array<Conference>}>{
76
- return [
77
- {status: "RECORDING", title:this.$t('In live'), lives:[]},
78
- {status: "PENDING", title:this.$t('This live is not started yet'), lives:[]},
79
- {status: "PLANNED", title:this.$t('Live to be'), lives:[]},
80
- {status: "DEBRIEFING", title:this.$t('Live terminated'), lives:[]},
81
- {status: "PUBLISHING", title:this.$t('Publishing'), lives:[]},
82
- {status: "ERROR", title:this.$t('In error'), lives:[]}
83
- ];
84
- },
85
- isNoLive(): boolean{
86
- return this.loaded && !this.livesArray[0].lives.length && !this.livesArray[2].lives.length && !this.livesArray[3].lives.length;
87
- },
90
+ ...mapState(useAuthStore, ['authOrganisation']),
88
91
  filterOrgaUsed(): string|undefined {
89
92
  return this.filterOrgaId?this.filterOrgaId:this.organisationId;
90
93
  },
91
- displayNextLiveMessage(): string {
92
- if (0 !== this.livesArray[0].lives.length) return '';
93
- if (this.livesArray[1].lives.length > 0)
94
- return this.$t('A live can start any moment');
95
- if (this.livesArray[2].lives.length > 0)
96
- return this.$t('Next live date', {date: dayjs(this.livesArray[2].lives[0].date).format('LLLL'),});
97
- return '';
98
- },
99
- myOrganisationId(): string|undefined {
100
- return state.generalParameters.organisationId;
101
- },
102
- organisationRight(): boolean {
103
- return this.isRoleLive && this.myOrganisationId === this.filterOrgaUsed;
104
- },
105
- isRoleLive(): boolean {
106
- return (state.generalParameters.isRoleLive as boolean);
107
- },
108
- },
109
- watch: {
110
- async organisationId(): Promise<void> {
111
- if(!this.organisationId){return;}
112
- const isLive = await octopusApi.fetchData<boolean>(0, 'organisation/liveEnabled/'+this.organisationId);
113
- if (isLive) {
114
- if(!this.loading){
115
- this.fetchContent();
94
+ editRight(): boolean {
95
+ return (true ===this.authenticated && this.myOrganisationId === this.filterOrgaUsed) ||true===state.generalParameters.isAdmin;
96
+ },
97
+ liveRight(): boolean {
98
+ return (state.generalParameters.isRoleLive as boolean)&& true===this.authOrganisation.attributes?.['live.active'];
99
+ },
100
+ isPodcastmaker(): boolean {
101
+ return (state.generalParameters.podcastmaker as boolean);
102
+ },
103
+ statusArraySelect(): Array<{title: string, value:string}>{
104
+ const statusArray =[{title: this.$t('All lives'), value:'ALL'}];
105
+ for(let status of this.statusFetched){
106
+ let title ="";
107
+ switch (status) {
108
+ case "RECORDING": title = this.$t('In live'); break;
109
+ case "PENDING": title = this.$t('live upcoming'); break;
110
+ case "PLANNED": title = this.$t('live in few time'); break;
111
+ case "DEBRIEFING": title = this.$t('In debriefing'); break;
112
+ case "PUBLISHING": title = this.$t('In the process of being published'); break;
113
+ case "ERROR": title = this.$t('In error'); break;
114
+ default: break;
116
115
  }
117
- } else {
118
- this.initArrays();
119
- this.loading = false;
120
- this.loaded = true;
116
+ statusArray.push({title: title, value: status});
121
117
  }
118
+ return statusArray;
122
119
  },
123
- filterOrgaId(): void {
124
- if(!this.loading){
125
- this.fetchContent();
120
+ statusFetched(): Array<string>{
121
+ if(this.editRight){
122
+ return this.statusClassic.concat(this.statusAdmin);
126
123
  }
127
- },
128
- conferenceWatched: {
129
- handler(): void {
130
- this.updateLiveLocal();
124
+ return this.statusClassic;
125
+ }
126
+ },
127
+ watch: {
128
+ filterOrgaUsed: {
129
+ async handler(): Promise<void> {
130
+ await this.checkIfLiveAuthorized();
131
+ this.fetchContent();
131
132
  },
132
- deep: true,
133
+ immediate: true,
133
134
  },
134
- },
135
-
136
- async created() {
137
- if(!this.filterOrgaUsed){
138
- return;
139
- }
140
- const isLive = await octopusApi.fetchData<boolean>(0, 'organisation/liveEnabled/'+this.filterOrgaUsed);
141
- if (isLive) {
135
+ selectedStatus(){
142
136
  this.fetchContent();
143
- } else {
144
- this.loading = false;
145
- this.loaded = true;
146
137
  }
147
138
  },
148
139
  methods: {
149
- initArrays(): void {
150
- for (let i = 0, len = this.livesArray.length; i < len; i++) {
151
- this.livesArray[i].lives.length = 0;
140
+ async checkIfLiveAuthorized(): Promise<void>{
141
+ if(!this.filterOrgaUsed){
142
+ return;
152
143
  }
144
+ this.isLiveAuthorized = await octopusApi.fetchData<boolean>(0, 'organisation/liveEnabled/'+this.filterOrgaUsed);
153
145
  },
154
- liveTreatement(i: number, dataLives: Array<Conference>, indexPast: number){
155
- if("PLANNED"!==this.livesArray[i].status && "PENDING"!==this.livesArray[i].status){
156
- this.livesArray[i].lives = dataLives.filter((p: Conference | null) => {
157
- return null !== p;
158
- });
159
- }else if("PENDING"===this.livesArray[i].status){
160
- this.dataLivesToBe = dataLives;
161
- for (let index = 0, len = dataLives.length; index < len; index++) {
162
- if (dayjs(dataLives[index].date).isBefore(dayjs())) {
163
- this.livesArray[i].lives.push(dataLives[index]);
164
- indexPast = index + 1;
165
- } else {break;}
166
- }
167
- }else{
168
- this.livesArray[i].lives = this.dataLivesToBe
169
- .slice(indexPast)
170
- .concat(dataLives)
171
- .filter((p: Conference | null) => {
172
- return null !== p;
173
- });
174
- }
175
- return indexPast;
146
+ endLoading():void{
147
+ this.loading = false;
148
+ this.loaded = true;
176
149
  },
177
- async fetchLives(): Promise<void>{
178
- let indexPast = 0;
179
- this.dataLivesToBe = [];
180
- for (let i = 0, len = this.livesArray.length; i < len; i++) {
181
- if (!this.organisationRight &&
182
- ("DEBRIEFING"===this.livesArray[i].status ||"ERROR"===this.livesArray[i].status ||"PUBLISHING"===this.livesArray[i].status)) {
183
- continue;
184
- }
150
+ updateLive(live: Conference, index:number):void{
151
+ this.lives.splice(index, 1, live);
152
+ },
153
+ async fetchContent(): Promise<void> {
154
+ this.lives.length = 0;
155
+ if (!this.filterOrgaUsed || !this.isLiveAuthorized) {
156
+ this.endLoading();
157
+ return;
158
+ }
159
+ this.loading = true;
160
+ this.loaded = false;
161
+ try {
185
162
  const dataLives = await octopusApi.fetchDataWithParams<Array<Conference>>(9, 'conference/list',{
186
163
  organisationId: this.filterOrgaUsed,
187
164
  withPodcastId: true,
188
- status: this.livesArray[i].status,
165
+ status: "ALL"===this.selectedStatus ? this.statusFetched : this.selectedStatus,
166
+ });
167
+ this.lives = dataLives.filter((p: Conference | null) => {
168
+ return null !== p;
189
169
  });
190
- indexPast = this.liveTreatement(i, dataLives, indexPast);
191
- }
192
- },
193
- async fetchContent(): Promise<void> {
194
- try {
195
- this.initArrays();
196
- if (!this.filterOrgaUsed) {
197
- this.loading = false;
198
- this.loaded = true;
199
- return;
200
- }
201
- this.loading = true;
202
- this.loaded = false;
203
- await this.fetchLives();
204
- const listIds = this.livesArray[0].lives
205
- .concat(this.livesArray[1].lives)
206
- .concat(this.livesArray[2].lives);
207
- this.$emit('initConferenceIds', listIds);
208
170
  } catch (error) {
209
171
  this.handle403((error as AxiosError));
210
172
  }
211
- this.loading = false;
212
- this.loaded = true;
213
- },
214
- deleteLive(indexLives: number, index: number): void {
215
- this.livesArray[indexLives].lives.splice(index, 1);
173
+ this.endLoading();
216
174
  },
217
- updateLiveLocal(): void {
218
- for (
219
- let index = 0, len = this.conferenceWatched.length;
220
- index < len;
221
- index++
222
- ) {
223
- const element = this.conferenceWatched[index];
224
- const indexLivesToBe = this.livesArray[1].lives.findIndex(
225
- (el: Conference) => el.conferenceId === element.conferenceId
226
- );
227
- if (-1 === indexLivesToBe) {
228
- const indexLives = this.livesArray[0].lives.findIndex(
229
- (el: Conference) => el.conferenceId === element.conferenceId
230
- );
231
- if (-1 === indexLives || 'DEBRIEFING' !== element.status) continue;
232
- const newConf = this.livesArray[0].lives[indexLives];
233
- newConf.status = element.status;
234
- this.livesArray[0].lives.splice(indexLives, 1);
235
- this.livesArray[3].lives.push(newConf);
236
- break;
237
- }
238
- if ('RECORDING' !== element.status) continue;
239
- const newConf = this.livesArray[1].lives[indexLivesToBe];
240
- newConf.status = element.status;
241
- this.livesArray[1].lives.splice(indexLivesToBe, 1);
242
- this.livesArray[0].lives.push(newConf);
243
- break;
244
- }
175
+ deleteLive(index: number): void {
176
+ this.lives.splice(index, 1);
245
177
  },
246
178
  },
247
179
  })
248
180
  </script>
249
-
250
- <style lang="scss">
251
- .octopus-app{
252
- .live-list-category {
253
- align-self: flex-start;
254
- text-transform: uppercase;
255
- font-weight: bold;
256
- }
257
- }
258
- </style>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <div class="d-flex align-items-center">
3
+ <div v-if="currentlyPlayingString.length || podcastRadio" class="me-2 fw-bold">{{$t('Currently') +' : '}}</div>
4
+ <router-link
5
+ v-if="podcastRadio"
6
+ class="d-flex align-items-center"
7
+ :to="{
8
+ name: 'podcast',
9
+ params: { podcastId: podcastRadio.podcastId },
10
+ query: { productor: filterOrgaId },
11
+ }">
12
+ <img
13
+ v-lazy="proxyImageUrl(podcastRadio.imageUrl, '80')"
14
+ width="80"
15
+ height="80"
16
+ class="small-img-box"
17
+ :title="$t('Episode name image', {name:podcastRadio.title})"
18
+ :alt="$t('Episode name image', {name:podcastRadio.title})"
19
+ >
20
+ <div>{{podcastRadio.title}}</div>
21
+ </router-link>
22
+ <div v-else-if="currentlyPlayingString.length">{{currentlyPlayingString}}</div>
23
+ </div>
24
+ </template>
25
+
26
+ <script lang="ts">
27
+ import { usePlayerStore } from '@/stores/PlayerStore';
28
+ import { useFilterStore } from '@/stores/FilterStore';
29
+ import { mapState } from 'pinia';
30
+ import imageProxy from '../../mixins/imageProxy';
31
+ import {fetchRadioData} from '../../mixins/radio/fetchRadioData';
32
+ import { defineComponent } from 'vue';
33
+ import { Canal } from '@/stores/class/radio/canal';
34
+ import { MediaRadio } from '@/stores/class/general/player';
35
+ import { Podcast } from '@/stores/class/general/podcast';
36
+ export default defineComponent({
37
+ name: 'RadioItem',
38
+
39
+ components: {
40
+ },
41
+
42
+ mixins: [imageProxy, fetchRadioData],
43
+
44
+ props: {
45
+ radio: { default: undefined, type: Object as ()=>Canal},
46
+ },
47
+
48
+ data() {
49
+ return {
50
+ currentMetadata: undefined as undefined|MediaRadio,
51
+ currentPodcast: undefined as undefined|Podcast,
52
+ radioInterval: undefined as ReturnType<typeof setTimeout>|undefined,
53
+ };
54
+ },
55
+
56
+ computed:{
57
+ ...mapState(usePlayerStore, ['playerRadio']),
58
+ ...mapState(useFilterStore, ['filterOrgaId']),
59
+ playingRadio(){
60
+ return this.playerRadio && this.playerRadio.canalId === this.radio?.id;
61
+ },
62
+ podcastRadio():Podcast|undefined{
63
+ if(this.playingRadio){
64
+ return this.playerRadio?.podcast;
65
+ }
66
+ return this.currentPodcast;
67
+ },
68
+ currentlyPlayingString(): string{
69
+ if(this.playingRadio && this.playerRadio){
70
+ return this.displayTitle(this.playerRadio.metadata);
71
+ }
72
+ if(this.currentMetadata){
73
+ return this.displayTitle(this.currentMetadata);
74
+ }
75
+ return "";
76
+ }
77
+ },
78
+
79
+ mounted() {
80
+ this.fetchCurrentlyPlaying();
81
+ this.radioInterval = setInterval(() => {
82
+ this.fetchCurrentlyPlaying();
83
+ }, 1000);
84
+ },
85
+ methods: {
86
+ async fetchCurrentlyPlaying(): Promise<void>{
87
+ if(!this.radio || this.playingRadio){return;}
88
+ this.fetchRadioMetadata(this.radio.id,this.currentMetadata?.title??"", this.updateMetadata);
89
+ },
90
+ updateMetadata(metadata: MediaRadio, podcast?:Podcast): void{
91
+ this.currentMetadata=metadata;
92
+ this.currentPodcast=podcast;
93
+ },
94
+ },
95
+ })
96
+ </script>
97
+ <style lang="scss">
98
+ .octopus-app{
99
+ .small-img-box{
100
+ height: 80px;
101
+ width: 80px;
102
+ border-radius: 0.2rem;
103
+ overflow: hidden;
104
+ flex-shrink: 0;
105
+ margin: 0.5rem;
106
+ }
107
+ }
108
+ </style>
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <div class="img-box position-relative flex-shrink-0 mb-3 me-3 float-start">
3
+ <img
4
+ v-lazy="radio.imageUrl ?proxyImageUrl(radio.imageUrl, '330') :'/img/tempRadio.jpg'"
5
+ width="330"
6
+ height="330"
7
+ class="img-box"
8
+ :title="$t('Image')+ ' '+radio.name"
9
+ :alt="$t('Image')+ ' '+radio.name"
10
+ >
11
+ <button
12
+ class="image-play-button"
13
+ @click="playRadio"
14
+ >
15
+ <div class="icon-container">
16
+ <div
17
+ v-if="!playingRadio"
18
+ :title="$t('Play')"
19
+ class="saooti-play"
20
+ />
21
+ <div
22
+ v-else
23
+ class="bloc-paddle"
24
+ >
25
+ <span class="paddle1" />
26
+ <span class="paddle2" />
27
+ <span class="paddle3" />
28
+ </div>
29
+ <div class="ms-2">
30
+ {{ playText }}
31
+ </div>
32
+ </div>
33
+ </button>
34
+ </div>
35
+ </template>
36
+
37
+ <script lang="ts">
38
+ import { usePlayerStore } from '@/stores/PlayerStore';
39
+ import { useFilterStore } from '@/stores/FilterStore';
40
+ import { mapState, mapActions } from 'pinia';
41
+ import imageProxy from '../../mixins/imageProxy';
42
+ import { defineComponent } from 'vue';
43
+ import { Canal } from '@/stores/class/radio/canal';
44
+ export default defineComponent({
45
+ name: 'RadioImage',
46
+
47
+ components: {
48
+ },
49
+
50
+ mixins: [imageProxy],
51
+
52
+ props: {
53
+ radio: { default: undefined, type: Object as ()=>Canal},
54
+ },
55
+
56
+ computed:{
57
+ ...mapState(usePlayerStore, ['playerRadio', 'playerStatus']),
58
+ ...mapState(useFilterStore, ['filterOrgaId']),
59
+ playingRadio(){
60
+ return this.playerRadio && this.playerRadio.canalId === this.radio?.id;
61
+ },
62
+ playText(): string {
63
+ return this.playingRadio && "PLAYING"===this.playerStatus ? this.$t('Pause'):this.$t('Play');
64
+ },
65
+ },
66
+
67
+ methods: {
68
+ ...mapActions(usePlayerStore, ['playerPlay', 'playerChangeStatus']),
69
+ playRadio(): void{
70
+ if(!this.radio){return;}
71
+ if (this.playingRadio) {
72
+ this.playerChangeStatus("PLAYING"===this.playerStatus);
73
+ } else {
74
+ this.playerPlay({
75
+ canalId: this.radio.id,
76
+ url: "https://"+this.radio.url + "/live.m3u8",
77
+ metadata : ""
78
+ });
79
+ }
80
+ }
81
+ },
82
+ })
83
+ </script>
84
+
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div v-if="radio" class="d-flex border w-100 p-3">
3
+ <RadioImage :radio="radio"/>
4
+ <router-link
5
+ :to="{
6
+ name: 'radio',
7
+ params: { canalId: radio.id },
8
+ query: { productor: filterOrgaId },
9
+ }"
10
+ class="text-dark emission-item-text"
11
+ >
12
+ <div class="emission-name mb-2">{{ radio.name }}</div>
13
+ <div v-if="radio.description" class="ten-line-clamp">{{ radio.description }}</div>
14
+ <RadioCurrently :radio="radio"/>
15
+ </router-link>
16
+ </div>
17
+ </template>
18
+
19
+ <script lang="ts">
20
+ import { useFilterStore } from '@/stores/FilterStore';
21
+ import { mapState } from 'pinia';
22
+ import imageProxy from '../../mixins/imageProxy';
23
+ import RadioImage from './RadioImage.vue';
24
+ import RadioCurrently from './RadioCurrently.vue';
25
+ import { defineComponent } from 'vue';
26
+ import { Canal } from '@/stores/class/radio/canal';
27
+ export default defineComponent({
28
+ name: 'RadioItem',
29
+
30
+ components: {
31
+ RadioCurrently,
32
+ RadioImage
33
+ },
34
+ mixins: [imageProxy],
35
+
36
+ props: {
37
+ radio: { default: undefined, type: Object as ()=>Canal},
38
+ },
39
+ computed:{
40
+ ...mapState(useFilterStore, ['filterOrgaId']),
41
+ },
42
+ })
43
+ </script>
44
+
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <div
3
+ v-if="(filterOrgaId || organisationId) && radio.length"
4
+ class="d-flex flex-column align-items-start mt-3"
5
+ >
6
+ <h2 class="mb-0 big-h2 mb-3">{{ $t('Radio') }}</h2>
7
+ <template v-if="radio.length">
8
+ <RadioItem
9
+ v-for="radioItem in radio"
10
+ :key="radioItem.id"
11
+ :radio="radioItem"
12
+ />
13
+ </template>
14
+ </div>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ import RadioItem from './RadioItem.vue';
19
+ import { handle403 } from '../../mixins/handle403';
20
+ import { orgaComputed } from '../../mixins/orgaComputed';
21
+ import octopusApi from '@saooti/octopus-api';
22
+ import { useFilterStore } from '@/stores/FilterStore';
23
+ import { mapState } from 'pinia';
24
+ import { Canal } from '@/stores/class/radio/canal';
25
+ import { defineComponent } from 'vue'
26
+ import { AxiosError } from 'axios';
27
+ export default defineComponent({
28
+ name: 'ecbd98d9-79bd-4312-ad5e-fc7c1c4a191c',
29
+ components: {
30
+ RadioItem,
31
+ },
32
+
33
+ mixins: [handle403, orgaComputed],
34
+
35
+ props: {
36
+ organisationId: { default: undefined, type: String},
37
+ },
38
+ data() {
39
+ return {
40
+ radio: [] as Array<Canal>
41
+ };
42
+ },
43
+
44
+ computed: {
45
+ ...mapState(useFilterStore, ['filterOrgaId']),
46
+ filterOrgaUsed(): string|undefined {
47
+ return this.filterOrgaId?this.filterOrgaId:this.organisationId;
48
+ },
49
+ },
50
+ watch: {
51
+ filterOrgaUsed: {
52
+ async handler(): Promise<void> {
53
+ this.fetchContent();
54
+ },
55
+ immediate: true,
56
+ }
57
+ },
58
+ methods: {
59
+ async fetchContent(): Promise<void> {
60
+ this.radio.length = 0;
61
+ if (!this.filterOrgaUsed) {
62
+ return;
63
+ }
64
+ try {
65
+ this.radio = await octopusApi.fetchData<Array<Canal>>(14, 'canal/orga/'+this.filterOrgaUsed+'/');
66
+ } catch (error) {
67
+ this.handle403((error as AxiosError));
68
+ }
69
+ },
70
+ },
71
+ })
72
+ </script>
@@ -113,6 +113,7 @@ export default defineComponent({
113
113
  size: this.dsize,
114
114
  query: this.query,
115
115
  organisationId: this.organisation,
116
+ ambiance:"NONE",
116
117
  sort: this.sort,
117
118
  };
118
119
  try {