@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
package/index.ts CHANGED
@@ -13,6 +13,7 @@ export const getHome = () => import("./src/components/pages/Home.vue");
13
13
  export const getCategory = () => import("./src/components/pages/Category.vue");
14
14
  export const getRubrique = () => import("./src/components/pages/Rubrique.vue");
15
15
  export const getError403Page = () => import("./src/components/pages/Error403Page.vue");
16
+ export const getRadio = () => import("./src/components/pages/Radio.vue");
16
17
 
17
18
  //Misc
18
19
  export const getAccordion = () => import("./src/components/misc/Accordion.vue");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "36.0.10",
3
+ "version": "36.0.12",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
Binary file
@@ -33,6 +33,7 @@ body{
33
33
  &.link-hover{
34
34
  color: black !important;
35
35
  font-weight: 500;
36
+ word-break: normal;
36
37
  }
37
38
  &.link-hover:hover, &.link-hover.router-link-exact-active.router-link-active{
38
39
  color: $octopus-primary-color !important;
@@ -205,6 +206,14 @@ body{
205
206
  word-break: break-word;
206
207
  }
207
208
 
209
+ .ten-line-clamp{
210
+ overflow: hidden;
211
+ display: -webkit-box;
212
+ -webkit-line-clamp: 10;
213
+ -webkit-box-orient: vertical;
214
+ word-break: break-word;
215
+ }
216
+
208
217
  .html-wysiwyg-content{
209
218
  h3,h4{
210
219
  margin: 0 0 0.5em 0 !important;
@@ -0,0 +1,11 @@
1
+ .octopus-app{
2
+ iframe{
3
+ border:0;
4
+ }
5
+ .max-iframe {
6
+ width: 500px;
7
+ @media (max-width: 960px){
8
+ width: calc(100% - 2rem);
9
+ }
10
+ }
11
+ }
@@ -253,4 +253,42 @@
253
253
  }
254
254
  }
255
255
  }
256
+ .image-play-button{
257
+ position: absolute;
258
+ display: flex;
259
+ justify-content: flex-end;
260
+ top: 0;
261
+ left: 0;
262
+ right: 0;
263
+ bottom: 0;
264
+ cursor: pointer;
265
+ flex-direction: column;
266
+ background: transparent;
267
+ border-width: 0;
268
+ width: 100%;
269
+ padding: 0;
270
+ &:focus{
271
+ background: rgba(0, 0, 0, 0.09);
272
+ }
273
+ .icon-container {
274
+ background: $primaryColorLessTransparent !important;
275
+ border-radius: 2rem;
276
+ color: white;
277
+ padding: 0.5rem;
278
+ margin: 0.5rem;
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ z-index: 2;
283
+
284
+ &:hover {
285
+ background: #00000030;
286
+ }
287
+ .saooti-play {
288
+ font-size: 1.2rem;
289
+ position: relative;
290
+ color: white;
291
+ }
292
+ }
293
+ }
256
294
  }
