@saooti/octopus-sdk 36.0.10 → 36.0.12

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/index.ts +1 -0
  2. package/package.json +1 -1
  3. package/public/img/tempRadio.jpg +0 -0
  4. package/src/assets/general.scss +9 -0
  5. package/src/assets/iframe.scss +11 -0
  6. package/src/assets/share.scss +38 -0
  7. package/src/assets/transition.scss +2 -3
  8. package/src/components/display/edit/EditBoxRadio.vue +11 -0
  9. package/src/components/display/list/SwiperList.vue +113 -0
  10. package/src/components/display/live/LiveItem.vue +26 -242
  11. package/src/components/display/live/LiveList.vue +113 -189
  12. package/src/components/display/live/RadioCurrently.vue +116 -0
  13. package/src/components/display/live/RadioImage.vue +84 -0
  14. package/src/components/display/live/RadioItem.vue +54 -0
  15. package/src/components/display/live/RadioList.vue +74 -0
  16. package/src/components/display/playlist/PlaylistList.vue +1 -0
  17. package/src/components/display/podcasts/PodcastImage.vue +15 -48
  18. package/src/components/display/podcasts/PodcastItem.vue +3 -0
  19. package/src/components/display/podcasts/PodcastSwiperList.vue +9 -80
  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 +45 -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 +117 -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,47 @@
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">
8
+ {{ $t('Live') }}
9
+ </h2>
10
+ <router-link
11
+ v-if="liveRight && !isPodcastmaker"
12
+ to="/main/priv/edit/live"
13
+ >
14
+ <button class="btn btn-primary">
15
+ {{ $t('Launch a new live') }}
16
+ </button>
17
+ </router-link>
18
+ </div>
19
+ <ClassicSelect
20
+ v-if="lives.length || 'ALL'!==selectedStatus"
21
+ v-model:textInit="selectedStatus"
22
+ id-select="status-live-chooser-select"
23
+ :label="$t('Selection by status')"
24
+ :display-label="false"
25
+ :options="statusArraySelect"
26
+ class="mb-3"
27
+ />
6
28
  <ClassicLoading
7
29
  :loading-text="loading?$t('Loading lives...'):undefined"
8
- :error-text="isNoLive?$t('No live currently'):undefined"
30
+ :error-text="0===lives.length?$t('No live currently'):undefined"
9
31
  />
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>
32
+ <template v-if="lives.length">
33
+ <SwiperList
34
+ v-if="!loading"
35
+ :list-object="lives"
36
+ >
37
+ <template #octopusSlide="{option, index}">
38
+ <LiveItem
39
+ :fetch-conference="option"
40
+ @deleteItem="deleteLive(index)"
41
+ @updateItem="updateLive($event, index)"
42
+ />
43
+ </template>
44
+ </SwiperList>
33
45
  </template>
34
46
  </div>
35
47
  </template>
@@ -37,12 +49,13 @@
37
49
  <script lang="ts">
38
50
  import ClassicLoading from '../../form/ClassicLoading.vue';
39
51
  import LiveItem from './LiveItem.vue';
52
+ import ClassicSelect from '../../form/ClassicSelect.vue';
53
+ import SwiperList from '../list/SwiperList.vue';
40
54
  import { handle403 } from '../../mixins/handle403';
55
+ import { orgaComputed } from '../../mixins/orgaComputed';
41
56
  import octopusApi from '@saooti/octopus-api';
42
- import dayjs from 'dayjs';
43
- import localizedFormat from 'dayjs/plugin/localizedFormat';
44
- dayjs.extend(localizedFormat);
45
57
  import { useFilterStore } from '@/stores/FilterStore';
58
+ import { useAuthStore } from '@/stores/AuthStore';
46
59
  import { mapState } from 'pinia';
47
60
  import { state } from '../../../stores/ParamSdkStore';
48
61
  import { Conference } from '@/stores/class/conference/conference';
