@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.
- package/package.json +1 -1
- package/public/img/wave.svg +5 -0
- package/src/assets/general.scss +0 -1
- package/src/assets/progressbar.scss +0 -13
- package/src/components/display/podcasts/PodcastModuleBox.vue +8 -0
- package/src/components/display/sharing/ShareButtons.vue +1 -1
- package/src/components/display/sharing/ShareButtonsIntern.vue +2 -2
- package/src/components/display/sharing/SharePlayerColors.vue +2 -0
- package/src/components/form/ClassicSelect.vue +19 -0
- package/src/components/misc/ClassicAccordion.vue +19 -7
- package/src/components/misc/ClassicNav.vue +6 -2
- package/src/components/misc/ClassicPopover.vue +15 -11
- package/src/components/misc/HomeDropdown.vue +13 -2
- package/src/components/misc/ProgressBar.vue +4 -54
- package/src/components/misc/modal/NewsletterModal.vue +1 -0
- package/src/components/misc/player/PlayerCompact.vue +0 -3
- package/src/components/misc/player/PlayerComponent.vue +1 -18
- package/src/components/misc/player/PlayerLarge.vue +0 -3
- package/src/components/mixins/player/playerLogicProgress.ts +1 -1
- package/src/components/pages/RadioPage.vue +1 -2
- package/src/helper/duration.ts +8 -6
- package/src/locale/de.ts +1 -1
- package/src/locale/en.ts +1 -1
- package/src/locale/es.ts +1 -1
- package/src/locale/fr.ts +2 -2
- package/src/locale/it.ts +1 -1
- package/src/locale/sl.ts +1 -1
- package/src/stores/ParamSdkStore.ts +21 -21
- package/src/stores/PlayerStore.ts +7 -43
- package/src/components/misc/player/ChapteringModal.vue +0 -95
- package/src/components/misc/player/PlayerChaptering.vue +0 -86
- package/src/stores/class/chaptering/chaptering.ts +0 -23
package/package.json
CHANGED
|
@@ -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>
|
package/src/assets/general.scss
CHANGED
|
@@ -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
|
-
|
|
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="
|
|
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
|
-
.
|
|
56
|
-
|
|
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
|
|
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="
|
|
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.
|
|
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.
|
|
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
|
-
<
|
|
3
|
+
<button
|
|
4
4
|
v-if="isAuthenticatedWithOrga"
|
|
5
5
|
:title="$t('My space')"
|
|
6
|
-
|
|
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
|
|
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="
|
|
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 {
|
|
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>
|
|
@@ -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="
|
|
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
|
|
|
@@ -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
|
);
|
package/src/helper/duration.ts
CHANGED
|
@@ -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
|
|
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 (
|
|
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": "
|
|
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:
|
|
7
|
-
authenticated:
|
|
8
|
-
isAdmin:
|
|
9
|
-
isRoleLive:
|
|
10
|
-
isCommments:
|
|
11
|
-
isOrganisation:
|
|
12
|
-
isPlaylist:
|
|
13
|
-
isProduction:
|
|
14
|
-
isContribution:
|
|
15
|
-
isRadio:
|
|
16
|
-
ApiUri: "https://api.
|
|
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.
|
|
31
|
-
hlsUri: "https://hls.live.
|
|
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.
|
|
84
|
-
commentsUrl: "https://comments.
|
|
85
|
-
imageUrl: "https://imageproxy.
|
|
86
|
-
studioUrl: "https://studio.
|
|
87
|
-
playerUrl: "https://playerbeta.
|
|
88
|
-
speechToTextUrl: "https://speech2text.
|
|
89
|
-
radioUrl:"https://radio.
|
|
90
|
-
recoUrl: "https://reco.
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
152
|
-
}
|
|
153
|
-
if (param.podcastId) {
|
|
126
|
+
} else if (param.podcastId) {
|
|
154
127
|
this.playerPodcast = param;
|
|
155
|
-
|
|
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
|
-
|
|
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
|
|
161
|
+
playerUpdateElapsed(elapsed: number, total: number) {
|
|
196
162
|
this.playerElapsed = elapsed;
|
|
197
|
-
|
|
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>;
|