@@ -5,9 +5,8 @@
5
5
  .bloc-paddle {
6
6
  align-items: flex-end;
7
7
  display: flex;
8
- width: 2rem;
9
- height: 2.6rem;
10
- padding: 0.7rem;
8
+ width: 0.9rem;
9
+ height: 1.2rem;
11
10
  justify-content: space-around;
12
11
  align-content: flex-start;
13
12
  border-radius: 50%;
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <div />
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import { defineComponent } from 'vue'
7
+ export default defineComponent({
8
+ methods:{
9
+ }
10
+ })
11
+ </script>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <swiper
3
+ :slides-per-view="numberItem"
4
+ :space-between="0"
5
+ :loop="listObject.length>=numberItem"
6
+ :navigation="true"
7
+ :modules="modules"
8
+ >
9
+ <swiper-slide
10
+ v-for="(obj, index) in listObject"
11
+ :key="obj"
12
+ >
13
+ <slot
14
+ name="octopusSlide"
15
+ :option="obj"
16
+ :index="index"
17
+ />
18
+ </swiper-slide>
19
+ </swiper>
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ import domHelper from '../../../helper/dom';
24
+ import { state } from '../../../stores/ParamSdkStore';
25
+ import { Swiper, SwiperSlide } from "swiper/vue";
26
+ import { Navigation } from "swiper";
27
+ import "swiper/css";
28
+ import "swiper/css/navigation";
29
+ import { defineComponent } from 'vue'
30
+ export default defineComponent({
31
+ name: 'SwiperList',
32
+
33
+ components: {
34
+ Swiper,
35
+ SwiperSlide,
36
+ },
37
+
38
+ props: {
39
+ listObject: { default: [], type: Array as ()=> Array<unknown>},
40
+ },
41
+
42
+ data() {
43
+ return {
44
+ modules: [Navigation],
45
+ numberItem: 5 as number
46
+ };
47
+ },
48
+ computed: {
49
+ sizeItem(): number {
50
+ if (window.innerWidth <= 450) {
51
+ return 12.5;
52
+ }
53
+ return state.generalParameters.podcastItem ? state.generalParameters.podcastItem: 16.5;
54
+ },
55
+ },
56
+
57
+ created() {
58
+ window.addEventListener('resize', this.handleResize);
59
+ },
60
+ unmounted() {
61
+ window.removeEventListener('resize', this.handleResize);
62
+ },
63
+
64
+ mounted() {
65
+ this.handleResize();
66
+ },
67
+ methods: {
68
+ handleResize(): void {
69
+ if (!this.$el) return;
70
+ const width = (this.$el as HTMLElement).offsetWidth - 95;
71
+ const sixteen = domHelper.convertRemToPixels(this.sizeItem+ 0.5);
72
+ this.numberItem = Math.max(1, Math.floor(width / sixteen));
73
+ },
74
+ },
75
+ })
76
+ </script>
77
+ <style lang="scss">
78
+ @import '@scss/_variables.scss';
79
+ .swiper {
80
+ width: 100%;
81
+ height: 100%;
82
+ }
83
+ .swiper-button-next, .swiper-button-prev{
84
+ color: $octopus-primary-color !important;
85
+ height: 100%;
86
+ top: 0;
87
+ bottom: 0;
88
+ margin: 0;
89
+ }
90
+ .swiper-button-next{
91
+ right: 0;
92
+ }
93
+ .swiper-button-prev{
94
+ left: 0;
95
+ }
96
+ .swiper-slide-active{
97
+ padding-left:27px;
98
+ @media (max-width: 550px) {
99
+ padding-left:0;
100
+ }
101
+ }
102
+ .swiper-slide-next{
103
+ padding-right:27px;
104
+ }
105
+ .swiper-button-lock{
106
+ display: flex;
107
+ }
108
+ .swiper-slide {
109
+ display: flex;
110
+ justify-content: center;
111
+ align-items: center;
112
+ }
113
+ </style>
@@ -1,148 +1,30 @@
1
1
  <template>
2
- <div
3
- v-if="live"
4
- class="d-flex-column live-item-container w-100"
5
- >
6
- <router-link
7
- class="live-date-box"
8
- :to="{
9
- name: 'podcast',
10
- params: { podcastId: live.podcastId },
11
- query: { productor: filterOrgaId },
12
- }"
13
- >
14
- <div class="fw-bold">
15
- {{ date }}
16
- </div>
17
- <div class="fw-bold">
18
- {{ hours }}
19
- </div>
20
- <div class="font-size-smaller">
21
- {{ $t('Duration', { duration: duration }) }}
22
- </div>
23
- </router-link>
24
- <router-link
25
- :to="{
26
- name: 'podcast',
27
- params: { podcastId: live.podcastId },
28
- query: { productor: filterOrgaId },
29
- }"
30
- >
31
- <PodcastImage
32
- class="me-3 flex-shrink-0"
33
- :podcast="live"
34
- :hide-play="false"
35
- :playing-podcast="false"
36
- :fetch-conference="fetchConference"
37
- :is-animator-live="organisationRight"
38
- />
39
- </router-link>
40
- <div class="d-flex flex-column">
41
- <router-link
42
- class="text-uppercase fw-bold text-truncate"
43
- :to="{
44
- name: 'podcast',
45
- params: { podcastId: live.podcastId },
46
- query: { productor: filterOrgaId },
47
- }"
48
- >
49
- {{ live.title }}
50
- </router-link>
51
- <router-link
52
- class="fw-bold text-truncate"
53
- :to="{
54
- name: 'emission',
55
- params: { emissionId: live.emission.emissionId },
56
- query: { productor: filterOrgaId },
57
- }"
58
- >
59
- {{ live.emission.name }}
60
- </router-link>
61
- <div
62
- ref="descriptionLiveContainer"
63
- class="live-description-container html-wysiwyg-content"
64
- >
65
- <!-- eslint-disable vue/no-v-html -->
66
- <div
67
- ref="descriptionLive"
68
- v-html="urlify(description)"
69
- />
70
- <!-- eslint-enable -->
71
- </div>
72
- <div
73
- v-if="live.animators"
74
- class="comma"
75
- >
76
- {{ $t('Animated by') }}<div class="mx-1">
77
- :
78
- </div>
79
- <router-link
80
- v-for="animator in live.animators"
81
- :key="animator.participantId"
82
- :title="$t('Participant')"
83
- class="fw-bold"
84
- :to="{
85
- name: 'participant',
86
- params: { participantId: animator.participantId },
87
- query: { productor: filterOrgaId },
88
- }"
89
- >
90
- {{ getName(animator) }}
91
- </router-link>
92
- </div>
93
- <div v-if="!isPodcastmaker">
94
- {{ $t('Producted by : ') }}
95
- <router-link
96
- class="fw-bold"
97
- :to="{
98
- name: 'productor',
99
- params: { productorId: live.organisation.id },
100
- query: { productor: filterOrgaId },
101
- }"
102
- >
103
- {{ live.organisation.name }}
104
- </router-link>
105
- </div>
106
- <RecordingItemButton
107
- v-if="fetchConference && organisationRight && isEditBox"
108
- :live="true"
109
- :recording="fetchConference"
110
- :podcast="live"
111
- @deleteItem="deleteItem"
112
- @validatePodcast="updatePodcast"
113
- />
114
- </div>
115
- </div>
2
+ <PodcastItem
3
+ v-if="live && 0!==live.podcastId"
4
+ :podcast="live"
5
+ :fetch-conference="fetchConference"
6
+ />
116
7
  </template>
