@saooti/octopus-sdk 38.0.22 → 38.0.25

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 (32) hide show
  1. package/package.json +1 -1
  2. package/public/img/wave.svg +5 -0
  3. package/src/assets/general.scss +0 -1
  4. package/src/assets/progressbar.scss +0 -13
  5. package/src/components/display/podcasts/PodcastModuleBox.vue +8 -0
  6. package/src/components/display/sharing/ShareButtons.vue +1 -1
  7. package/src/components/display/sharing/ShareButtonsIntern.vue +2 -2
  8. package/src/components/display/sharing/SharePlayerColors.vue +2 -0
  9. package/src/components/form/ClassicSelect.vue +19 -0
  10. package/src/components/misc/ClassicAccordion.vue +19 -7
  11. package/src/components/misc/ClassicNav.vue +6 -2
  12. package/src/components/misc/ClassicPopover.vue +15 -11
  13. package/src/components/misc/HomeDropdown.vue +13 -2
  14. package/src/components/misc/ProgressBar.vue +4 -54
  15. package/src/components/misc/modal/NewsletterModal.vue +1 -0
  16. package/src/components/misc/player/PlayerCompact.vue +0 -3
  17. package/src/components/misc/player/PlayerComponent.vue +1 -18
  18. package/src/components/misc/player/PlayerLarge.vue +0 -3
  19. package/src/components/mixins/player/playerLogicProgress.ts +1 -1
  20. package/src/components/pages/RadioPage.vue +1 -2
  21. package/src/helper/duration.ts +8 -6
  22. package/src/locale/de.ts +1 -1
  23. package/src/locale/en.ts +1 -1
  24. package/src/locale/es.ts +1 -1
  25. package/src/locale/fr.ts +2 -2
  26. package/src/locale/it.ts +1 -1
  27. package/src/locale/sl.ts +1 -1
  28. package/src/stores/ParamSdkStore.ts +21 -21
  29. package/src/stores/PlayerStore.ts +7 -43
  30. package/src/components/misc/player/ChapteringModal.vue +0 -95
  31. package/src/components/misc/player/PlayerChaptering.vue +0 -86
  32. package/src/stores/class/chaptering/chaptering.ts +0 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "38.0.22",
3
+ "version": "38.0.25",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="uuid-cd939b38-9c51-44e2-969a-c00901ca97ed" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg"
3
+ viewBox="0 0 95.43 34.27">
4
+ <path d="m95.43,11.57c-1.9.01-2.49,3.87-3.23,7.62-.25,1.28-.9,4.54-1.42,5.22-.14-.26-.39-.89-.67-2.33-.37-1.85-.67-4.38-.96-6.83-.93-7.84-1.45-10.8-3.25-10.8-1.16,0-1.74,1.3-2.28,5.14-.38,2.65-.68,6.23-.98,9.73-.28,3.28-.57,6.66-.91,9.22-.24,1.77-.47,2.79-.63,3.37-.15-.48-.35-1.28-.56-2.59-.35-2.14-.63-4.98-.92-7.82-.96-9.52-1.42-12.6-3.25-12.6s-2.39,3.09-3.25,9c-.29,2.01-.59,4.09-.95,5.6-.21.86-.39,1.35-.52,1.63-.15-.36-.37-1.06-.62-2.38-.36-1.93-.65-4.53-.94-7.04-.93-8.17-1.45-11.25-3.25-11.25s-2.38,3.22-3.25,9.94c-.29,2.22-.59,4.51-.95,6.18-.27,1.26-.51,1.82-.65,2.06-.55-.71-1.19-3.94-1.45-5.22-.74-3.76-1.33-6.73-3.24-6.73s-2.37,3.07-3.25,9.45c-.29,2.12-.59,4.31-.95,5.9-.18.8-.35,1.3-.47,1.61-.17-.54-.43-1.58-.69-3.56-.35-2.57-.64-5.97-.91-9.25-.29-3.46-.6-7.04-.97-9.7-.54-3.84-1.12-5.14-2.28-5.14-1.83,0-2.3,3.3-3.25,13.49-.28,2.98-.57,6.07-.92,8.39-.26,1.76-.51,2.68-.66,3.14-.13-.31-.31-.82-.5-1.66-.36-1.59-.66-3.79-.95-5.91-.88-6.38-1.38-9.45-3.25-9.45s-2.31,3.15-3.25,12.18c-.28,2.68-.57,5.45-.92,7.52-.22,1.28-.42,2.04-.56,2.49-.17-.53-.39-1.48-.63-3.13-.35-2.4-.64-5.59-.92-8.67-.96-10.54-1.42-13.94-3.25-13.94s-2.29,3.08-3.25,12.63c-.28,2.77-.57,5.64-.92,7.79-.24,1.51-.47,2.35-.63,2.8-.14-.34-.32-.92-.52-1.89-.37-1.76-.67-4.18-.96-6.52-.87-6.99-1.37-10.35-3.25-10.35s-2.37,3.07-3.25,9.45c-.29,2.12-.59,4.31-.95,5.91-.21.9-.39,1.42-.53,1.72-.15-.39-.38-1.14-.63-2.54-.35-2.01-.65-4.69-.93-7.28-.95-8.67-1.44-11.7-3.25-11.7s-2.32,2.96-3.25,10.82c-.29,2.44-.59,4.97-.96,6.81-.26,1.32-.49,1.96-.64,2.25-.12-.19-.3-.55-.51-1.23-.36-1.16-.66-2.79-.94-4.36-.74-4.02-1.32-7.19-3.24-7.19-.03,0-.06,0-.09,0v1.73s0,0,0,0c.01,0,.29.18.67,1.43.36,1.16.66,2.79.94,4.36.74,4.01,1.32,7.18,3.24,7.18,1.8,0,2.32-2.96,3.25-10.8.29-2.45.59-4.98.96-6.83.21-1.07.4-1.69.54-2.05.15.41.37,1.15.6,2.48.35,2,.65,4.69.93,7.28.95,8.67,1.44,11.7,3.25,11.7s2.37-3.07,3.25-9.47c.29-2.11.59-4.3.95-5.89.22-.95.41-1.48.55-1.76.14.32.35.92.58,2.03.37,1.77.67,4.19.96,6.52.87,6.99,1.37,10.35,3.25,10.35s2.29-3.08,3.25-12.63c.28-2.77.57-5.64.92-7.79.22-1.35.42-2.16.57-2.63.17.54.39,1.48.62,3.11.35,2.4.64,5.59.92,8.67.95,10.54,1.42,13.94,3.25,13.94s2.31-3.15,3.25-12.15c.28-2.69.57-5.46.92-7.55.25-1.49.48-2.28.64-2.7.13.3.32.82.52,1.7.36,1.59.66,3.77.95,5.9.88,6.39,1.38,9.45,3.25,9.45s2.29-3.3,3.25-13.5c.28-2.98.57-6.06.92-8.38.22-1.45.42-2.33.58-2.86.17.59.39,1.6.62,3.33.35,2.56.63,5.95.92,9.26.29,3.46.6,7.04.97,9.69.54,3.84,1.12,5.14,2.28,5.14,1.87,0,2.37-3.07,3.25-9.45.29-2.11.59-4.3.95-5.9.27-1.19.51-1.72.64-1.94.56.69,1.2,3.95,1.45,5.23.74,3.76,1.33,6.73,3.24,6.73s2.38-3.22,3.25-9.94c.29-2.22.59-4.51.95-6.17.21-.97.4-1.53.54-1.84.15.37.37,1.06.6,2.34.36,1.93.65,4.53.94,7.04.93,8.17,1.45,11.25,3.25,11.25s2.39-3.09,3.25-9c.29-2.01.59-4.09.95-5.6.2-.81.37-1.29.5-1.58.16.43.4,1.27.66,2.87.35,2.16.64,5.04.92,7.82.96,9.52,1.42,12.6,3.25,12.6,1.16,0,1.74-1.3,2.28-5.14.38-2.66.68-6.24.97-9.7.28-3.28.57-6.68.91-9.25.26-1.89.5-2.92.66-3.48.14.37.31.97.5,1.92.37,1.85.67,4.38.96,6.83.93,7.84,1.45,10.8,3.25,10.8,1.91,0,2.5-2.97,3.24-6.74.27-1.36.98-5.86,1.52-6.2v-1.75Z"/>
5
+ </svg>
@@ -111,7 +111,6 @@ body{
111
111
  margin: 1rem 0;
112
112
  }
