@saooti/octopus-sdk 40.2.9 → 40.2.10
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/src/App.vue +1 -1
- package/src/components/display/filter/AdvancedSearch.vue +19 -1
- package/src/components/display/podcasts/PodcastModuleBox.vue +1 -1
- package/src/components/display/podcasts/TagList.vue +7 -2
- package/src/components/display/sharing/QrCode.vue +1 -1
- package/src/components/form/ClassicLoading.vue +1 -1
- package/src/components/misc/ClassicSpinner.vue +86 -2
- package/src/components/misc/TopBarMainContent.vue +5 -2
- package/src/components/misc/player/video/PlayerVideo.vue +13 -5
- package/src/components/misc/player/video/PlayerYoutubeEmbed.vue +29 -0
- package/src/components/pages/PodcastPage.vue +6 -1
- package/src/helper/youtubeVideoHelper.ts +13 -0
- package/src/style/share.scss +2 -2
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<div>{{ $t("Advanced filters") }}</div>
|
|
8
8
|
<ChevronDownIcon :class="{ 'arrow-transform': showFilters }" />
|
|
9
9
|
</button>
|
|
10
|
+
<Transition name="advanced-search">
|
|
10
11
|
<div
|
|
11
12
|
v-if="firstLoaded"
|
|
12
13
|
v-show="showFilters"
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
@update:sort="updateSort"
|
|
77
78
|
/>
|
|
78
79
|
</div>
|
|
80
|
+
</Transition>
|
|
79
81
|
</div>
|
|
80
82
|
</template>
|
|
81
83
|
|
|
@@ -282,12 +284,28 @@ export default defineComponent({
|
|
|
282
284
|
background: var(--octopus-background);
|
|
283
285
|
display: flex;
|
|
284
286
|
width: 100%;
|
|
285
|
-
|
|
287
|
+
padding-bottom: 1rem;
|
|
286
288
|
justify-content: space-around;
|
|
287
289
|
|
|
288
290
|
@media (width <= 720px) {
|
|
289
291
|
flex-wrap: wrap;
|
|
290
292
|
}
|
|
291
293
|
}
|
|
294
|
+
|
|
295
|
+
.advanced-search-enter-active,
|
|
296
|
+
.advanced-search-leave-active {
|
|
297
|
+
transition: 0.3s all;
|
|
298
|
+
opacity: 1;
|
|
299
|
+
max-height: 900px;
|
|
300
|
+
height: auto;
|
|
301
|
+
overflow: hidden;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.advanced-search-enter-from,
|
|
305
|
+
.advanced-search-leave-to {
|
|
306
|
+
opacity: 0;
|
|
307
|
+
max-height: 0;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
}
|
|
292
310
|
}
|
|
293
311
|
</style>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
<div v-if="isLiveReady" class="text-danger">
|
|
41
41
|
{{ $t("Episode record in live") }}
|
|
42
42
|
</div>
|
|
43
|
-
<div class="d-flex flex-column align-items-end
|
|
43
|
+
<div class="d-flex flex-column align-items-end">
|
|
44
44
|
<time :datetime="durationIso">
|
|
45
45
|
{{ duration }}
|
|
46
46
|
</time>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
v-if="undefined !==
|
|
3
|
+
v-if="undefined !== tagListFiltered && 0 !== tagListFiltered.length"
|
|
4
4
|
class="tag-list-component d-flex align-items-center flex-wrap mb-3 small-text"
|
|
5
5
|
>
|
|
6
6
|
<div class="fw-bold me-3">
|
|
7
7
|
{{ $t("Podcast tags") + " : " }}
|
|
8
8
|
</div>
|
|
9
9
|
<router-link
|
|
10
|
-
v-for="(tag, index) in
|
|
10
|
+
v-for="(tag, index) in tagListFiltered"
|
|
11
11
|
:key="tag"
|
|
12
12
|
class="d-flex align-items-center border p-1 m-1 text-dark"
|
|
13
13
|
:to="{
|
|
@@ -72,6 +72,11 @@ export default defineComponent({
|
|
|
72
72
|
},
|
|
73
73
|
computed: {
|
|
74
74
|
...mapState(useFilterStore, ["filterOrgaId"]),
|
|
75
|
+
tagListFiltered(): Array<string>{
|
|
76
|
+
return this.tagList.filter((tag: string) => {
|
|
77
|
+
return !tag.match(/^\[\[.*\]\]$/);
|
|
78
|
+
});
|
|
79
|
+
},
|
|
75
80
|
organisationQuery(){
|
|
76
81
|
if(this.filterOrgaId){
|
|
77
82
|
return undefined;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
:margin="2"
|
|
26
26
|
/>
|
|
27
27
|
<div class="d-flex align-items-center my-3">
|
|
28
|
-
<FormatSwitch
|
|
28
|
+
<FormatSwitch v-model:is-svg="isSvg" class="me-3"/>
|
|
29
29
|
<button class="btn btn-primary" @click="download">
|
|
30
30
|
{{ $t("Download") }}
|
|
31
31
|
</button>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="octopus-spinner" :
|
|
2
|
+
<div class="octopus-spinner" :style="small ? '--size-spinner:1rem;' : ''" >
|
|
3
|
+
<div v-for="index of 12" :key="index"></div>
|
|
4
|
+
</div>
|
|
3
5
|
</template>
|
|
4
6
|
|
|
5
7
|
<script lang="ts">
|
|
@@ -13,7 +15,89 @@ export default defineComponent({
|
|
|
13
15
|
</script>
|
|
14
16
|
<style lang="scss">
|
|
15
17
|
.octopus-app .octopus-spinner {
|
|
18
|
+
|
|
19
|
+
--size-spinner: 3rem;
|
|
20
|
+
--size-spinner-section: calc(var(--size-spinner) / 20);
|
|
21
|
+
--half-size-spinner: calc(var(--size-spinner) / 2);
|
|
22
|
+
|
|
23
|
+
color: #000000;
|
|
16
24
|
display: inline-block;
|
|
25
|
+
position: relative;
|
|
26
|
+
width: var(--size-spinner);
|
|
27
|
+
height: var(--size-spinner);
|
|
28
|
+
|
|
29
|
+
div {
|
|
30
|
+
transform-origin: var(--half-size-spinner) var(--half-size-spinner);
|
|
31
|
+
animation: octopus-spinner 1.2s linear infinite;
|
|
32
|
+
}
|
|
33
|
+
div:after {
|
|
34
|
+
content: " ";
|
|
35
|
+
display: block;
|
|
36
|
+
position: absolute;
|
|
37
|
+
top: 3px;
|
|
38
|
+
left: calc(var(--half-size-spinner) - calc(var(--size-spinner-section) / 2));
|
|
39
|
+
width: var(--size-spinner-section);
|
|
40
|
+
height: calc(var(--half-size-spinner) / 3);
|
|
41
|
+
border-radius: 20%;
|
|
42
|
+
background: currentColor;
|
|
43
|
+
}
|
|
44
|
+
div:nth-child(1) {
|
|
45
|
+
transform: rotate(0deg);
|
|
46
|
+
animation-delay: -1.1s;
|
|
47
|
+
}
|
|
48
|
+
div:nth-child(2) {
|
|
49
|
+
transform: rotate(30deg);
|
|
50
|
+
animation-delay: -1s;
|
|
51
|
+
}
|
|
52
|
+
div:nth-child(3) {
|
|
53
|
+
transform: rotate(60deg);
|
|
54
|
+
animation-delay: -0.9s;
|
|
55
|
+
}
|
|
56
|
+
div:nth-child(4) {
|
|
57
|
+
transform: rotate(90deg);
|
|
58
|
+
animation-delay: -0.8s;
|
|
59
|
+
}
|
|
60
|
+
div:nth-child(5) {
|
|
61
|
+
transform: rotate(120deg);
|
|
62
|
+
animation-delay: -0.7s;
|
|
63
|
+
}
|
|
64
|
+
div:nth-child(6) {
|
|
65
|
+
transform: rotate(150deg);
|
|
66
|
+
animation-delay: -0.6s;
|
|
67
|
+
}
|
|
68
|
+
div:nth-child(7) {
|
|
69
|
+
transform: rotate(180deg);
|
|
70
|
+
animation-delay: -0.5s;
|
|
71
|
+
}
|
|
72
|
+
div:nth-child(8) {
|
|
73
|
+
transform: rotate(210deg);
|
|
74
|
+
animation-delay: -0.4s;
|
|
75
|
+
}
|
|
76
|
+
div:nth-child(9) {
|
|
77
|
+
transform: rotate(240deg);
|
|
78
|
+
animation-delay: -0.3s;
|
|
79
|
+
}
|
|
80
|
+
div:nth-child(10) {
|
|
81
|
+
transform: rotate(270deg);
|
|
82
|
+
animation-delay: -0.2s;
|
|
83
|
+
}
|
|
84
|
+
div:nth-child(11) {
|
|
85
|
+
transform: rotate(300deg);
|
|
86
|
+
animation-delay: -0.1s;
|
|
87
|
+
}
|
|
88
|
+
div:nth-child(12) {
|
|
89
|
+
transform: rotate(330deg);
|
|
90
|
+
animation-delay: 0s;
|
|
91
|
+
}
|
|
92
|
+
@keyframes octopus-spinner {
|
|
93
|
+
0% {
|
|
94
|
+
opacity: 1;
|
|
95
|
+
}
|
|
96
|
+
100% {
|
|
97
|
+
opacity: 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/* display: inline-block;
|
|
17
101
|
width: 2rem;
|
|
18
102
|
height: 2rem;
|
|
19
103
|
border-radius: 50%;
|
|
@@ -31,6 +115,6 @@ export default defineComponent({
|
|
|
31
115
|
to {
|
|
32
116
|
transform: rotate(360deg);
|
|
33
117
|
}
|
|
34
|
-
}
|
|
118
|
+
} */
|
|
35
119
|
}
|
|
36
120
|
</style>
|
|
@@ -308,12 +308,15 @@ export default defineComponent({
|
|
|
308
308
|
color: white;
|
|
309
309
|
font-weight: bold;
|
|
310
310
|
font-size: 0.93rem;
|
|
311
|
+
text-decoration: underline;
|
|
312
|
+
text-decoration-color: transparent;
|
|
313
|
+
transition: text-decoration-color 250ms;
|
|
314
|
+
text-underline-offset: 8px;
|
|
311
315
|
|
|
312
316
|
&.link-hover:hover,
|
|
313
317
|
&.link-hover.router-link-exact-active.router-link-active {
|
|
314
318
|
color: white;
|
|
315
|
-
text-decoration:
|
|
316
|
-
text-underline-offset: 8px;
|
|
319
|
+
text-decoration-color: white;
|
|
317
320
|
}
|
|
318
321
|
}
|
|
319
322
|
|
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
<WindowCloseIcon />
|
|
6
6
|
</button>
|
|
7
7
|
<div class="video-wrapper">
|
|
8
|
-
<
|
|
8
|
+
<PlayerYoutubeEmbed v-if="youtubeId" :youtube-id="youtubeId" />
|
|
9
|
+
<PlayerVideoDigiteka v-else-if="!playerLive" :video-id="playerPodcast?.video?.videoId" />
|
|
9
10
|
<PlayerVideoHls v-else :hls-url="hlsVideoUrl" />
|
|
10
11
|
</div>
|
|
11
12
|
</template>
|
|
12
13
|
</teleport>
|
|
13
14
|
</template>
|
|
14
15
|
<script lang="ts">
|
|
16
|
+
import youtubeVideoHelper from "../../../../helper/youtubeVideoHelper";
|
|
15
17
|
import WindowCloseIcon from "vue-material-design-icons/WindowClose.vue";
|
|
16
18
|
import { usePlayerStore } from "../../../../stores/PlayerStore";
|
|
17
19
|
import { useApiStore } from "../../../../stores/ApiStore";
|
|
@@ -23,16 +25,22 @@ const PlayerVideoDigiteka = defineAsyncComponent(
|
|
|
23
25
|
const PlayerVideoHls = defineAsyncComponent(
|
|
24
26
|
() => import("../video/PlayerVideoHls.vue"),
|
|
25
27
|
);
|
|
28
|
+
const PlayerYoutubeEmbed = defineAsyncComponent(
|
|
29
|
+
() => import("../video/PlayerYoutubeEmbed.vue"),
|
|
30
|
+
);
|
|
26
31
|
export default defineComponent({
|
|
27
32
|
name: "PlayerVideo",
|
|
28
33
|
|
|
29
34
|
components: {
|
|
30
35
|
PlayerVideoDigiteka,
|
|
31
36
|
PlayerVideoHls,
|
|
37
|
+
PlayerYoutubeEmbed,
|
|
32
38
|
WindowCloseIcon,
|
|
33
39
|
},
|
|
34
40
|
data() {
|
|
35
|
-
return {
|
|
41
|
+
return {
|
|
42
|
+
youtubeId: undefined as string|undefined,
|
|
43
|
+
};
|
|
36
44
|
},
|
|
37
45
|
computed: {
|
|
38
46
|
...mapState(useApiStore, ["hlsUrl"]),
|
|
@@ -43,9 +51,9 @@ export default defineComponent({
|
|
|
43
51
|
}
|
|
44
52
|
return `${this.hlsUrl}live/video_dev.${this.playerLive.conferenceId}/index.m3u8`;
|
|
45
53
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
},
|
|
55
|
+
created(){
|
|
56
|
+
this.youtubeId = youtubeVideoHelper.getYoutubeId((this.playerPodcast ?? this.playerLive )?.tags ?? []);
|
|
49
57
|
},
|
|
50
58
|
|
|
51
59
|
methods: {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<iframe
|
|
3
|
+
width="500"
|
|
4
|
+
height="281"
|
|
5
|
+
:title="$t('Video')"
|
|
6
|
+
class="youtube-iframe"
|
|
7
|
+
:src="'https://www.youtube.com/embed/'+youtubeId"
|
|
8
|
+
frameborder="0"
|
|
9
|
+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
10
|
+
referrerpolicy="strict-origin-when-cross-origin"
|
|
11
|
+
allowfullscreen>
|
|
12
|
+
</iframe>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
import { defineComponent } from "vue";
|
|
17
|
+
export default defineComponent({
|
|
18
|
+
name: "PlayerYoutubeEmbed",
|
|
19
|
+
components: {
|
|
20
|
+
},
|
|
21
|
+
props: {
|
|
22
|
+
youtubeId: { default: undefined, type: String },
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
<style lang="scss">
|
|
28
|
+
@use "../../../../style/videoPlayer";
|
|
29
|
+
</style>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
:organisation-id="podcast.organisation.id"
|
|
22
22
|
/>
|
|
23
23
|
<SharePlayer
|
|
24
|
-
v-if="!isPodcastmaker && editRight"
|
|
24
|
+
v-if="!isPodcastmaker && editRight && !youtubeId"
|
|
25
25
|
:podcast="podcast"
|
|
26
26
|
:emission="podcast?.emission"
|
|
27
27
|
:organisation-id="authOrgaId"
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
</template>
|
|
69
69
|
|
|
70
70
|
<script lang="ts">
|
|
71
|
+
import youtubeVideoHelper from "../../helper/youtubeVideoHelper";
|
|
71
72
|
import {useOrgaComputed} from "../composable/useOrgaComputed";
|
|
72
73
|
import PodcastInlineList from "../display/podcasts/PodcastInlineList.vue";
|
|
73
74
|
import PodcastModuleBox from "../display/podcasts/PodcastModuleBox.vue";
|
|
@@ -135,6 +136,7 @@ export default defineComponent({
|
|
|
135
136
|
error: false as boolean,
|
|
136
137
|
fetchConference: undefined as Conference | undefined,
|
|
137
138
|
infoReload: undefined as ReturnType<typeof setTimeout> | undefined,
|
|
139
|
+
youtubeId: undefined as string|undefined,
|
|
138
140
|
};
|
|
139
141
|
},
|
|
140
142
|
|
|
@@ -312,6 +314,9 @@ export default defineComponent({
|
|
|
312
314
|
this.podcastInProcessing();
|
|
313
315
|
this.updatePathParams(this.podcast.title);
|
|
314
316
|
await this.getCommentsConfig(this.podcast);
|
|
317
|
+
if((this.fetchConference?.videoProfile?.includes("video_") && "READY_TO_RECORD" === this.podcast.processingStatus) || undefined !== this.podcast.video?.videoId){
|
|
318
|
+
this.youtubeId = youtubeVideoHelper.getYoutubeId(this.podcast?.tags ?? []);
|
|
319
|
+
}
|
|
315
320
|
this.loaded = true;
|
|
316
321
|
} catch (error) {
|
|
317
322
|
this.handle403(error as AxiosError);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
getYoutubeId(tags: Array<string>){
|
|
3
|
+
let youtubeId = undefined;
|
|
4
|
+
for(const tag of tags){
|
|
5
|
+
const regexExec = /^\[\[https:\/\/(?:www.)?youtube.com\/(?:watch\?v=|live\/)(?<id>\S+)\]\]$/.exec(tag);
|
|
6
|
+
if(regexExec?.groups?.id){
|
|
7
|
+
youtubeId = regexExec.groups.id;
|
|
8
|
+
break;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return youtubeId;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/style/share.scss
CHANGED
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
.img-box-podcast{
|
|
50
|
-
height: calc(var(--octopus-podcast-size) -
|
|
51
|
-
width: calc(var(--octopus-podcast-size) -
|
|
50
|
+
height: calc(var(--octopus-podcast-size) - 2px);
|
|
51
|
+
width: calc(var(--octopus-podcast-size) - 2px);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
.img-box,.img-box.img-box-podcast{
|