@@ -52,207 +65,118 @@ export default defineComponent({
52
65
  name: 'LiveList',
53
66
  components: {
54
67
  LiveItem,
55
- ClassicLoading
68
+ ClassicLoading,
69
+ SwiperList,
70
+ ClassicSelect
56
71
  },
57
72
 
58
- mixins: [handle403],
73
+ mixins: [handle403, orgaComputed],
59
74
 
60
75
  props: {
61
- conferenceWatched: { default: () => [], type: Array as ()=>Array<Conference>},
62
76
  organisationId: { default: undefined, type: String},
63
77
  },
64
- emits: ['initConferenceIds'],
65
78
  data() {
66
79
  return {
67
80
  loading: true as boolean,
68
81
  loaded: true as boolean,
69
- dataLivesToBe: [] as Array<Conference>
82
+ lives: [] as Array<Conference>,
83
+ isLiveAuthorized: false as boolean,
84
+ statusClassic: ["RECORDING", "PENDING", "PLANNED"] as Array<string>,
85
+ statusAdmin: ["DEBRIEFING", "ERROR", "PUBLISHING"] as Array<string>,
86
+ selectedStatus: "ALL" as string
70
87
  };
71
88
  },
72
89
 
73
90
  computed: {
74
91
  ...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
- },
92
+ ...mapState(useAuthStore, ['authOrganisation']),
88
93
  filterOrgaUsed(): string|undefined {
89
94
  return this.filterOrgaId?this.filterOrgaId:this.organisationId;
90
95
  },
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();
96
+ editRight(): boolean {
97
+ return (true ===this.authenticated && this.myOrganisationId === this.filterOrgaUsed) ||true===state.generalParameters.isAdmin;
98
+ },
99
+ liveRight(): boolean {
100
+ return (state.generalParameters.isRoleLive as boolean)&& true===this.authOrganisation.attributes?.['live.active'];
101
+ },
102
+ isPodcastmaker(): boolean {
103
+ return (state.generalParameters.podcastmaker as boolean);
104
+ },
105
+ statusArraySelect(): Array<{title: string, value:string}>{
106
+ const statusArray =[{title: this.$t('All lives'), value:'ALL'}];
107
+ for(let status of this.statusFetched){
108
+ let title ="";
109
+ switch (status) {
110
+ case "RECORDING": title = this.$t('In live'); break;
111
+ case "PENDING": title = this.$t('live upcoming'); break;
112
+ case "PLANNED": title = this.$t('live in few time'); break;
113
+ case "DEBRIEFING": title = this.$t('In debriefing'); break;
114
+ case "PUBLISHING": title = this.$t('In the process of being published'); break;
115
+ case "ERROR": title = this.$t('In error'); break;
116
+ default: break;
116
117
  }
117
- } else {
118
- this.initArrays();
119
- this.loading = false;
120
- this.loaded = true;
118
+ statusArray.push({title: title, value: status});
121
119
  }
120
+ return statusArray;
122
121
  },
123
- filterOrgaId(): void {
124
- if(!this.loading){
125
- this.fetchContent();
122
+ statusFetched(): Array<string>{
123
+ if(this.editRight){
124
+ return this.statusClassic.concat(this.statusAdmin);
126
125
  }
127
- },
128
- conferenceWatched: {
129
- handler(): void {
130
- this.updateLiveLocal();
126
+ return this.statusClassic;
127
+ }
128
+ },
129
+ watch: {
130
+ filterOrgaUsed: {
131
+ async handler(): Promise<void> {
132
+ await this.checkIfLiveAuthorized();
133
+ this.fetchContent();
131
134
  },
132
- deep: true,
135
+ immediate: true,
133
136
  },
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) {
137
+ selectedStatus(){
142
138
  this.fetchContent();
143
- } else {
144
- this.loading = false;
145
- this.loaded = true;
146
139
  }
147
140
  },
148
141
  methods: {
149
- initArrays(): void {
150
- for (let i = 0, len = this.livesArray.length; i < len; i++) {
151
- this.livesArray[i].lives.length = 0;
142
+ async checkIfLiveAuthorized(): Promise<void>{
143
+ if(!this.filterOrgaUsed){
144
+ return;
152
145
  }
146
+ this.isLiveAuthorized = await octopusApi.fetchData<boolean>(0, 'organisation/liveEnabled/'+this.filterOrgaUsed);
153
147
  },
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;
148
+ endLoading():void{
149
+ this.loading = false;
150
+ this.loaded = true;
176
151
  },
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
- }
152
+ updateLive(live: Conference, index:number):void{
153
+ this.lives.splice(index, 1, live);
154
+ },
155
+ async fetchContent(): Promise<void> {
156
+ this.lives.length = 0;
157
+ if (!this.filterOrgaUsed || !this.isLiveAuthorized) {
158
+ this.endLoading();
159
+ return;
160
+ }
161
+ this.loading = true;
162
+ this.loaded = false;
163
+ try {
185
164
  const dataLives = await octopusApi.fetchDataWithParams<Array<Conference>>(9, 'conference/list',{
186
165
  organisationId: this.filterOrgaUsed,
187
166
  withPodcastId: true,
188
- status: this.livesArray[i].status,
167
+ status: "ALL"===this.selectedStatus ? this.statusFetched : this.selectedStatus,
168
+ });
169
+ this.lives = dataLives.filter((p: Conference | null) => {
170
+ return null !== p;
189
171
  });
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
172
  } catch (error) {
209
173
  this.handle403((error as AxiosError));
210
174
  }
211
- this.loading = false;
212
- this.loaded = true;
213
- },
214
- deleteLive(indexLives: number, index: number): void {
215
- this.livesArray[indexLives].lives.splice(index, 1);
175
+ this.endLoading();
216
176
  },
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
- }
177
+ deleteLive(index: number): void {
178
+ this.lives.splice(index, 1);
245
179
  },
246
180
  },
247
181
  })
248
182
  </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,116 @@
1
+ <template>
2
+ <div class="d-flex align-items-center">
3
+ <div
4
+ v-if="currentlyPlayingString.length || podcastRadio"
5
+ class="me-2 fw-bold"
6
+ >
7
+ {{ $t('Currently') +' : ' }}
8
+ </div>
9
+ <router-link
10
+ v-if="podcastRadio"
11
+ class="d-flex align-items-center"
12
+ :to="{
13
+ name: 'podcast',
14
+ params: { podcastId: podcastRadio.podcastId },
15
+ query: { productor: filterOrgaId },
16
+ }"
17
+ >
18
+ <img
19
+ v-lazy="proxyImageUrl(podcastRadio.imageUrl, '80')"
20
+ width="80"
21
+ height="80"
22
+ class="small-img-box"
23
+ :title="$t('Episode name image', {name:podcastRadio.title})"
24
+ :alt="$t('Episode name image', {name:podcastRadio.title})"
25
+ >
26
+ <div>{{ podcastRadio.title }}</div>
27
+ </router-link>
28
+ <div v-else-if="currentlyPlayingString.length">
29
+ {{ currentlyPlayingString }}
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <script lang="ts">
35
+ import { usePlayerStore } from '@/stores/PlayerStore';
36
+ import { useFilterStore } from '@/stores/FilterStore';
37
+ import { mapState } from 'pinia';
38
+ import imageProxy from '../../mixins/imageProxy';
39
+ import {fetchRadioData} from '../../mixins/radio/fetchRadioData';
40
+ import { defineComponent } from 'vue';
41
+ import { Canal } from '@/stores/class/radio/canal';
42
+ import { MediaRadio } from '@/stores/class/general/player';
43
+ import { Podcast } from '@/stores/class/general/podcast';
44
+ export default defineComponent({
45
+ name: 'RadioItem',
46
+
47
+ components: {
48
+ },
49
+
50
+ mixins: [imageProxy, fetchRadioData],
51
+
52
+ props: {
53
+ radio: { default: undefined, type: Object as ()=>Canal},
54
+ },
55
+
56
+ data() {
57
+ return {
58
+ currentMetadata: undefined as undefined|MediaRadio,
59
+ currentPodcast: undefined as undefined|Podcast,
60
+ radioInterval: undefined as ReturnType<typeof setTimeout>|undefined,
61
+ };
62
+ },
63
+
64
+ computed:{
65
+ ...mapState(usePlayerStore, ['playerRadio']),
66
+ ...mapState(useFilterStore, ['filterOrgaId']),
67
+ playingRadio(){
68
+ return this.playerRadio && this.playerRadio.canalId === this.radio?.id;
69
+ },
70
+ podcastRadio():Podcast|undefined{
71
+ if(this.playingRadio){
72
+ return this.playerRadio?.podcast;
73
+ }
74
+ return this.currentPodcast;
75
+ },
76
+ currentlyPlayingString(): string{
77
+ if(this.playingRadio && this.playerRadio){
78
+ return this.displayTitle(this.playerRadio.metadata);
79
+ }
80
+ if(this.currentMetadata){
81
+ return this.displayTitle(this.currentMetadata);
82
+ }
83
+ return "";
84
+ }
85
+ },
86
+
87
+ mounted() {
88
+ this.fetchCurrentlyPlaying();
89
+ this.radioInterval = setInterval(() => {
90
+ this.fetchCurrentlyPlaying();
91
+ }, 1000);
92
+ },
93
+ methods: {
94
+ async fetchCurrentlyPlaying(): Promise<void>{
95
+ if(!this.radio || this.playingRadio){return;}
96
+ this.fetchRadioMetadata(this.radio.id,this.currentMetadata?.title??"", this.updateMetadata);
97
+ },
98
+ updateMetadata(metadata: MediaRadio, podcast?:Podcast): void{
99
+ this.currentMetadata=metadata;
100
+ this.currentPodcast=podcast;
101
+ },
102
+ },
103
+ })
104
+ </script>
105
+ <style lang="scss">
106
+ .octopus-app{
107
+ .small-img-box{
108
+ height: 80px;
109
+ width: 80px;
110
+ border-radius: 0.2rem;
111
+ overflow: hidden;
112
+ flex-shrink: 0;
113
+ margin: 0.5rem;
114
+ }
115
+ }
116
+ </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,54 @@
1
+ <template>
2
+ <div
3
+ v-if="radio"
4
+ class="d-flex border w-100 p-3"
5
+ >
6
+ <RadioImage :radio="radio" />
7
+ <router-link
8
+ :to="{
9
+ name: 'radio',
10
+ params: { canalId: radio.id },
11
+ query: { productor: filterOrgaId },
12
+ }"
13
+ class="text-dark emission-item-text"
14
+ >
15
+ <div class="emission-name mb-2">
16
+ {{ radio.name }}
17
+ </div>
18
+ <div
19
+ v-if="radio.description"
20
+ class="ten-line-clamp"
21
+ >
22
+ {{ radio.description }}
23
+ </div>
24
+ <RadioCurrently :radio="radio" />
25
+ </router-link>
26
+ </div>
27
+ </template>
28
+
29
+ <script lang="ts">
30
+ import { useFilterStore } from '@/stores/FilterStore';
31
+ import { mapState } from 'pinia';
32
+ import imageProxy from '../../mixins/imageProxy';
33
+ import RadioImage from './RadioImage.vue';
34
+ import RadioCurrently from './RadioCurrently.vue';
35
+ import { defineComponent } from 'vue';
36
+ import { Canal } from '@/stores/class/radio/canal';
37
+ export default defineComponent({
38
+ name: 'RadioItem',
39
+
40
+ components: {
41
+ RadioCurrently,
42
+ RadioImage
43
+ },
44
+ mixins: [imageProxy],
45
+
46
+ props: {
47
+ radio: { default: undefined, type: Object as ()=>Canal},
48
+ },
49
+ computed:{
50
+ ...mapState(useFilterStore, ['filterOrgaId']),
51
+ },
52
+ })
53
+ </script>
54
+