113
113
  }
114
-
115
114
  .flex-super-grow{
116
115
  flex-grow: 2;
117
116
  }
@@ -20,19 +20,6 @@
20
20
  background-color: $octopus-primary-color;
21
21
  transition: width 0.6s ease;
22
22
  }
23
- .octopus-chapter{
24
- position: absolute;
25
- background: transparent;
26
- background-clip: content-box;
27
- padding: 0 5px;
28
- box-shadow: inset -2px 1px 0px 0px rgb(0 0 0),
29
- inset 2px 1px 0px 0px rgb(0 0 0);
30
-
31
- &:hover{
32
- background: rgba(255, 255, 255, 0.4);
33
- box-shadow: -4px 1px 0px 0px rgb(0 0 0);
34
- }
35
- }
36
23
  &,.octopus-progress-bar{
37
24
  height: 4px;
38
25
  @media (max-width: 960px) {
@@ -77,6 +77,11 @@
77
77
  <div v-if="'' !== audioCredit" class="mb-1">
78
78
  {{ $t("Audio credits") + " : " + audioCredit }}
79
79
  </div>
80
+ <div v-if="'' !== authorCredit" class="mb-1">
81
+ {{ $t("Author credits") + " : " + authorCredit }}
82
+ </div>
83
+
84
+
80
85
  <a
81
86
  v-if="podcast.article"
82
87
  class="btn d-flex align-items-center my-2 width-fit-content mb-1"
@@ -267,6 +272,9 @@ export default defineComponent({
267
272
  audioCredit(): string {
268
273
  return (this.podcast?.annotations?.audioCredit as string) ?? "";
269
274
  },
275
+ authorCredit(): string {
276
+ return (this.podcast?.annotations?.authorCredit as string) ?? "";
277
+ },
270
278
  isEditBox(): boolean {
271
279
  return (state.podcastPage.EditBox as boolean) ?? false;
272
280
  },
@@ -10,11 +10,11 @@
10
10
  role="button"
11
11
  tabindex="0"
12
12
  class="saooti-help ms-2"
13
+ :aria-label="$t('Help')"
13
14
  />
14
15
  <ClassicPopover
15
16
  v-if="authenticated"
16
17
  target="popover-share-help"
17
- :title="$t('Help')"
18
18
  :content="$t('Share this page without edit and share blocks')"
19
19
  relative-class="page-element"
20
20
  :is-fixed="true"
@@ -18,7 +18,7 @@
18
18
  <div :class="button.icon" />
19
19
  </a>
20
20
  </template>
21
- <!-- <router-link
21
+ <router-link
22
22
  v-if="!isPodcastmaker && authenticated && podcast && isProduction"
23
23
  :class="getClass('saooti-share')"
24
24
  :title="$t('Advanced sharing')"
@@ -26,7 +26,7 @@
26
26
  name: 'advancedShare',
27
27
  params: { podcastId: podcast.podcastId },
28
28
  }"
29
- /> -->
29
+ />
30
30
  </div>
31
31
  </div>
32
32
  <div v-if="podcast || emission || playlist" class="d-flex flex-column me-2">
@@ -8,6 +8,7 @@
8
8
  :model-value="color"
9
9
  class="c-hand"
10
10
  show-fallback
11
+ fallback-input-type="color"
11
12
  colors="text-advanced"
12
13
  popover-to="right"
13
14
  :data-color="color"
@@ -22,6 +23,7 @@
22
23
  :model-value="theme"
23
24
  class="c-hand"
24
25
  show-fallback
26
+ fallback-input-type="color"
25
27
  colors="text-advanced"
26
28
  popover-to="right"
27
29
  :data-color="theme"
@@ -61,13 +61,32 @@ export default defineComponent({
61
61
  });
62
62
  </script>
63
63
  <style lang="scss">
64
+ @import "@scss/_variables.scss";
64
65
  .octopus-app {
66
+ select option:checked,
67
+ select option:hover {
68
+ box-shadow: 0 0 10px 100px #dddddd inset;
69
+ }
70
+ select:focus > option:checked {
71
+ background: #dddddd !important;
72
+ }
73
+ .classic-select select{
74
+ -webkit-appearance: none;
75
+ -moz-appearance: none;
76
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"10\" role=\"presentation\"><path fill=\"%233c3c3c80\" d=\"M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z\"></path></svg>") !important;
77
+ background-repeat: no-repeat !important;
78
+ background-position-x: calc(100% - 6px) !important;
79
+ background-position-y: 0.7rem !important;
80
+ }
81
+
65
82
  select.transparent {
66
83
  background: transparent !important;
67
84
  outline-color: transparent !important;
68
85
  padding: 0;
69
86
  border: 0;
70
87
  height: unset;
88
+ -webkit-appearance: auto !important;
89
+ -moz-appearance: auto !important;
71
90
  }
72
91
  }
73
92
  </style>
@@ -1,10 +1,9 @@
1
1
  <template>
2
- <div class="my-2" :class="displayAccordion ? 'octopus-accordion' : ''">
2
+ <div class="my-2" :class="[displayAccordion ? 'octopus-accordion' : '', isOpen?'octopus-accordion-open':'' ]">
3
3
  <template v-if="displayAccordion">
4
4
  <button
5
5
  :id="'accordion-' + idComposer"
6
- class="btn-transparent bg-white w-100 p-2 text-start d-flex flex-no-wrap align-items-center"
7
- :class="isOpen ? 'really-light-primary-bg' : ''"
6
+ class="w-100 py-2 text-start d-flex flex-nowrap align-items-center"
8
7
  @click="isOpen = !isOpen"
9
8
  >
10
9
  <span v-if="icon" class="img-accordion text-primary" :class="icon" />
@@ -52,10 +51,23 @@ export default defineComponent({
52
51
  });
53
52
  </script>
54
53
  <style lang="scss">
55
- .octopus-accordion {
56
- border: 1px solid #ccc;
57
- > button {
54
+ @import '@scss/_variables.scss';
55
+ .octopus-accordion{
56
+ > button{
57
+ background: white;
58
58
  min-height: 50px;
59
+ color: $octopus-primary-color;
60
+ border: 1px solid transparent;
61
+ &:hover{
62
+ border: 1px solid $octopus-primary-color;
63
+ }
64
+ }
65
+ &.octopus-accordion-open{
66
+ border: 1px solid $octopus-primary-color;
67
+ > button{
68
+ background: $octopus-primary-color;
69
+ color: white;
70
+ }
59
71
  }
60
72
  .img-accordion {
61
73
  width: 30px;
@@ -67,7 +79,7 @@ export default defineComponent({
67
79
  align-items: center;
68
80
  }
69
81
  .body {
70
- border-top: 1px solid #ccc;
82
+ border-top: 1px solid $octopus-primary-color;
71
83
  }
72
84
  }
73
85
  </style>
@@ -85,12 +85,16 @@ export default defineComponent({
85
85
  background-color 0.15s ease-in-out,
86
86
  border-color 0.15s ease-in-out;
87
87
  border: 0.1rem solid transparent;
88
- &:hover,
89
- &.active {
88
+ &:hover{
90
89
  border-color: #dee2e6;
91
90
  border-bottom-color: $octopus-primary-color;
92
91
  color: $octopus-primary-color;
93
92
  }
93
+ &.active{
94
+ border-color: $octopus-primary-color;
95
+ background: $octopus-primary-color;
96
+ color:white;
97
+ }
94
98
  }
95
99
  .octopus-nav.light .octopus-nav-link {
96
100
  border-top: 0 !important;
@@ -5,9 +5,11 @@
5
5
  ref="popover"
6
6
  tabindex="0"
7
7
  class="octopus-popover"
8
- :class="[onlyClick ? 'octopus-dropdown' : '', popoverClass]"
8
+ :class="onlyClick ? 'octopus-dropdown' : ''"
9
9
  :style="positionInlineStyle"
10
10
  @blur="clearDataBlur"
11
+ @mouseenter="overPopover=true"
12
+ @mouseleave="overPopover=false;clearData();"
11
13
  >
12
14
  <div v-if="title" class="bg-secondary p-2">
13
15
  {{ title }}
@@ -28,12 +30,10 @@ export default defineComponent({
28
30
  target: { type: String, required: true },
29
31
  disable: { type: Boolean, default: false },
30
32
  onlyClick: { type: Boolean, default: false },
31
- onlyMouse: { type: Boolean, default: false },
32
33
  isFixed: { type: Boolean, default: false },
33
34
  relativeClass: { type: String, default: undefined },
34
35
  leftPos: { type: Boolean, default: false },
35
36
  topPos: { type: Boolean, default: false },
36
- popoverClass: { type: String, default: undefined },
37
37
  },
38
38
  data() {
39
39
  return {
@@ -42,6 +42,7 @@ export default defineComponent({
42
42
  posX: 0 as number,
43
43
  posY: 0 as number,
44
44
  targetElement: null as HTMLElement | null,
45
+ overPopover: false as boolean
45
46
  };
46
47
  },
47
48
  computed: {
@@ -67,11 +68,9 @@ export default defineComponent({
67
68
  "mouseenter",
68
69
  this.setPopoverData,
69
70
  );
70
- this.targetElement.addEventListener("mouseleave", this.clearData);
71
- }
72
- if (!this.onlyMouse) {
73
- this.targetElement.addEventListener("click", this.setPopoverData);
71
+ this.targetElement.addEventListener("mouseleave", this.clearDataTimeout);
74
72
  }
73
+ this.targetElement.addEventListener("click", this.setPopoverData);
75
74
  this.targetElement.addEventListener("blur", this.clearDataBlur);
76
75
  }
77
76
  },
@@ -82,11 +81,9 @@ export default defineComponent({
82
81
  "mouseenter",
83
82
  this.setPopoverData,
84
83
  );
85
- this.targetElement.removeEventListener("mouseleave", this.clearData);
86
- }
87
- if (!this.onlyMouse) {
88
- this.targetElement.removeEventListener("click", this.setPopoverData);
84
+ this.targetElement.removeEventListener("mouseleave", this.clearDataTimeout);
89
85
  }
86
+ this.targetElement.removeEventListener("click", this.setPopoverData);
90
87
  this.targetElement.addEventListener("blur", this.clearDataBlur);
91
88
  }
92
89
  },
@@ -180,6 +177,13 @@ export default defineComponent({
180
177
  this.isClick = false;
181
178
  this.clearData();
182
179
  },
180
+ clearDataTimeout() {
181
+ setTimeout(() => {
182
+ if(!this.overPopover){
183
+ this.clearData();
184
+ }
185
+ }, 500);
186
+ },
183
187
  clearData() {
184
188
  if (this.isClick) {
185
189
  return;
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <div class="d-flex align-items-center">
3
- <router-link
3
+ <button
4
4
  v-if="isAuthenticatedWithOrga"
5
5
  :title="$t('My space')"
6
- to="/main/priv/backoffice"
6
+ @click="goToAdministration"
7
7
  class="btn admin-button hide-smallest-screen m-1 saooti-admin-menu"
8
8
  />
9
9
  <router-link
@@ -147,5 +147,16 @@ export default defineComponent({
147
147
  return state.generalParameters.isContribution ?? false;
148
148
  },
149
149
  },
150
+ methods:{
151
+ goToAdministration(){
152
+ if("homePriv" !== this.$route.name){
153
+ this.$router.push("/main/priv/backoffice");
154
+ }else if (window.history.length > 1) {
155
+ this.$router.go(-1);
156
+ } else {
157
+ this.$router.push("/");
158
+ }
159
+ }
160
+ }
150
161
  });
151
162
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-if="display" id="test-menu-dropdown" class="octopus-progress">
2
+ <div class="octopus-progress">
3
3
  <div
4
4
  v-if="secondaryProgress"
5
5
  class="octopus-progress-bar bg-light"
@@ -48,50 +48,18 @@
48
48
  />
49
49
  <div
50
50
  v-if="isProgressCursor"
51
- class="octopus-progress-bar-cursor"
51
+ class="progress-bar-cursor"
52
52
  :style="'left:' + mainProgress + '%'"
53
53
  />
54
- <template v-if="playerChapteringPercent">
55
- <template v-for="chapter in playerChapteringPercent" :key="chapter">
56
- <div
57
- :id="'chapter-' + chapter.startPercent"
58
- class="octopus-progress-bar octopus-chapter"
59
- role="progressbar"
60
- aria-valuenow="0"
61
- aria-valuemin="0"
62
- aria-valuemax="100"
63
- :style="{
64
- left: chapter.startPercent + '%',
65
- right: 100 - chapter.endPercent + '%',
66
- }"
67
- />
68
- <Teleport to="#octopus-player-component">
69
- <ClassicPopover
70
- :target="'chapter-' + chapter.startPercent"
71
- :is-fixed="true"
72
- relative-class="player-container"
73
- :only-mouse="true"
74
- popover-class="octopus-small-popover"
75
- :content="chapter.title"
76
- />
77
- </Teleport>
78
- </template>
79
- </template>
80
54
  </div>
81
55
  </template>
82
56
 
83
57
  <script lang="ts">
84
58
  import { usePlayerStore } from "@/stores/PlayerStore";
85
59
  import { mapState } from "pinia";
86
- import { defineAsyncComponent, defineComponent } from "vue";
87
- const ClassicPopover = defineAsyncComponent(
88
- () => import("../misc/ClassicPopover.vue"),
89
- );
60
+ import { defineComponent } from "vue";
90
61
  export default defineComponent({
91
62
  name: "ProgressBar",
92
- components: {
93
- ClassicPopover,
94
- },
95
63
  props: {
96
64
  alertBar: { default: undefined, type: Number },
97
65
  mainProgress: { default: 0, type: Number },
@@ -105,14 +73,7 @@ export default defineComponent({
105
73
  };
106
74
  },
107
75
  computed: {
108
- ...mapState(usePlayerStore, [
109
- "playerMedia",
110
- "playerChapteringPercent",
111
- "playerStatus",
112
- ]),
113
- display() {
114
- return "STOPPED" !== this.playerStatus;
115
- },
76
+ ...mapState(usePlayerStore, ["playerMedia"]),
116
77
  },
117
78
  watch: {
118
79
  playerMedia: {
@@ -143,15 +104,4 @@ export default defineComponent({
143
104
 
144
105
  <style lang="scss">
145
106
  @import "../../assets/progressbar.scss";
146
- .octopus-app .player-container {
147
- .octopus-small-popover {
148
- font-size: 0.7rem;
149
- background: #282828;
150
- color: white;
151
- border: 0;
152
- .p-2 {
153
- padding: 0.2rem !important;
154
- }
155
- }
156
- }
157
107
  </style>
@@ -39,6 +39,7 @@
39
39
  v-model="color"
40
40
  class="c-hand me-2 mt-2"
41
41
  show-fallback
42
+ fallback-input-type="color"
42
43
  colors="text-advanced"
43
44
  popover-to="right"
44
45
  :data-color="color"
@@ -34,7 +34,6 @@
34
34
  {{ playedTime }} / {{ totalTime }}
35
35
  </div>
36
36
  </div>
37
- <PlayerChaptering />
38
37
  <PlayerProgressBar
39
38
  v-if="!radioUrl"
40
39
  :show-timeline="showTimeline"
@@ -70,7 +69,6 @@ import { playerDisplay } from "../../mixins/player/playerDisplay";
70
69
  import imageProxy from "../../mixins/imageProxy";
71
70
  import ClassicSpinner from "../ClassicSpinner.vue";
72
71
  import PlayerTimeline from "./PlayerTimeline.vue";
73
- import PlayerChaptering from "./PlayerChaptering.vue";
74
72
  import { defineAsyncComponent, defineComponent } from "vue";
75
73
  const RadioProgressBar = defineAsyncComponent(
76
74
  () => import("./radio/RadioProgressBar.vue"),
@@ -86,7 +84,6 @@ export default defineComponent({
86
84
  RadioProgressBar,
87
85
  PlayerTimeline,
88
86
  ClassicSpinner,
89
- PlayerChaptering,
90
87
  },
91
88
  mixins: [playerDisplay, imageProxy],
92
89
 
@@ -1,12 +1,11 @@
1
1
  <template>
2
2
  <div
3
- id="octopus-player-component"
4
3
  class="player-container"
5
4
  :class="playerVideo ? 'player-video' : ''"
6
5
  :style="{ height: playerHeight }"
7
6
  @transitionend="onHidden"
8
7
  >
9
- <template v-if="displayWithTimeout">
8
+ <template v-if="display">
10
9
  <PlayerVideo v-if="playerVideo" />
11
10
  <template v-else>
12
11
  <audio
@@ -87,7 +86,6 @@ export default defineComponent({
87
86
  comments: [] as Array<CommentPodcast>,
88
87
  audioUrlToPlay: "" as string,
89
88
  hlsReady: false as boolean,
90
- displayWithTimeout: false as boolean,
91
89
  };
92
90
  },
93
91
  computed: {
@@ -106,15 +104,6 @@ export default defineComponent({
106
104
  playerHeight(): void {
107
105
  this.$emit("hide", 0 === this.playerHeight);
108
106
  },
109
- display(): void {
110
- if (this.display) {
111
- this.displayWithTimeout = this.display;
112
- } else {
113
- setTimeout(() => {
114
- this.displayWithTimeout = this.display;
115
- }, 3000);
116
- }
117
- },
118
107
  },
119
108
 
120
109
  methods: {
@@ -152,12 +141,6 @@ export default defineComponent({
152
141
  transition: height 1s;
153
142
  background: #282828 !important;
154
143
  font-size: 1rem;
155
- .medium-text {
156
- font-size: 0.65rem;
157
- }
158
- .small-text {
159
- font-size: 0.5rem;
160
- }
161
144
 
162
145
  @media (max-width: 960px) {
163
146
  .d-flex {
@@ -24,7 +24,6 @@
24
24
  {{ podcastTitle }}
25
25
  </div>
26
26
  </div>
27
- <PlayerChaptering class="justify-content-center w-100" />
28
27
  <div class="player-grow-large-content">
29
28
  <PlayerProgressBar
30
29
  v-if="!radioUrl"
@@ -87,7 +86,6 @@ import ClassicSpinner from "../ClassicSpinner.vue";
87
86
  import { playerDisplay } from "../../mixins/player/playerDisplay";
88
87
  import imageProxy from "../../mixins/imageProxy";
89
88
  import PlayerTimeline from "./PlayerTimeline.vue";
90
- import PlayerChaptering from "./PlayerChaptering.vue";
91
89
  import { defineAsyncComponent, defineComponent } from "vue";
92
90
  import { CommentPodcast } from "@/stores/class/general/comment";
93
91
  const RadioProgressBar = defineAsyncComponent(
@@ -108,7 +106,6 @@ export default defineComponent({
108
106
  PlayerTimeline,
109
107
  ClassicSpinner,
110
108
  RadioHistory,
111
- PlayerChaptering,
112
109
  },
113
110
  mixins: [playerDisplay, imageProxy],
114
111
 
@@ -41,7 +41,7 @@ export const playerLogicProgress = defineComponent({
41
41
  );
42
42
  },
43
43
  playerSeekTime() {
44
- if (undefined===this.playerSeekTime) {
44
+ if (!this.playerSeekTime) {
45
45
  return;
46
46
  }
47
47
  if (this.playerPodcast || this.playerLive) {
@@ -91,8 +91,7 @@ export default defineComponent({
91
91
  computed: {
92
92
  editRight(): boolean {
93
93
  return (
94
- (true === this.authenticated &&
95
- true === state.generalParameters.isRadio &&
94
+ (true === this.authenticated && true === state.generalParameters.isRadio &&
96
95
  this.myOrganisationId === this.radio?.organisationId) ||
97
96
  true === state.generalParameters.isAdmin
98
97
  );
@@ -1,18 +1,20 @@
1
1
  export default {
2
- convertTimestamptoSeconds(timestamp: string){
3
- const [hours, minutes, seconds] = timestamp.split(':');
4
- return Number(hours) * 60 * 60 + Number(minutes) * 60 + Number(seconds);
5
- },
6
2
  formatToString(value: number) {
7
3
  if (value < 10) {
8
4
  return "0" + value;
9
5
  }
10
6
  return value.toString();
11
7
  },
12
- formatDuration(totalSeconds: number, separator="'", isLast=true): string {
8
+ formatDuration(totalSeconds: number): string {
13
9
  const hours = Math.floor(totalSeconds / 3600);
14
10
  const minutes = Math.floor((totalSeconds - hours * 3600) / 60);
15
11
  const seconds = totalSeconds - hours * 3600 - minutes * 60;
16
- return (hours > 0? this.formatToString(hours)+separator:"") + this.formatToString(minutes) +separator+ this.formatToString(seconds) + (isLast?separator:'' );
12
+ return (
13
+ (hours > 0 ? this.formatToString(hours) + "'" : "") +
14
+ this.formatToString(minutes) +
15
+ "'" +
16
+ this.formatToString(seconds) +
17
+ "''"
18
+ );
17
19
  },
18
20
  };
package/src/locale/de.ts CHANGED
@@ -310,6 +310,7 @@ export default {
310
310
  "Wenn die Abschrift vorhanden ist, zeigen Sie sie",
311
311
  "Photo credits": "Bildnachweis",
312
312
  "Audio credits": "Audio-Credits",
313
+ "Author credits": "Autorennachweise",
313
314
  "View transcript": "Transkript ansehen",
314
315
  "Suggested listening": "Anhören empfohlen",
315
316
  More: "Mehr",
@@ -350,5 +351,4 @@ export default {
350
351
  "Trigger automatic reading if this is possible":"Wenn möglich, automatisches Auslesen auslösen",
351
352
  "High version":"Hohe Version",
352
353
  "Advanced sharing":"Erweitertes Teilen",
353
- "Chaptering":"Kapitelaufteilung",
354
354
  }
package/src/locale/en.ts CHANGED
@@ -310,6 +310,7 @@ export default {
310
310
  "If the transcript is available, show it",
311
311
  "Photo credits": "Photo credits",
312
312
  "Audio credits": "Audio credits",
313
+ "Author credits": "Author credits",
313
314
  "View transcript": "View transcript",
314
315
  "Suggested listening": "Suggested listening",
315
316
  More: "More",
@@ -350,5 +351,4 @@ export default {
350
351
  "Trigger automatic reading if this is possible":"Trigger automatic reading if this is possible",
351
352
  "High version":"High version",
352
353
  "Advanced sharing":"Advanced sharing",
353
- "Chaptering":"Chaptering",
354
354
  };
package/src/locale/es.ts CHANGED
@@ -311,6 +311,7 @@ export default {
311
311
  "Si la transcripción está disponible, muéstrela",
312
312
  "Photo credits": "Créditos fotográficos",
313
313
  "Audio credits": "Créditos de audio",
314
+ "Author credits": "Créditos del autor",
314
315
  "View transcript": "Ver transcripción",
315
316
  "Suggested listening": "Escucha sugerida",
316
317
  More: "Más",
@@ -351,5 +352,4 @@ export default {
351
352
  "Trigger automatic reading if this is possible":"Activar la lectura automática si esto es posible",
352
353
  "High version":"Versión alta",
353
354
  "Advanced sharing":"Reparto adelantado",
354
- "Chaptering":"Capítulos",
355
355
  }
package/src/locale/fr.ts CHANGED
@@ -32,7 +32,7 @@ export default {
32
32
  Emission: "Émission",
33
33
  "Emission description": "Description de l'émission",
34
34
  "Emission image": "Image de l'émission",
35
- "Emission name": "Nom de l'émission",
35
+ "Emission name": "Title de l'émission",
36
36
  "No elements found. Consider changing the search query.":
37
37
  "Aucun élement ne correspond à votre recherche",
38
38
  "Podcast is not visible for listeners":
@@ -317,6 +317,7 @@ export default {
317
317
  "Si la transcription est disponible, l'afficher",
318
318
  "Photo credits": "Crédits photo",
319
319
  "Audio credits": "Crédits audio",
320
+ "Author credits": "Crédits auteur",
320
321
  "View transcript": "Afficher la transcription",
321
322
  "Suggested listening": "Suggestion d'écoute",
322
323
  More: "Plus",
@@ -357,5 +358,4 @@ export default {
357
358
  "Trigger automatic reading if this is possible":"Déclencher la lecture automatique si celle ci est possible",
358
359
  "High version":"Version en hauteur",
359
360
  "Advanced sharing":"Partage avancé",
360
- "Chaptering":"Chapitrage",
361
361
  };
package/src/locale/it.ts CHANGED
@@ -303,6 +303,7 @@ export default{
303
303
  "If the transcript is available, show it":"Se la trascrizione è disponibile, mostrala",
304
304
  "Photo credits":"Crediti fotografici",
305
305
  "Audio credits":"Crediti audio",
306
+ "Author credits": "Crediti dell'autore",
306
307
  "View transcript":"Visualizza trascrizione",
307
308
  "Suggested listening":"Ascolto suggerito",
308
309
  "More":"Di più",
@@ -343,5 +344,4 @@ export default{
343
344
  "Trigger automatic reading if this is possible":"Attivare la lettura automatica, se possibile",
344
345
  "High version":"Versione alta",
345
346
  "Advanced sharing":"Condivisione avanzata",
346
- "Chaptering":"Capitolazione",
347
347
  };
package/src/locale/sl.ts CHANGED
@@ -300,6 +300,7 @@ export default {
300
300
  "Če je prepis na voljo, ga pokažite",
301
301
  "Photo credits": "Avtorji fotografij",
302
302
  "Audio credits": "Avdio krediti",
303
+ "Author credits": "Zasluge avtorja",
303
304
  "View transcript": "Ogled prepisa",
304
305
  "Suggested listening": "Predlagano poslušanje",
305
306
  More: "Več",
@@ -340,5 +341,4 @@ export default {
340
341
  "Trigger automatic reading if this is possible":"Sprožite samodejno branje, če je to mogoče",
341
342
  "High version":"Visoka različica",
342
343
  "Advanced sharing":"Napredno deljenje",
343
- "Chaptering":"Poglavje",
344
344
  }
@@ -3,17 +3,17 @@ import { Category } from "./class/general/category";
3
3
 
4
4
  const state: ParamStore = {
5
5
  generalParameters: {
6
- organisationId:undefined/* "ecbd98d9-79bd-4312-ad5e-fc7c1c4a191c" */,
7
- authenticated: false,
8
- isAdmin: false,
9
- isRoleLive: false,
10
- isCommments: false,
11
- isOrganisation:false,
12
- isPlaylist: false,
13
- isProduction: false,
14
- isContribution: false,
15
- isRadio: false,
16
- ApiUri: "https://api.dev2.saooti.org/",
6
+ organisationId: "ecbd98d9-79bd-4312-ad5e-fc7c1c4a191c",
7
+ authenticated: true,
8
+ isAdmin: true,
9
+ isRoleLive: true,
10
+ isCommments: true,
11
+ isOrganisation:true,
12
+ isPlaylist: true,
13
+ isProduction: true,
14
+ isContribution: true,
15
+ isRadio: true,
16
+ ApiUri: "https://api.staging.saooti.org/",
17
17
  podcastmaker: false,
18
18
  buttonPlus: true,
19
19
  allCategories: [],
@@ -27,8 +27,8 @@ const state: ParamStore = {
27
27
  SharePlayer: true,
28
28
  ShareButtons: true,
29
29
  ShareDistribution: true,
30
- MiniplayerUri: "https://playerbeta.dev2.saooti.org/",
31
- hlsUri: "https://hls.live.dev2.saooti.org/",
30
+ MiniplayerUri: "https://playerbeta.staging.saooti.org/",
31
+ hlsUri: "https://hls.live.staging.saooti.org/",
32
32
  mainRubrique: 0,
33
33
  resourceUrl: undefined,
34
34
  podcastItemShowEmission: false,
@@ -80,14 +80,14 @@ const state: ParamStore = {
80
80
  userName: "",
81
81
  },
82
82
  octopusApi: {
83
- url: "https://api.dev2.saooti.org/",
84
- commentsUrl: "https://comments.dev2.saooti.org/",
85
- imageUrl: "https://imageproxy.dev2.saooti.org/",
86
- studioUrl: "https://studio.dev2.saooti.org/",
87
- playerUrl: "https://playerbeta.dev2.saooti.org/",
88
- speechToTextUrl: "https://speech2text.dev2.saooti.org/",
89
- radioUrl:"https://radio.dev2.saooti.org/",
90
- recoUrl: "https://reco.dev2.saooti.org/",
83
+ url: "https://api.staging.saooti.org/",
84
+ commentsUrl: "https://comments.staging.saooti.org/",
85
+ imageUrl: "https://imageproxy.staging.saooti.org/",
86
+ studioUrl: "https://studio.staging.saooti.org/",
87
+ playerUrl: "https://playerbeta.staging.saooti.org/",
88
+ speechToTextUrl: "https://speech2text.staging.saooti.org/",
89
+ radioUrl:"https://radio.staging.saooti.org/",
90
+ recoUrl: "https://reco.staging.saooti.org/",
91
91
  organisationId: undefined,
92
92
  rubriqueIdFilter: undefined,
93
93
  },
@@ -3,8 +3,6 @@ import { Media } from "@/stores/class/general/media";
3
3
  import { MediaRadio, Radio } from "@/stores/class/general/player";
4
4
  import { Podcast } from "@/stores/class/general/podcast";
5
5
  import { defineStore } from "pinia";
6
- import { Chaptering, ChapteringPercent } from "./class/chaptering/chaptering";
7
- import octopusApi from "@saooti/octopus-api";
8
6
  interface Transcript {
9
7
  actual: number;
10
8
  actualText: string;
@@ -24,7 +22,6 @@ interface PlayerState {
24
22
  playerTranscript?: Transcript;
25
23
  playerLargeVersion: boolean;
26
24
  playerVideo: boolean;
27
- playerChaptering?: Chaptering;
28
25
  }
29
26
  export const usePlayerStore = defineStore("PlayerStore", {
30
27
  state: (): PlayerState => ({
@@ -39,33 +36,13 @@ export const usePlayerStore = defineStore("PlayerStore", {
39
36
  playerSeekTime: 0,
40
37
  playerLargeVersion: false,
41
38
  playerVideo: false,
42
- playerChaptering: undefined,
43
39
  }),
44
40
  getters: {
45
- playerChapteringPercent(): ChapteringPercent|undefined{
46
- if(!this.playerChaptering || 0===this.playerTotal){
47
- return;
48
- }
49
- let chapteringPercent: ChapteringPercent = [];
50
- for (let i = 0, len = this.playerChaptering.chapters.length; i < len; i++) {
51
- chapteringPercent.push({
52
- startTime : this.playerChaptering.chapters[i].startTime,
53
- startDisplay: DurationHelper.formatDuration(this.playerChaptering.chapters[i].startTime, ':', false),
54
- startPercent: (this.playerChaptering.chapters[i].startTime * 100 ) / (Math.round(this.playerTotal)),
55
- endPercent:100,
56
- title: this.playerChaptering.chapters[i].title
57
- });
58
- }
59
- for (let i = 0, len = chapteringPercent.length; i < len; i++) {
60
- chapteringPercent[i].endPercent = chapteringPercent[i].startPercent + ((chapteringPercent[i+1]?.startPercent ?? 100) - chapteringPercent[i].startPercent);
61
- }
62
- return chapteringPercent;
63
- },
64
41
  playerHeight() {
65
42
  if ("STOPPED" === this.playerStatus) return 0;
66
43
  if (this.playerVideo) return "0px"/* "281px" */;
67
44
  if (this.playerLargeVersion) return "27rem";
68
- if (window.innerWidth > 450) return "6rem";
45
+ if (window.innerWidth > 450) return "5rem";
69
46
  return "3.5rem";
70
47
  },
71
48
  playedTime(): string {
@@ -114,7 +91,7 @@ export const usePlayerStore = defineStore("PlayerStore", {
114
91
  },
115
92
  },
116
93
  actions: {
117
- async playerPlay(param?: any, isVideo = false) {
94
+ playerPlay(param?: any, isVideo = false) {
118
95
  if (!param) {
119
96
  this.playerStatus = "STOPPED";
120
97
  this.playerPodcast = undefined;
@@ -123,7 +100,6 @@ export const usePlayerStore = defineStore("PlayerStore", {
123
100
  this.playerRadio = undefined;
124
101
  this.playerElapsed = 0;
125
102
  this.playerVideo = false;
126
- this.playerChaptering=undefined;
127
103
  return;
128
104
  }
129
105
  if (
@@ -142,26 +118,16 @@ export const usePlayerStore = defineStore("PlayerStore", {
142
118
  this.playerRadio = undefined;
143
119
  this.playerVideo = isVideo;
144
120
  this.playerElapsed = 0;
145
- this.playerChaptering=undefined;
146
121
  if (
147
122
  param.conferenceId &&
148
123
  (!param.podcastId || param.processingStatus !== "READY")
149
124
  ) {
150
125
  this.playerLive = param;
151
- return;
152
- }
153
- if (param.podcastId) {
126
+ } else if (param.podcastId) {
154
127
  this.playerPodcast = param;
155
- if(param.annotations?.chaptering){
156
- this.playerChaptering = await octopusApi.fetchDataPublic<Chaptering>(4, (param.annotations.chaptering as string));
157
- }
158
- return;
159
- }
160
- if (param.mediaId) {
128
+ } else if (param.mediaId) {
161
129
  this.playerMedia = param;
162
- return;
163
- }
164
- if (param.canalId) {
130
+ } else if (param.canalId) {
165
131
  this.playerRadio = { ...param, ...{ isInit: false } };
166
132
  }
167
133
  },
@@ -192,11 +158,9 @@ export const usePlayerStore = defineStore("PlayerStore", {
192
158
  this.playerRadio.podcast = podcast;
193
159
  },
194
160
 
195
- playerUpdateElapsed(elapsed: number, total?: number) {
161
+ playerUpdateElapsed(elapsed: number, total: number) {
196
162
  this.playerElapsed = elapsed;
197
- if(total){
198
- this.playerTotal = total;
199
- }
163
+ this.playerTotal = total;
200
164
  },
201
165
 
202
166
  playerUpdateTranscript(transcript?: Transcript) {
@@ -1,95 +0,0 @@
1
- <template>
2
- <ClassicModal
3
- id-modal="chaptering-modal"
4
- :title-modal="$t('Chaptering')"
5
- @close="closePopup"
6
- >
7
- <template #body>
8
- <div class="d-flex flex-column">
9
- <button
10
- v-for="(chapter, index) in playerChapteringPercent"
11
- :key="chapter"
12
- class="btn d-flex flex-nowrap align-items-center p-2 mt-1 c-hand text-truncate mb-1"
13
- :class="actualChapter === index ? 'chapter-selected':'border'"
14
- @click="goToChapter(index)"
15
- >
16
- <div class="d-flex align-items-center me-auto">
17
- <svg v-if="actualChapter === index" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-soundwave" viewBox="0 0 16 16">
18
- <path fill-rule="evenodd" d="M8.5 2a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-1 0v-11a.5.5 0 0 1 .5-.5m-2 2a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5m4 0a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5m-6 1.5A.5.5 0 0 1 5 6v4a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m8 0a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m-10 1A.5.5 0 0 1 3 7v2a.5.5 0 0 1-1 0V7a.5.5 0 0 1 .5-.5m12 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0V7a.5.5 0 0 1 .5-.5"/>
19
- </svg>
20
- <div v-else>{{ index + 1 }}</div>
21
- <div class="ms-2">{{ "- " + chapter.title }}</div>
22
- </div>
23
- <div>{{ chapter.startDisplay }}</div>
24
- </button>
25
- </div>
26
- </template>
27
- <template #footer>
28
- <button class="btn m-1" @click="closePopup">
29
- {{ $t("Close") }}
30
- </button>
31
- </template>
32
- </ClassicModal>
33
- </template>
34
-
35
- <script lang="ts">
36
- import { usePlayerStore } from "@/stores/PlayerStore";
37
- import { mapState, mapActions } from "pinia";
38
- import ClassicModal from "../modal/ClassicModal.vue";
39
- import { defineComponent } from "vue";
40
- export default defineComponent({
41
- name: "ChapteringModal",
42
- components: {
43
- ClassicModal,
44
- },
45
- props: {actualChapter: {default: -1, type: Number}},
46
- emits: ["close"],
47
- data() {
48
- return {
49
- audioPlayer: null as HTMLAudioElement | null,
50
- };
51
- },
52
- computed: {
53
- ...mapState(usePlayerStore, [
54
- "playerPodcast",
55
- "playerLive",
56
- "playerChapteringPercent",
57
- "playerTotal",
58
- "playerElapsed",
59
- ]),
60
- },
61
- created() {
62
- this.audioPlayer = document.querySelector("#audio-player");
63
- },
64
- methods: {
65
- ...mapActions(usePlayerStore, [
66
- "playerUpdateSeekTime",
67
- "playerUpdateElapsed",
68
- ]),
69
- closePopup(): void {
70
- this.$emit("close");
71
- },
72
- goToChapter(index: number) {
73
- if (!this.playerChapteringPercent || !this.audioPlayer) {
74
- return;
75
- }
76
- const seekTime =
77
- this.playerTotal *
78
- (this.playerChapteringPercent[index].startPercent / 100);
79
- this.playerUpdateSeekTime(seekTime);
80
- if (0 === seekTime) {
81
- this.playerUpdateElapsed(0);
82
- }
83
- this.audioPlayer.currentTime = seekTime;
84
- },
85
- },
86
- });
87
- </script>
88
- <style lang="scss">
89
- @import "@scss/_variables.scss";
90
- .octopus-app {
91
- .chapter-selected{
92
- border: $octopus-primary-color 3px solid;
93
- }
94
- }
95
- </style>
@@ -1,86 +0,0 @@
1
- <template>
2
- <div v-if="actualChapter" class="d-flex mb-1">
3
- <button
4
- class="btn-transparent d-flex align-items-center text-truncate medium-text text-light"
5
- @click="showChaptering = !showChaptering"
6
- >
7
- <div class="text-truncate">
8
- {{ actualIndex + 1 + " - " + actualChapter.title }}
9
- </div>
10
- <span class="saooti-right small-text" />
11
- </button>
12
- <ChapteringModal v-if="showChaptering" @close="showChaptering = false" :actual-chapter="actualIndex" />
13
- </div>
14
- <div v-else-if="playerChapteringPercent" class="margin-chaptering"></div>
15
- </template>
16
- <script lang="ts">
17
- import { ChapterPercent } from "@/stores/class/chaptering/chaptering";
18
- import { usePlayerStore } from "@/stores/PlayerStore";
19
- import { mapState } from "pinia";
20
- import { defineAsyncComponent, defineComponent } from "vue";
21
- const ChapteringModal = defineAsyncComponent(
22
- () => import("./ChapteringModal.vue"),
23
- );
24
- export default defineComponent({
25
- name: "PlayerChaptering",
26
-
27
- components: {
28
- ChapteringModal,
29
- },
30
- data() {
31
- return {
32
- actualChapter: undefined as ChapterPercent | undefined,
33
- actualIndex: -1 as number,
34
- showChaptering: false as boolean,
35
- };
36
- },
37
- computed: {
38
- ...mapState(usePlayerStore, ["playerChapteringPercent", "playerElapsed"]),
39
- },
40
- watch: {
41
- playerElapsed: {
42
- immediate: true,
43
- handler() {
44
- if (!this.playerChapteringPercent) {
45
- this.actualChapter = undefined;
46
- return;
47
- }
48
- const progressPercent = (this.playerElapsed ?? 0) * 100;
49
- if (
50
- this.actualChapter &&
51
- this.isInChapter(progressPercent, this.actualChapter)
52
- ) {
53
- return;
54
- }
55
- for (
56
- let i = 0, len = this.playerChapteringPercent.length;
57
- i < len;
58
- i++
59
- ) {
60
- if (
61
- this.isInChapter(progressPercent, this.playerChapteringPercent[i])
62
- ) {
63
- this.actualChapter = this.playerChapteringPercent[i];
64
- this.actualIndex = i;
65
- return;
66
- }
67
- }
68
- this.actualChapter = undefined;
69
- this.actualIndex = -1;
70
- },
71
- },
72
- },
73
- methods: {
74
- isInChapter(val: number, chapter: ChapterPercent) {
75
- return Math.floor(chapter.startPercent) <= val && val < Math.floor(chapter.endPercent);
76
- },
77
- },
78
- });
79
- </script>
80
- <style lang="scss">
81
- .octopus-app {
82
- .margin-chaptering{
83
- height: 23px;
84
- }
85
- }
86
- </style>
@@ -1,23 +0,0 @@
1
- //https://github.com/Podcastindex-org/podcast-namespace/blob/main/chapters/jsonChapters.md
2
- export interface Chaptering {
3
- version: string;
4
- chapters: Array<Chapter>;
5
- }
6
-
7
- export interface Chapter{
8
- startTime: number;
9
- title: string;
10
- img?: string;
11
- url?:string
12
- }
13
-
14
- export interface ChapterPercent {
15
- startTime: number;
16
- startDisplay: string;
17
- startPercent: number;
18
- endPercent: number;
19
- title: string;
20
- }
21
-
22
-
23
- export type ChapteringPercent = Array<ChapterPercent>;