@saooti/octopus-sdk 36.0.36 → 37.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "36.0.36",
3
+ "version": "37.0.0",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
@@ -0,0 +1,50 @@
1
+ @import '@scss/_variables.scss';
2
+ .octopus-app{
3
+ .octopus-progress{
4
+ display: flex;
5
+ overflow: hidden;
6
+ background-color:#e9ecef;
7
+ border-radius: $octopus-borderradius;
8
+ position: relative;
9
+ cursor: pointer;
10
+
11
+ .octopus-progress-bar{
12
+ position: absolute;
13
+ display: flex;
14
+ flex-direction: column;
15
+ justify-content: center;
16
+ overflow: hidden;
17
+ color: white;
18
+ text-align: center;
19
+ white-space: nowrap;
20
+ background-color: $octopus-primary-color;
21
+ transition: width 0.6s ease;
22
+ }
23
+ &,.octopus-progress-bar{
24
+ height: 4px;
25
+ @media (max-width: 960px) {
26
+ height: 8px;
27
+ }
28
+ }
29
+ &.large,&.large .octopus-progress-bar{
30
+ height: 15px;
31
+ }
32
+ &.medium,&.medium .octopus-progress-bar{
33
+ height: 6px;
34
+ }
35
+ .octopus-progress-bar-duration {
36
+ width: 10px;
37
+ }
38
+ .octopus-progress-bar-cursor{
39
+ width: 10px;
40
+ height: 10px;
41
+ border-radius: 50%;
42
+ background: black;
43
+ align-self: center;
44
+ position: absolute;
45
+ }
46
+ .end-0{
47
+ right: 0;
48
+ }
49
+ }
50
+ }
@@ -88,7 +88,7 @@ export default defineComponent({
88
88
  this.fetchCurrentlyPlaying();
89
89
  this.radioInterval = setInterval(() => {
90
90
  this.fetchCurrentlyPlaying();
91
- }, 5000);
91
+ }, 10000);
92
92
  },
