@saooti/octopus-sdk 38.0.31 → 38.0.33

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": "38.0.31",
3
+ "version": "38.0.33",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
@@ -111,6 +111,7 @@ body{
111
111
  margin: 1rem 0;
112
112
  }
113
113
  }
114
+
114
115
  .flex-super-grow{
115
116
  flex-grow: 2;
116
117
  }
@@ -20,6 +20,19 @@
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
+ }
23
36
  &,.octopus-progress-bar{
24
37
  height: 4px;
25
38
  @media (max-width: 960px) {
@@ -1,51 +1,151 @@
1
1
  <template>
2
2
  <div v-if="!isLoading && (authenticated || !noSharing)" class="module-box">
3
- <div class="d-flex align-items-center mb-3">
4
- <h2 class="big-h2 mb-0">
5
- {{ $t("Share") }}
6
- </h2>
7
- <span
8
- v-if="authenticated"
9
- id="popover-share-help"
10
- role="button"
11
- tabindex="0"
12
- class="saooti-help ms-2"
13
- :aria-label="$t('Help')"
3
+ <div class="d-flex align-items-center justify-content-between">
4
+ <div v-if="!isGarStudent && !noSharing" class="d-flex flex-column me-2">
5
+ <div class="h4 mb-2">
6
+ {{ $t("Share in one click") }}
7
+ </div>
8
+ <div class="d-flex align-items-center">
9
+ <template v-for="button in arrayShareButtons" :key="button.title">
10
+ <a
11
+ v-if="button.condition"
12
+ rel="noopener"
13
+ target="_blank"
14
+ :href="button.url"
15
+ :class="getClass(button.className)"
16
+ class="me-2"
17
+ :title="button.title"
18
+ >
19
+ <div :class="button.icon" />
20
+ </a>
21
+ </template>
22
+ <button
23
+ :class="getClass()"
24
+ class="saooti-link"
25
+ :title="$t('Copy this page URL')"
26
+ @click="onCopyCode(urlPage, afterCopy)"
27
+ />
28
+ </div>
29
+ </div>
30
+ <div v-if="podcast || emission || playlist" class="d-flex flex-column me-2">
31
+ <div class="h4 mb-2">
32
+ {{ $t("Newsletter") }}
33
+ </div>
34
+ <div class="d-flex align-items-center justify-content-center">
35
+ <button
36
+ :class="getClass()"
37
+ class="saooti-newsletter"
38
+ :title="$t('Share newsletter')"
39
+ @click="newsletter = true"
40
+ />
41
+ </div>
42
+ </div>
43
+ <div class="d-flex flex-column me-2">
44
+ <div class="h4 mb-2">
45
+ {{ $t("QR Code") }}
46
+ </div>
47
+ <div class="d-flex align-items-center justify-content-center">
48
+ <button
49
+ :class="getClass()"
50
+ :title="$t('Share QR Code')"
51
+ class="saooti-qrcode"
52
+ @click="qrCode = true"
53
+ />
54
+ </div>
55
+ </div>
56
+ <div v-if="'' !== rssUrl && displayRss" class="d-flex flex-column me-2">
57
+ <div class="h4 mb-2">
58
+ {{ $t("Rss feed") }}
59
+ </div>
60
+ <div class="d-flex align-items-center justify-content-center">
61
+ <a
62
+ rel="noopener"
63
+ target="_blank"
64
+ class="saooti-rss"
65
+ :class="getClass()"
66
+ :href="rssUrl"
67
+ :title="titleRssButton"
68
+ @click.prevent="openPopup()"
69
+ />
70
+ </div>
71
+ </div>
72
+ <div v-if="!isPodcastmaker && authenticated && podcast && isProduction" class="d-flex flex-column me-2">
73
+ <div class="h4 mb-2">
74
+ {{ $t("Generate a social media post (with AI)") }}
75
+ </div>
76
+ <div class="d-flex align-items-center justify-content-center">
77
+ <router-link
78
+ :class="getClass()"
79
+ :title="$t('Generate a social media post (with AI)')"
80
+ :to="{
81
+ name: 'advancedShare',
82
+ params: { podcastId: podcast.podcastId },
83
+ }"
84
+ >
85
+ <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-stars" viewBox="0 0 16 16">
86
+ <path d="M7.657 6.247c.11-.33.576-.33.686 0l.645 1.937a2.89 2.89 0 0 0 1.829 1.828l1.936.645c.33.11.33.576 0 .686l-1.937.645a2.89 2.89 0 0 0-1.828 1.829l-.645 1.936a.361.361 0 0 1-.686 0l-.645-1.937a2.89 2.89 0 0 0-1.828-1.828l-1.937-.645a.361.361 0 0 1 0-.686l1.937-.645a2.89 2.89 0 0 0 1.828-1.828l.645-1.937zM3.794 1.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387A1.734 1.734 0 0 0 4.593 5.69l-.387 1.162a.217.217 0 0 1-.412 0L3.407 5.69A1.734 1.734 0 0 0 2.31 4.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387A1.734 1.734 0 0 0 3.407 2.31l.387-1.162zM10.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732L9.1 2.137a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L10.863.1z"/>
87
+ </svg>
88
+ </router-link>
89
+ </div>
90
+ </div>
91
+
92
+ <ClipboardModal
93
+ v-if="dataRSSSave"
94
+ :link="rssUrl"
95
+ :emission="emission"
96
+ @close="dataRSSSave = false"
97
+ @copy="afterCopy"
98
+ />
99
+ <NewsletterModal
100
+ v-if="newsletter"
101
+ :closable="true"
102
+ :podcast="podcast"
103
+ :emission="emission"
104
+ :playlist="playlist"
105
+ @close="newsletter = false"
14
106
  />
15
- <ClassicPopover
16
- v-if="authenticated"
17
- target="popover-share-help"
18
- :content="$t('Share this page without edit and share blocks')"
19
- relative-class="page-element"
20
- :is-fixed="true"
107
+ <QrCodeModal
108
+ v-if="qrCode"
109
+ :closable="true"
110
+ :url-page="urlPage"
111
+ @close="qrCode = false"
112
+ />
113
+ <SnackBar
114
+ v-if="lazyLoadingSnackbar"
115
+ ref="snackbar"
116
+ position="bottom-left"
21
117
  />
22
118
  </div>
23
- <ShareButtonsIntern
24
- :no-sharing="noSharing"
25
- :podcast="podcast"
26
- :emission="emission"
27
- :playlist="playlist"
28
- :participant-id="participantId"
29
- :organisation-id="organisationId"
30
- />
31
119
  </div>
32
120
  </template>
33
121
 
34
122
  <script lang="ts">
35
123
  import { useSaveFetchStore } from "@/stores/SaveFetchStore";
36
- import { mapActions } from "pinia";
124
+ import { mapActions, mapState } from "pinia";
37
125
  import { Emission } from "@/stores/class/general/emission";
38
126
  import { Podcast } from "@/stores/class/general/podcast";
39
127
  import { state } from "../../../stores/ParamSdkStore";
128
+ import octopusApi from "@saooti/octopus-api";
40
129
  import displayMethods from "../../mixins/displayMethods";
41
- import ClassicPopover from "../../misc/ClassicPopover.vue";
42
- import ShareButtonsIntern from "./ShareButtonsIntern.vue";
43
- import { defineComponent } from "vue";
130
+ import { defineAsyncComponent, defineComponent } from "vue";
44
131
  import { Playlist } from "@/stores/class/general/playlist";
132
+ import { useAuthStore } from "@/stores/AuthStore";
133
+ const ClipboardModal = defineAsyncComponent(
134
+ () => import("../../misc/modal/ClipboardModal.vue"),
135
+ );
136
+ const NewsletterModal = defineAsyncComponent(
137
+ () => import("../../misc/modal/NewsletterModal.vue"),
138
+ );
139
+ const QrCodeModal = defineAsyncComponent(
140
+ () => import("../../misc/modal/QrCodeModal.vue"),
141
+ );
142
+ const SnackBar = defineAsyncComponent(() => import("../../misc/SnackBar.vue"));
45
143
  export default defineComponent({
46
144
  components: {
47
- ShareButtonsIntern,
48
- ClassicPopover,
145
+ ClipboardModal,
146
+ NewsletterModal,
147
+ QrCodeModal,
148
+ SnackBar,
49
149
  },
50
150
  mixins: [displayMethods],
51
151
  props: {
@@ -59,14 +159,94 @@ export default defineComponent({
59
159
  return {
60
160
  noSharing: true as boolean,
61
161
  isLoading: true as boolean,
162
+ dataRSSSave: false as boolean,
163
+ newsletter: false as boolean,
164
+ qrCode: false as boolean,
165
+ displayRss: false as boolean,
166
+ lazyLoadingSnackbar: false as boolean,
62
167
  };
63
168
  },
64
169
  computed: {
170
+ ...mapState(useAuthStore, ["isGarStudent"]),
65
171
  authenticated(): boolean {
66
172
  return state.generalParameters.authenticated as boolean;
67
173
  },
174
+ titleRssButton(): string {
175
+ if (this.participantId) {
176
+ return this.$t("Subscribe to this participant");
177
+ }
178
+ if (this.emission) {
179
+ return this.$t("Subscribe to this emission");
180
+ }
181
+ return this.$t("Subscribe to this RSS feed");
182
+ },
183
+ arrayShareButtons() {
184
+ return [
185
+ {
186
+ title: "Facebook",
187
+ icon: "saooti-facebook",
188
+ className: "btn-facebook",
189
+ url: `https://www.facebook.com/sharer/sharer.php?u=${this.urlPage}`,
190
+ condition: true,
191
+ },
192
+ {
193
+ title: "X",
194
+ icon: "saooti-twitter",
195
+ className: "btn-twitter",
196
+ url: `https://twitter.com/intent/tweet?text=${this.urlPage}`,
197
+ condition: true,
198
+ },
199
+ {
200
+ title: "Linkedin",
201
+ icon: "saooti-linkedin",
202
+ className: "btn-linkedin",
203
+ url: `https://www.linkedin.com/sharing/share-offsite/?url=${this.urlPage}`,
204
+ condition: true,
205
+ },
206
+ {
207
+ title: "Whatsapp",
208
+ icon: "saooti-Whatsapp",
209
+ className: "btn-whatsapp",
210
+ url: `whatsapp://send?text=${this.urlPage}`,
211
+ condition: window.matchMedia("(hover: none)").matches,
212
+ },
213
+ ];
214
+ },
215
+ urlPage(): string {
216
+ return window.location.href;
217
+ },
218
+ isProduction(): boolean {
219
+ return state.generalParameters.isProduction as boolean;
220
+ },
221
+ isPodcastmaker(): boolean {
222
+ return state.generalParameters.podcastmaker as boolean;
223
+ },
224
+ rssUrl(): string {
225
+ let api = state.generalParameters.ApiUri + "rss/";
226
+ if (this.emission) {
227
+ return api + "emission/" + this.emission.emissionId + ".rss";
228
+ }
229
+ if (this.participantId) {
230
+ return api + "participant/" + this.participantId + ".rss";
231
+ }
232
+ if (this.playlist) {
233
+ return api + "playlist/" + this.playlist.playlistId + ".rss";
234
+ }
235
+ if (this.organisationId) {
236
+ return api + "productor/" + this.organisationId + ".rss";
237
+ }
238
+ return "";
239
+ },
68
240
  },
69
241
  async created() {
242
+ if (undefined !== this.participantId) {
243
+ this.displayRss = await octopusApi.fetchDataPublic<boolean>(
244
+ 0,
245
+ `rss/participants/allowed/${this.organisationId}`,
246
+ );
247
+ } else {
248
+ this.displayRss = true;
249
+ }
70
250
  if (!this.organisationId) {
71
251
  return;
72
252
  }
@@ -76,6 +256,24 @@ export default defineComponent({
76
256
  },
77
257
  methods: {
78
258
  ...mapActions(useSaveFetchStore, ["getOrgaAttributes"]),
259
+ getClass(className = "btn-rss"): string {
260
+ return `btn ${className} share-btn mb-2 text-dark`;
261
+ },
262
+ openPopup(): void {
263
+ this.dataRSSSave = !this.dataRSSSave;
264
+ },
265
+ afterCopy(): void {
266
+ if (!this.lazyLoadingSnackbar) {
267
+ this.lazyLoadingSnackbar = true;
268
+ setTimeout(() => {
269
+ this.afterCopy();
270
+ }, 500);
271
+ } else {
272
+ (this.$refs.snackbar as InstanceType<typeof SnackBar>).open(
273
+ this.$t("Link in clipboard"),
274
+ );
275
+ }
276
+ },
79
277
  },
80
278
  });
81
279
  </script>
@@ -5,7 +5,7 @@
5
5
  ref="popover"
6
6
  tabindex="0"
7
7
  class="octopus-popover"
8
- :class="onlyClick ? 'octopus-dropdown' : ''"
8
+ :class="[onlyClick ? 'octopus-dropdown' : '', popoverClass]"
9
9
  :style="positionInlineStyle"
10
10
  @blur="clearDataBlur"
11
11
  @mouseenter="overPopover=true"
@@ -30,10 +30,12 @@ export default defineComponent({
30
30
  target: { type: String, required: true },
31
31
  disable: { type: Boolean, default: false },
32
32
  onlyClick: { type: Boolean, default: false },
33
+ onlyMouse: { type: Boolean, default: false },
33
34
  isFixed: { type: Boolean, default: false },
34
35
  relativeClass: { type: String, default: undefined },
35
36
  leftPos: { type: Boolean, default: false },
36
37
  topPos: { type: Boolean, default: false },
38
+ popoverClass: { type: String, default: undefined },
37
39
  },
38
40
  data() {
39
41
  return {
@@ -70,7 +72,9 @@ export default defineComponent({
70
72
  );
71
73
  this.targetElement.addEventListener("mouseleave", this.clearDataTimeout);
72
74
  }
73
- this.targetElement.addEventListener("click", this.setPopoverData);
75
+ if (!this.onlyMouse) {
76
+ this.targetElement.addEventListener("click", this.setPopoverData);
77
+ }
74
78
  this.targetElement.addEventListener("blur", this.clearDataBlur);
75
79
  }
76
80
  },
@@ -83,7 +87,9 @@ export default defineComponent({
83
87
  );
84
88
  this.targetElement.removeEventListener("mouseleave", this.clearDataTimeout);
85
89
  }
86
- this.targetElement.removeEventListener("click", this.setPopoverData);
90
+ if (!this.onlyMouse) {
91
+ this.targetElement.removeEventListener("click", this.setPopoverData);
92
+ }
87
93
  this.targetElement.addEventListener("blur", this.clearDataBlur);
88
94
  }
89
95
  },
@@ -60,7 +60,7 @@
60
60
  </template>
61
61
  </template>
62
62
  <hr />
63
- <a class="octopus-dropdown-item" href="/sso/logout" realLink="true">
63
+ <a class="octopus-dropdown-item c-hand" @click="logoutFunction" >
64
64
  {{ $t("Logout") }}
65
65
  </a>
66
66
  </template>
@@ -72,6 +72,7 @@
72
72
  </template>
73
73
 
74
74
  <script lang="ts">
75
+ import crudApi from "@/api/classicCrud";
75
76
  import { state } from "../../stores/ParamSdkStore";
76
77
  import ClassicPopover from "../misc/ClassicPopover.vue";
77
78
  import { useAuthStore } from "@/stores/AuthStore";
@@ -148,8 +149,17 @@ export default defineComponent({
148
149
  },
149
150
  },
150
151
  methods:{
152
+ async logoutFunction(){
153
+ try {
154
+ await crudApi.postData(4, '/logout', undefined);
155
+ await this.$router.push({ path: '/' });
156
+ location.reload();
157
+ } catch (error) {
158
+ //Do nothing
159
+ }
160
+ },
151
161
  goToAdministration(){
152
- if("homePriv" !== this.$route.name){
162
+ if("backoffice" !== this.$route.name){
153
163
  this.$router.push("/main/priv/backoffice");
154
164
  }else if (window.history.length > 1) {
155
165
  this.$router.go(-1);
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="octopus-progress">
2
+ <div v-if="display" id="test-menu-dropdown" class="octopus-progress">
3
3
  <div
4
4
  v-if="secondaryProgress"
5
5
  class="octopus-progress-bar bg-light"
@@ -48,18 +48,50 @@
48
48
  />
49
49
  <div
50
50
  v-if="isProgressCursor"
51
- class="progress-bar-cursor"
51
+ class="octopus-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>
54
80
  </div>
55
81
  </template>
56
82
 
57
83
  <script lang="ts">
58
84
  import { usePlayerStore } from "@/stores/PlayerStore";
59
85
  import { mapState } from "pinia";
60
- import { defineComponent } from "vue";
86
+ import { defineAsyncComponent, defineComponent } from "vue";
87
+ const ClassicPopover = defineAsyncComponent(
88
+ () => import("../misc/ClassicPopover.vue"),
89
+ );
61
90
  export default defineComponent({
62
91
  name: "ProgressBar",
92
+ components: {
93
+ ClassicPopover,
94
+ },
63
95
  props: {
64
96
  alertBar: { default: undefined, type: Number },
65
97
  mainProgress: { default: 0, type: Number },
@@ -73,7 +105,14 @@ export default defineComponent({
73
105
  };
74
106
  },
75
107
  computed: {
76
- ...mapState(usePlayerStore, ["playerMedia"]),
108
+ ...mapState(usePlayerStore, [
109
+ "playerMedia",
110
+ "playerChapteringPercent",
111
+ "playerStatus",
112
+ ]),
113
+ display() {
114
+ return "STOPPED" !== this.playerStatus;
115
+ },
77
116
  },
78
117
  watch: {
79
118
  playerMedia: {
@@ -104,4 +143,15 @@ export default defineComponent({
104
143
 
105
144
  <style lang="scss">
106
145
  @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
+ }
107
157
  </style>
@@ -0,0 +1,95 @@
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>