117
8
 
118
9
  <script lang="ts">
119
- import { state } from '../../../stores/ParamSdkStore';
120
10
  import octopusApi from '@saooti/octopus-api';
121
- import PodcastImage from '../podcasts/PodcastImage.vue';
11
+ import PodcastItem from '../podcasts/PodcastItem.vue';
122
12
  import crudApi from '@/api/classicCrud';
123
- import dayjs from 'dayjs';
124
- // @ts-ignore
125
- import humanizeDuration from 'humanize-duration';
126
13
  import displayMethods from '../../mixins/displayMethods';
127
14
  import { Podcast } from '@/stores/class/general/podcast';
128
- import { Participant } from '@/stores/class/general/participant';
129
- import { useFilterStore } from '@/stores/FilterStore';
130
- import { mapState } from 'pinia';
131
- import { defineComponent, defineAsyncComponent } from 'vue';
132
- const RecordingItemButton = defineAsyncComponent(() => import('@/components/display/studio/RecordingItemButton.vue'));
15
+ import { defineComponent } from 'vue';
16
+ import { Conference } from '@/stores/class/conference/conference';
133
17
  export default defineComponent({
134
18
  name: 'LiveItem',
135
19
 
136
20
  components: {
137
- RecordingItemButton,
138
- PodcastImage,
21
+ PodcastItem,
139
22
  },
140
23
  mixins: [displayMethods],
141
24
  props: {
142
- fetchConference: { default: undefined, type: Object as ()=>Podcast},
143
- index: { default: undefined, type: Number},
25
+ fetchConference: { default: undefined, type: Object as ()=>Conference},
144
26
  },
145
- emits: ['deleteItem'],
27
+ emits: ['deleteItem', 'updateItem'],
146
28
 
147
29
  data() {
148
30
  return {
@@ -150,134 +32,36 @@ export default defineComponent({
150
32
  };
151
33
  },
152
34
 
153
- computed: {
154
- ...mapState(useFilterStore, ['filterOrgaId']),
155
- isEditBox(): boolean {
156
- return (state.podcastPage.EditBox as boolean);
157
- },
158
- isPodcastmaker(): boolean {
159
- return (state.generalParameters.podcastmaker as boolean);
160
- },
161
- hours(): string {
162
- return !this.live?'': dayjs(this.live.pubDate).format('HH[H]mm');
163
- },
164
- date(): string {
165
- return !this.live? '': dayjs(this.live.pubDate).format('D/MM/YYYY');
166
- },
167
- description(): string {
168
- return this.live?.description??'';
169
- },
170
- myOrganisationId(): string|undefined {
171
- return state.generalParameters.organisationId;
172
- },
173
- organisationRight(): boolean {
174
- return true===this.isRoleLive && this.myOrganisationId === this.live?.organisation.id;
175
- },
176
- isRoleLive(): boolean {
177
- return (state.generalParameters.isRoleLive as boolean);
178
- },
179
- duration(): string {
180
- if (!this.live || this.live.duration <= 1) return '';
181
- if (this.live.duration > 600000) {
182
- return humanizeDuration(this.live.duration, {
183
- language: this.$i18n.locale,
184
- largest: 1,
185
- round: true,
186
- });
187
- }
188
- return humanizeDuration(this.live.duration, {
189
- language: this.$i18n.locale,
190
- largest: 2,
191
- round: true,
192
- });
193
- },
194
- },
195
- watch: {
196
- live: {
197
- deep: true,
198
- handler(){
199
- this.handleDescription();
200
- }
201
- },
202
- },
203
-
204
35
  async created() {
205
36
  this.fetchPodcastData();
37
+ this.watchStatus();
206
38
  },
207
39
  methods: {
208
- updatePodcast(podcastUpdated: Podcast): void {
209
- this.live = podcastUpdated;
210
- },
211
- getName(person: Participant): string {
212
- return (`${person.firstName??''} ${person.lastName??''}`).trim();
213
- },
214
40
  async fetchPodcastData(): Promise<void> {
215
41
  if (!this.fetchConference || !this.fetchConference.podcastId) return;
216
42
  try {
217
43
  this.live = await octopusApi.fetchData<Podcast>(0, 'podcast/'+this.fetchConference.podcastId);
218
44
  } catch {
219
- this.$emit('deleteItem', this.index);
45
+ this.$emit('deleteItem');
220
46
  if(this.fetchConference.conferenceId){
221
47
  await crudApi.deleteData(9 ,'conference/'+this.fetchConference.conferenceId);
222
48
  }
223
49
  }
224
50
  },
225
- async handleDescription(): Promise<void> {
226
- this.$nextTick(() => {
227
- if(!this.live){
228
- return;
229
- }
230
- const liveDesc = (this.$refs.descriptionLive as HTMLElement);
231
- const liveDescContainer = (this.$refs.descriptionLiveContainer as HTMLElement);
232
- if (
233
- null !== liveDesc && null !== liveDescContainer &&
234
- liveDesc.clientHeight > liveDescContainer.clientHeight
235
- ) {
236
- liveDescContainer.classList.add('after-live-description');
237
- }
238
- });
239
- },
240
- deleteItem(): void {
241
- this.$emit('deleteItem', this.index);
242
- },
51
+ async watchStatus():Promise<void>{
52
+ if(!this.fetchConference || ("PLANNED"!==this.fetchConference.status && "PENDING"!==this.fetchConference.status && "RECORDING"!==this.fetchConference.status)){
53
+ return;
54
+ }
55
+ const newStatus = await octopusApi.fetchData<string>(9, 'conference/realstatus/'+this.fetchConference.conferenceId);
56
+ if(newStatus !== this.fetchConference.status){
57
+ this.$emit('updateItem', {...this.fetchConference, ...{status: newStatus}});
58
+ }else{
59
+ setTimeout(() => {
60
+ this.watchStatus();
61
+ }, 5000);
62
+ }
63
+ }
243
64
  },
244
65
  })
245
66
  </script>
246
67
 
247
- <style lang="scss">
248
- .octopus-app{
249
- .live-item-container{
250
- @media (max-width: 960px) {
251
- align-items: center;
252
- justify-content: center;
253
- }
254
- }
255
- .live-date-box {
256
- width: 200px;
257
- display: flex;
258
- flex-shrink: 0;
259
- flex-direction: column;
260
- }
261
- .font-size-smaller {
262
- font-size: smaller;
263
- }
264
- .live-description-container {
265
- overflow: hidden;
266
- margin-top: 0.5em;
267
- word-break: break-word;
268
- max-height: 6rem;
269
- position: relative;
270
- &.after-live-description:after {
271
- content: '...';
272
- position: absolute;
273
- padding-left: 1rem;
274
- right: 0;
275
- bottom: 0;
276
- width: 100%;
277
- font-size: 1rem;
278
- font-weight: bolder;
279
- background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #f3f3f3 40%);
280
- }
281
- }
282
- }
283
- </style>