93
93
  methods: {
94
94
  async fetchCurrentlyPlaying(): Promise<void>{
@@ -214,7 +214,7 @@ export default defineComponent({
214
214
  case 'RECORDING':
215
215
  return this.$t('In live');
216
216
  case 'DEBRIEFING':
217
- if (!this.isAnimatorLive) return '';
217
+ /* if (!this.isAnimatorLive) return ''; */
218
218
  if ('READY_TO_RECORD' === this.podcast.processingStatus)
219
219
  return this.$t('Not recording');
220
220
  return this.$t('Debriefing');
@@ -135,7 +135,6 @@
135
135
  v-if="
136
136
  !!fetchConference &&
137
137
  isLiveReadyToRecord &&
138
- !isNotRecorded &&
139
138
  isOctopusAndAnimator
140
139
  "
141
140
  :podcast="podcast"
@@ -147,6 +146,7 @@
147
146
  <EditBox
148
147
  v-else-if="editRight && isEditBox"
149
148
  :podcast="podcast"
149
+ :display-studio-access="isDebriefing"
150
150
  @validatePodcast="$emit('updatePodcast', $event)"
151
151
  />
152
152
  <TagList
@@ -243,9 +243,8 @@ export default defineComponent({
243
243
  'READY' === this.podcast?.processingStatus
244
244
  );
245
245
  },
246
- isNotRecorded(): boolean {
246
+ isDebriefing(): boolean {
247
247
  return (
248
- this.isLiveReadyToRecord &&
249
248
  undefined!==this.fetchConference &&
250
249
  'DEBRIEFING' === this.fetchConference.status
251
250
  );
@@ -169,7 +169,7 @@ export default defineComponent({
169
169
  min-width: 200px;
170
170
  .octopus-dropdown-item{
171
171
  display: flex;
172
- justify-content: center;
172
+ justify-content: center;
173
173
  color: rgb(29, 29, 29);
174
174
  width: 100%;
175
175
  padding: 0.25rem 1rem;
@@ -99,54 +99,5 @@ export default defineComponent({
99
99
  </script>
100
100
 
101
101
  <style lang="scss">
102
- @import '@scss/_variables.scss';
103
- .octopus-app{
104
- .octopus-progress{
105
- display: flex;
106
- overflow: hidden;
107
- background-color:#e9ecef;
108
- border-radius: $octopus-borderradius;
109
- position: relative;
110
- cursor: pointer;
111
-
112
- .octopus-progress-bar{
113
- position: absolute;
114
- display: flex;
115
- flex-direction: column;
116
- justify-content: center;
117
- overflow: hidden;
118
- color: white;
119
- text-align: center;
120
- white-space: nowrap;
121
- background-color: $octopus-primary-color;
122
- transition: width 0.6s ease;
123
- }
124
- &,.octopus-progress-bar{
125
- height: 4px;
126
- @media (max-width: 960px) {
127
- height: 8px;
128
- }
129
- }
130
- &.large,&.large .octopus-progress-bar{
131
- height: 15px;
132
- }
133
- &.medium,&.medium .octopus-progress-bar{
134
- height: 6px;
135
- }
136
- .octopus-progress-bar-duration {
137
- width: 10px;
138
- }
139
- .octopus-progress-bar-cursor{
140
- width: 10px;
141
- height: 10px;
142
- border-radius: 50%;
143
- background: black;
144
- align-self: center;
145
- position: absolute;
146
- }
147
- .end-0{
148
- right: 0;
149
- }
150
- }
151
- }
102
+ @import '../../assets/progressbar.scss';
152
103
  </style>
@@ -63,6 +63,9 @@
63
63
  :listen-time="listenTime"
64
64
  @updateNotListenTime="$emit('update:notListenTime', $event)"
65
65
  />
66
+ <RadioProgressBar
67
+ v-else
68
+ />
66
69
  </div>
67
70
  <button
68
71
  :title="''!=transcriptText ? $t('View transcript'): $t('Enlarge')"
@@ -86,14 +89,16 @@ import { CommentPodcast } from '@/stores/class/general/comment';
86
89
  import { playerDisplay } from '../../mixins/player/playerDisplay';
87
90
  import imageProxy from '../../mixins/imageProxy';
88
91
  import Spinner from '../Spinner.vue';
89
- import PlayerProgressBar from './PlayerProgressBar.vue';
90
92
  import PlayerTimeline from './PlayerTimeline.vue';
91
- import { defineComponent } from 'vue';
93
+ import { defineAsyncComponent, defineComponent } from 'vue';
94
+ const RadioProgressBar = defineAsyncComponent(() => import('./radio/RadioProgressBar.vue'));
95
+ const PlayerProgressBar = defineAsyncComponent(() => import('./PlayerProgressBar.vue'));
92
96
  export default defineComponent({
93
97
  name: 'PlayerCompact',
94
98
 
95
99
  components: {
96
100
  PlayerProgressBar,
101
+ RadioProgressBar,
97
102
  PlayerTimeline,
98
103
  Spinner
99
104
  },
@@ -32,6 +32,7 @@
32
32
  </div>
33
33
  <div class="player-grow-large-content">
34
34
  <PlayerProgressBar
35
+ v-if="!radioUrl"
35
36
  ref="progressbar"
36
37
  class-progress="large"
37
38
  :hls-ready="hlsReady"
@@ -44,11 +45,14 @@
44
45
  :listen-time="listenTime"
45
46
  @updateNotListenTime="$emit('update:notListenTime', $event)"
46
47
  />
48
+ <RadioProgressBar v-else />
47
49
  <div class="d-flex justify-content-between">
48
50
  <div>{{ playedTime }}</div>
49
51
  <div>{{ totalTime }}</div>
50
52
  </div>
53
+ <RadioHistory v-if="radioUrl" />
51
54
  </div>
55
+
52
56
  <div
53
57
  v-if="''!=transcriptText"
54
58
  class="flex-grow-1 d-flex align-items-center w-100"
@@ -94,17 +98,21 @@
94
98
  import Spinner from '../Spinner.vue';
95
99
  import { playerDisplay } from '../../mixins/player/playerDisplay';
96
100
  import imageProxy from '../../mixins/imageProxy';
97
- import PlayerProgressBar from './PlayerProgressBar.vue';
98
101
  import PlayerTimeline from './PlayerTimeline.vue';
99
- import { defineComponent } from 'vue';
102
+ import { defineAsyncComponent, defineComponent } from 'vue';
100
103
  import { CommentPodcast } from '@/stores/class/general/comment';
104
+ const RadioProgressBar = defineAsyncComponent(() => import('./radio/RadioProgressBar.vue'));
105
+ const RadioHistory = defineAsyncComponent(() => import('./radio/RadioHistory.vue'));
106
+ const PlayerProgressBar = defineAsyncComponent(() => import('./PlayerProgressBar.vue'));
101
107
  export default defineComponent({
102
108
  name: 'PlayerLarge',
103
109
 
104
110
  components: {
105
111
  PlayerProgressBar,
112
+ RadioProgressBar,
106
113
  PlayerTimeline,
107
- Spinner
114
+ Spinner,
115
+ RadioHistory
108
116
  },
109
117
  mixins:[playerDisplay, imageProxy],
110
118
 
@@ -30,7 +30,6 @@ export default defineComponent({
30
30
  },
31
31
  props: {
32
32
  classProgress:{ default: "", type: String},
33
- hlsReady: { default: false, type: Boolean},
34
33
  showTimeline: { default: false, type: Boolean},
35
34
  comments: { default: ()=>[], type: Array as ()=>Array<CommentPodcast>},
36
35
  displayAlertBar: { default: false, type: Boolean},
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div
3
+ v-if="playerRadio.history.length"
4
+ class="d-flex align-items-center flex-wrap mt-3"
5
+ >
6
+ <div class="fw-bold me-3">
7
+ {{ $t('Previously') +':' }}
8
+ </div>
9
+ <div
10
+ v-for="pastItem in playerRadio.history"
11
+ :key="pastItem.title"
12
+ class="me-3"
13
+ >
14
+ <span class="me-2 hour-past-item">{{ displayTimeItem(pastItem) }}</span>
15
+ <span>{{ displayPreviousItem(pastItem) }}</span>
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script lang="ts">
21
+ import { usePlayerStore } from '@/stores/PlayerStore';
22
+ import { mapState } from 'pinia';
23
+ import dayjs from 'dayjs';
24
+ import {fetchRadioData} from '../../../mixins/radio/fetchRadioData';
25
+ import { defineComponent } from 'vue';
26
+ import { MediaRadio } from '@/stores/class/general/player';
27
+ export default defineComponent({
28
+ name: 'RadioHistory',
29
+
30
+ components: {
31
+ },
32
+
33
+ mixins: [fetchRadioData],
34
+ emits: ['updateNotListenTime'],
35
+ data() {
36
+ return {
37
+ };
38
+ },
39
+
40
+ computed: {
41
+ ...mapState(usePlayerStore, ['playerRadio']),
42
+ },
43
+ mounted(){
44
+ console.log(this.playerRadio);
45
+ },
46
+ methods:{
47
+ displayTimeItem(item: MediaRadio):string{
48
+ return dayjs(item.startDate).format('HH:mm');
49
+ },
50
+ displayPreviousItem(item: MediaRadio):string{
51
+ if(item.podcastId){
52
+ return item.title;
53
+ }
54
+ return this.displayTitle(item);
55
+ }
56
+ }
57
+ })
58
+ </script>
59
+ <style lang="scss">
60
+ .octopus-app{
61
+ .hour-past-item{
62
+ font-size: 0.8rem;
63
+ color: #dbdbdb;
64
+ }
65
+ }
66
+ </style>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div
3
+ class="octopus-progress c-hand-auto mt-1"
4
+ :class="isAmbiance?'ambiance-progress':''"
5
+ >
6
+ <div
7
+ class="octopus-progress-bar"
8
+ role="progressbar"
9
+ aria-valuenow="0"
10
+ aria-valuemin="0"
11
+ aria-valuemax="100"
12
+ :style="'width: ' + percentProgress + '%'"
13
+ />
14
+ </div>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ import { usePlayerStore } from '@/stores/PlayerStore';
19
+ import { mapState, mapActions } from 'pinia';
20
+ import dayjs from 'dayjs';
21
+ import { defineComponent } from 'vue';
22
+ export default defineComponent({
23
+ name: 'RadioProgressBar',
24
+
25
+ components: {
26
+ },
27
+ emits: ['updateNotListenTime'],
28
+ data() {
29
+ return {
30
+ percentInterval: undefined as ReturnType<typeof setTimeout>|undefined,
31
+ };
32
+ },
33
+
34
+ computed: {
35
+ ...mapState(usePlayerStore, ['playerRadio', 'playerElapsed']),
36
+ isAmbiance(): boolean{
37
+ return !this.playerRadio?.podcast?.podcastId
38
+ },
39
+ percentProgress(): number{
40
+ if(!this.playerElapsed){return 0;}
41
+ return this.playerElapsed * 100;
42
+ },
43
+ },
44
+ mounted(){
45
+ this.handlePercentInterval();
46
+ },
47
+ methods:{
48
+ ...mapActions(usePlayerStore, ['playerUpdateElapsed']),
49
+ handlePercentInterval(/* clear: boolean */): void{
50
+ /* if(clear){
51
+ clearInterval((this.percentInterval as unknown as number));
52
+ this.percentInterval = undefined;
53
+ return;
54
+ } */
55
+ this.percentInterval = setInterval(() => {
56
+ this.calculatePercent();
57
+ }, 1000);
58
+ },
59
+ calculatePercent(): void{
60
+ if(!this.playerRadio?.metadata){return;}
61
+ const actualMilliSecondsPlayed = dayjs().subtract(18, 'second').diff(dayjs(this.playerRadio.metadata.startDate));
62
+ const percentPlayed = (actualMilliSecondsPlayed) / (this.playerRadio?.metadata.mediaDuration * 1000);
63
+ this.playerUpdateElapsed(percentPlayed, this.playerRadio?.metadata.mediaDuration);
64
+ }
65
+ }
66
+
67
+ })
68
+ </script>
69
+ <style lang="scss">
70
+ @import '../../../../assets/progressbar.scss';
71
+ .octopus-app{
72
+ .ambiance-progress{
73
+ background-color: #d1d1d1;
74
+ .octopus-progress-bar{
75
+ background-color: #747474;
76
+ }
77
+ }
78
+ }
79
+ </style>
@@ -88,7 +88,7 @@ export const playerDisplay = defineComponent({
88
88
  this.fetchCurrentlyPlaying();
89
89
  this.radioInterval = setInterval(() => {
90
90
  this.fetchCurrentlyPlaying();
91
- }, 2000);
91
+ }, 10000);
92
92
  }
93
93
  }
94
94
  },
@@ -104,8 +104,8 @@ export const playerDisplay = defineComponent({
104
104
  async fetchCurrentlyPlaying(): Promise<void>{
105
105
  this.fetchRadioMetadata(this.playerRadio?.canalId??0,this.playerRadio?.metadata.title??"", this.updateMetadata);
106
106
  },
107
- updateMetadata(metadata: MediaRadio, podcast?:Podcast): void{
108
- this.playerMetadata(metadata);
107
+ updateMetadata(metadata: MediaRadio, podcast:Podcast|undefined, history?: Array<MediaRadio>): void{
108
+ this.playerMetadata(metadata, history??[]);
109
109
  this.playerRadioPodcast(podcast);
110
110
  },
111
111
  addKeyboardControl(event: KeyboardEvent): void{
@@ -216,6 +216,9 @@ export const playerLogic = defineComponent({
216
216
  }
217
217
  },
218
218
  onTimeUpdate(event: Event): void {
219
+ if(this.playerRadio){
220
+ return;
221
+ }
219
222
  const mediaTarget = (event.currentTarget as HTMLMediaElement);
220
223
  if (this.playerPodcast || this.playerLive) {
221
224
  if (!this.downloadId) {
@@ -13,18 +13,18 @@ export const fetchRadioData = defineComponent({
13
13
  clearInterval((this.radioInterval as unknown as number));
14
14
  },
15
15
  methods: {
16
- async fetchRadioMetadata(canalId: number, previousTitle: string, callbackMetadata: (metadata: MediaRadio, podcast?:Podcast) => void): Promise<void>{
16
+ async fetchRadioMetadata(canalId: number, previousTitle: string, callbackMetadata: (metadata: MediaRadio, podcast:Podcast|undefined,history?: Array<MediaRadio> ) => void): Promise<void>{
17
17
  const metadata = await octopusApi.fetchData<MetadataRadio>(14, 'player/playing/'+canalId);
18
18
  const arrayMetadata = metadata.previously;
19
19
  arrayMetadata.unshift(metadata.currently);
20
- for (let el of arrayMetadata) {
21
- if(dayjs().valueOf()-29000 > dayjs(el.startDate).valueOf()){
22
- if(previousTitle !== el.title){
23
- if(el.podcastId){
24
- const data : Podcast = await octopusApi.fetchData<Podcast>(0, 'podcast/'+el.podcastId);
25
- callbackMetadata(el, data);
20
+ for (let index = 0, len = arrayMetadata.length; index < len; index++) {
21
+ if(dayjs().valueOf()-18000 > dayjs(arrayMetadata[index].startDate).valueOf()){
22
+ if(previousTitle !== arrayMetadata[index].title){
23
+ if(arrayMetadata[index].podcastId){
24
+ const data : Podcast = await octopusApi.fetchData<Podcast>(0, 'podcast/'+arrayMetadata[index].podcastId);
25
+ callbackMetadata(arrayMetadata[index], data, arrayMetadata.slice(index, len));
26
26
  }else{
27
- callbackMetadata(el);
27
+ callbackMetadata(arrayMetadata[index], undefined, arrayMetadata.slice(index, len));
28
28
  }
29
29
  }
30
30
  return;
@@ -223,18 +223,25 @@ export default defineComponent({
223
223
  },
224
224
 
225
225
  methods: {
226
+ async fetchConferencePublic(){
227
+ const data = await octopusApi.fetchData<string>(9, 'conference/realstatus/'+this.podcast.conferenceId);
228
+ this.fetchConference = {
229
+ status: data,
230
+ conferenceId: this.podcast.conferenceId,
231
+ title:'',
232
+ };
233
+ },
226
234
  async initConference(){
227
- if (!this.podcast || !this.isLiveReadyToRecord) return;
228
- if (this.isOctopusAndAnimator && undefined!==this.podcast.conferenceId) {
229
- const data = await crudApi.fetchData<Conference>(9,'conference/'+this.podcast.conferenceId);
230
- this.fetchConference = data ? data : {conferenceId:-1, title:''};
231
- } else if(undefined!==this.podcast.conferenceId){
232
- const data = await octopusApi.fetchData<string>(9, 'conference/realstatus/'+this.podcast.conferenceId);
233
- this.fetchConference = {
234
- status: data,
235
- conferenceId: this.podcast.conferenceId,
236
- title:'',
237
- };
235
+ if (!this.podcast || undefined==this.podcast.conferenceId) return;
236
+ if (this.isOctopusAndAnimator ) {
237
+ try {
238
+ const data = await crudApi.fetchData<Conference>(9,'conference/'+this.podcast.conferenceId);
239
+ this.fetchConference = data ? data : {conferenceId:-1, title:''};
240
+ } catch {
241
+ await this.fetchConferencePublic();
242
+ }
243
+ } else{
244
+ await this.fetchConferencePublic();
238
245
  }
239
246
  if (
240
247
  this.fetchConference &&
package/src/locale/fr.ts CHANGED
@@ -334,4 +334,8 @@ export default{
334
334
  'Canal name image': 'Image du canal {name}',
335
335
  "Show animated wave":"Afficher la vague animée",
336
336
  'Characters number calculated over HTML code':'Le nombre de caractères est calculé à partir du code HTML généré par cet éditeur. Vous pouvez voir ce code grâce au bouton "html".',
337
+
338
+
339
+
340
+ 'Previously':"Précédemment",
337
341
  };
@@ -128,9 +128,10 @@ export const usePlayerStore = defineStore('PlayerStore', {
128
128
  this.playerSeekTime = seekTime;
129
129
  },
130
130
 
131
- playerMetadata(metadata: MediaRadio){
131
+ playerMetadata(metadata: MediaRadio, history: Array<MediaRadio>){
132
132
  if(!this.playerRadio){return;}
133
133
  this.playerRadio.metadata = metadata;
134
+ this.playerRadio.history = history;
134
135
  },
135
136
  playerRadioPodcast(podcast: Podcast|undefined){
136
137
  if(!this.playerRadio){return;}
@@ -5,18 +5,16 @@ export interface Radio{
5
5
  canalId: number;
6
6
  url: string;
7
7
  metadata: MediaRadio;
8
+ history: Array<MediaRadio>;
8
9
  isInit: boolean;
9
10
  podcast?: Podcast;
10
11
  }
11
12
  export interface MediaRadio{
12
13
  artist:string;
13
- /* kind:string; */
14
14
  mediaId?:number;
15
- /* mediaType:string|null; */
16
15
  podcastId:number;
17
16
  startDate:string;
18
17
  title:string;
19
- /* uri:string; */
20
18
  mediaDuration: number,
21
19
  playDuration: number,
22
20
  }