@saooti/octopus-sdk 41.10.5 → 41.10.7
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/BUILD_FIX.md +105 -0
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/src/components/composable/player/usePlayerLogic.ts +32 -5
- package/src/components/display/sharing/SubscribeButtons.vue +153 -196
- package/src/components/pages/EmissionPage.vue +1 -1
- package/src/stores/PlayerStore.ts +42 -19
- package/src/stores/class/general/organisation.ts +10 -1
- package/src/stores/class/securisation/privateOrganisation.ts +8 -2
package/BUILD_FIX.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Fixing `@` alias resolution when consumed by other projects
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
`octopus-sdk` currently publishes raw TypeScript source. When a consumer (e.g. frontoffice)
|
|
6
|
+
bundles the SDK, it processes source files with its own Vite config, so `@/` imports resolve
|
|
7
|
+
against the consumer's `src/` instead of the SDK's. This affects both dev and production builds.
|
|
8
|
+
|
|
9
|
+
## Solution: build the SDK as a library
|
|
10
|
+
|
|
11
|
+
The SDK should be pre-built so all `@` aliases are resolved before any consumer sees the files.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Install `vite-plugin-dts`
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install -D vite-plugin-dts
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Update `vite.config.js`
|
|
24
|
+
|
|
25
|
+
Add a `lib` build alongside the existing app config. The alias resolution in the `resolve` block
|
|
26
|
+
ensures `@` is rewritten to relative paths in the output.
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
import dts from 'vite-plugin-dts';
|
|
30
|
+
|
|
31
|
+
// In the build config:
|
|
32
|
+
build: {
|
|
33
|
+
lib: {
|
|
34
|
+
entry: path.resolve(__dirname, 'index.ts'),
|
|
35
|
+
formats: ['es'],
|
|
36
|
+
fileName: 'index',
|
|
37
|
+
},
|
|
38
|
+
outDir: 'dist',
|
|
39
|
+
rollupOptions: {
|
|
40
|
+
// Mark all dependencies as external so they are not bundled
|
|
41
|
+
external: (id) => !id.startsWith('.') && !path.isAbsolute(id),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
plugins: [
|
|
45
|
+
vue(),
|
|
46
|
+
dts({ rollupTypes: true }),
|
|
47
|
+
],
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Run `npm run build` to produce `dist/index.js` and `dist/index.d.ts`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 3. Update `package.json`
|
|
55
|
+
|
|
56
|
+
Point `exports` to the built output instead of raw source:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
"exports": {
|
|
60
|
+
".": {
|
|
61
|
+
"types": "./dist/index.d.ts",
|
|
62
|
+
"default": "./dist/index.js"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"files": ["dist"]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 4. Development workflow
|
|
71
|
+
|
|
72
|
+
With a built package, `npm link` / `yalc link` alone is no longer enough — consumers need the
|
|
73
|
+
built output, not the source.
|
|
74
|
+
|
|
75
|
+
**Option A — watch build (recommended for active SDK development):**
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
# Terminal 1 — SDK
|
|
79
|
+
npm run build -- --watch
|
|
80
|
+
|
|
81
|
+
# Terminal 2 — frontoffice
|
|
82
|
+
npm run dev
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
frontoffice picks up changes via the symlink each time the SDK rebuild completes.
|
|
86
|
+
HMR in frontoffice will trigger on the rebuilt file, not on source edits directly.
|
|
87
|
+
|
|
88
|
+
**Option B — yalc push on change:**
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
# In octopus-sdk, after each change:
|
|
92
|
+
npm run build && yalc push
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
frontoffice receives the new build automatically if `yalc` is configured with `--watch`.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## What to revert in frontoffice
|
|
100
|
+
|
|
101
|
+
Once the SDK is built, remove from frontoffice's `vite.config.js`:
|
|
102
|
+
|
|
103
|
+
- `optimizeDeps.exclude: ['@saooti/octopus-sdk']` — no longer needed
|
|
104
|
+
- `server.watch.ignored: ['!**/node_modules/@saooti/octopus-sdk/**']` — no longer needed
|
|
105
|
+
- `server.fs.allow: ['../../../octopus-sdk']` — no longer needed (for npm link setups)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 41.10.7 (28/05/2026)
|
|
4
|
+
|
|
5
|
+
**Fixes**
|
|
6
|
+
|
|
7
|
+
- **14534** - Correction affichage boutons de plateformes
|
|
8
|
+
|
|
9
|
+
**Misc**
|
|
10
|
+
|
|
11
|
+
- Mise à jour dépendances
|
|
12
|
+
|
|
13
|
+
## 41.10.6 (27/05/2026)
|
|
14
|
+
|
|
15
|
+
**Fixes**
|
|
16
|
+
|
|
17
|
+
- **144228** - Correction lecture épisodes non publiés sur orga sécurisée
|
|
18
|
+
|
|
3
19
|
## 41.10.5 (26/05/2026)
|
|
4
20
|
|
|
5
21
|
**Features**
|
package/package.json
CHANGED
|
@@ -12,9 +12,12 @@ import fetchHelper from "../../../helper/fetchHelper";
|
|
|
12
12
|
import dayjs from "dayjs";
|
|
13
13
|
import { FetchParam } from "@/stores/class/general/fetchParam";
|
|
14
14
|
import { podcastApi } from "../../../api/podcastApi";
|
|
15
|
+
import { Organisation } from "../../../stores/class/general/organisation";
|
|
16
|
+
import { organisationApi } from "../../../api/organisationApi";
|
|
17
|
+
import { OrganisationPrivacy } from "../../../stores/class/securisation/privateOrganisation";
|
|
15
18
|
|
|
16
19
|
export const usePlayerLogic = (forceHide: Ref<boolean, boolean>) => {
|
|
17
|
-
const hlsReady= ref(false);
|
|
20
|
+
const hlsReady = ref(false);
|
|
18
21
|
|
|
19
22
|
const { listenTime, onPlay, setDownloadId, onTimeUpdateProgress, playLive, endingLive, playRadio} = usePlayerLive(hlsReady);
|
|
20
23
|
const { contentEndedAdsLoader } = usePlayerStitching();
|
|
@@ -35,6 +38,10 @@ export const usePlayerLogic = (forceHide: Ref<boolean, boolean>) => {
|
|
|
35
38
|
|
|
36
39
|
watch(()=>getAudioUrl(), async () => {
|
|
37
40
|
playerError.value = false;
|
|
41
|
+
|
|
42
|
+
// In some cases, the audio does not go through normal download endpoint
|
|
43
|
+
// Mostly when the podcast is not available to users
|
|
44
|
+
let download = true;
|
|
38
45
|
if (
|
|
39
46
|
playerStore.playerMedia ||
|
|
40
47
|
!playerStore.playerPodcast ||
|
|
@@ -42,12 +49,32 @@ export const usePlayerLogic = (forceHide: Ref<boolean, boolean>) => {
|
|
|
42
49
|
!playerStore.playerPodcast.availability.visibility ||
|
|
43
50
|
listenError.value
|
|
44
51
|
) {
|
|
52
|
+
download = false;
|
|
53
|
+
|
|
54
|
+
// Not yet available podcasts in secured organisations go through
|
|
55
|
+
// download if possible (see #14228)
|
|
56
|
+
const podcast = playerStore.playerPodcast;
|
|
57
|
+
if (podcast && !podcast.availability.visibility) {
|
|
58
|
+
let organisation: Organisation|null = null;
|
|
59
|
+
if (podcast.organisation) {
|
|
60
|
+
organisation = podcast.organisation;
|
|
61
|
+
} else if ('organisationId' in podcast) {
|
|
62
|
+
// Handle case of missing organisation (for example for SimplifiedPodcast)
|
|
63
|
+
organisation = await organisationApi.get(podcast.organisationId as string);
|
|
64
|
+
}
|
|
65
|
+
if (organisation.privacy === OrganisationPrivacy.SECURED) {
|
|
66
|
+
download = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (download) {
|
|
72
|
+
const response = await podcastApi.downloadRegister(playerStore.playerPodcast.podcastId, getAudioUrlParameters());
|
|
73
|
+
setDownloadId(response.downloadId.toString());
|
|
74
|
+
audioUrlToPlay.value = response.location;
|
|
75
|
+
} else {
|
|
45
76
|
audioUrlToPlay.value = getAudioUrl();
|
|
46
|
-
return;
|
|
47
77
|
}
|
|
48
|
-
const response = await podcastApi.downloadRegister(playerStore.playerPodcast.podcastId, getAudioUrlParameters());
|
|
49
|
-
setDownloadId(response.downloadId.toString());
|
|
50
|
-
audioUrlToPlay.value = response.location;
|
|
51
78
|
});
|
|
52
79
|
|
|
53
80
|
watch(()=>playerStore.playerPodcast, async () => {
|
|
@@ -1,80 +1,80 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
>
|
|
7
|
-
<div ref="subscribeButtonsContainer">
|
|
8
|
-
<a
|
|
9
|
-
v-for="(sub, index) in subscriptionsDisplay"
|
|
10
|
-
:id="'subLink' + sub.name"
|
|
11
|
-
:key="sub.name"
|
|
12
|
-
rel="noreferrer noopener"
|
|
13
|
-
target="_blank"
|
|
14
|
-
:class="{
|
|
15
|
-
first: 0 === index,
|
|
16
|
-
last: subscriptionsDisplay.length - 1 === index,
|
|
17
|
-
mono,
|
|
18
|
-
small
|
|
19
|
-
}"
|
|
20
|
-
class="btn share-btn"
|
|
21
|
-
:href="sub.url"
|
|
22
|
-
:title="t('New window', {text: sub.title})"
|
|
23
|
-
>
|
|
24
|
-
<component
|
|
25
|
-
:is="sub.icon"
|
|
26
|
-
:fill-color="fillColor(sub)"
|
|
27
|
-
:size="iconSize"
|
|
28
|
-
non-decorative
|
|
29
|
-
/>
|
|
30
|
-
</a>
|
|
31
|
-
</div>
|
|
32
|
-
<a
|
|
33
|
-
v-if="!noRss"
|
|
34
|
-
id="rss-suscribe-button"
|
|
35
|
-
rel="noreferrer noopener"
|
|
36
|
-
target="_blank"
|
|
37
|
-
class="btn share-btn"
|
|
38
|
-
:class="{ mono, small }"
|
|
39
|
-
:href="rssUrl"
|
|
40
|
-
:title="t('New window', {text: t('Rss feed')})"
|
|
41
|
-
>
|
|
42
|
-
<RssIcon :fill-color="fillColor()" :size="iconSize" />
|
|
43
|
-
</a>
|
|
44
|
-
|
|
45
|
-
<button
|
|
46
|
-
v-if="limit === undefined"
|
|
47
|
-
v-show="hiddenLinks.length"
|
|
48
|
-
id="subscribe-buttons-dropdown"
|
|
49
|
-
class="btn share-btn mx-2"
|
|
50
|
-
:title="t('See more')"
|
|
2
|
+
<div
|
|
3
|
+
v-if="subscriptionsDisplay.length || rssUrl"
|
|
4
|
+
class="subscribe-buttons-container"
|
|
5
|
+
:class="{ 'justify-center': justifyCenter }"
|
|
51
6
|
>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
7
|
+
<div ref="subscribeButtonsContainer">
|
|
8
|
+
<a
|
|
9
|
+
v-for="(sub, index) in shownLinks"
|
|
10
|
+
:id="'subLink' + sub.name"
|
|
11
|
+
:key="sub.name"
|
|
12
|
+
rel="noreferrer noopener"
|
|
13
|
+
target="_blank"
|
|
14
|
+
:class="{
|
|
15
|
+
first: 0 === index,
|
|
16
|
+
last: subscriptionsDisplay.length - 1 === index,
|
|
17
|
+
mono,
|
|
18
|
+
small
|
|
19
|
+
}"
|
|
20
|
+
class="btn share-btn"
|
|
21
|
+
:href="sub.url"
|
|
22
|
+
:title="t('New window', {text: sub.title})"
|
|
23
|
+
>
|
|
24
|
+
<component
|
|
25
|
+
:is="sub.icon"
|
|
26
|
+
:fill-color="fillColor(sub)"
|
|
27
|
+
:size="iconSize"
|
|
28
|
+
non-decorative
|
|
29
|
+
/>
|
|
30
|
+
</a>
|
|
31
|
+
</div>
|
|
32
|
+
<a
|
|
33
|
+
v-if="!noRss"
|
|
34
|
+
id="rss-suscribe-button"
|
|
35
|
+
rel="noreferrer noopener"
|
|
36
|
+
target="_blank"
|
|
37
|
+
class="btn share-btn"
|
|
38
|
+
:class="{ mono, small }"
|
|
39
|
+
:href="rssUrl"
|
|
40
|
+
:title="t('New window', {text: t('Rss feed')})"
|
|
41
|
+
>
|
|
42
|
+
<RssIcon :fill-color="fillColor()" :size="iconSize" />
|
|
43
|
+
</a>
|
|
44
|
+
|
|
45
|
+
<button
|
|
46
|
+
v-if="limit === undefined"
|
|
47
|
+
v-show="hiddenLinks.length"
|
|
48
|
+
id="subscribe-buttons-dropdown"
|
|
49
|
+
class="btn share-btn mx-2"
|
|
50
|
+
:title="t('See more')"
|
|
51
|
+
>
|
|
52
|
+
<PlusIcon />
|
|
53
|
+
</button>
|
|
54
|
+
<ClassicPopover
|
|
55
|
+
target="subscribe-buttons-dropdown"
|
|
56
|
+
popover-class="popover-z-index"
|
|
57
|
+
:only-click="true"
|
|
58
|
+
:left-pos="true"
|
|
59
|
+
>
|
|
60
|
+
<a
|
|
61
|
+
v-for="link in hiddenLinks"
|
|
62
|
+
:key="link.name"
|
|
63
|
+
rel="noreferrer noopener"
|
|
64
|
+
target="_blank"
|
|
65
|
+
class="octopus-dropdown-item justify-content-start d-flex align-items-center realLink"
|
|
66
|
+
:href="link.url"
|
|
67
|
+
:title="t('New window', {text: link.title})"
|
|
68
|
+
>
|
|
69
|
+
<component
|
|
70
|
+
:is="link.icon"
|
|
71
|
+
:fill-color="fillColor(link)"
|
|
72
|
+
class="me-1"
|
|
73
|
+
/>
|
|
74
|
+
{{ link.title }}
|
|
75
|
+
</a>
|
|
76
|
+
</ClassicPopover>
|
|
77
|
+
</div>
|
|
78
78
|
</template>
|
|
79
79
|
|
|
80
80
|
<script setup lang="ts">
|
|
@@ -83,173 +83,130 @@ import RssIcon from "vue-material-design-icons/Rss.vue";
|
|
|
83
83
|
import { useApiStore } from "../../../stores/ApiStore";
|
|
84
84
|
import ClassicPopover from "../../misc/ClassicPopover.vue";
|
|
85
85
|
import { Emission } from "@/stores/class/general/emission";
|
|
86
|
-
import { type Component, computed, onMounted
|
|
86
|
+
import { type Component, computed, onMounted } from "vue";
|
|
87
87
|
import { useI18n } from "vue-i18n";
|
|
88
|
-
import { Playlist } from "
|
|
88
|
+
import { Playlist } from "../../../stores/class/general/playlist";
|
|
89
89
|
import { useSharePlatforms } from "../../composable/share/useSharePlatforms";
|
|
90
|
+
import { useResizePhone } from "../../composable/useResizePhone";
|
|
90
91
|
|
|
91
92
|
type Link = {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
name: string;
|
|
94
|
+
icon: Component;
|
|
95
|
+
title: string;
|
|
96
|
+
color?: string;
|
|
97
|
+
url: string | undefined;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
//Props
|
|
100
101
|
const props = withDefaults(defineProps<{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
content: Emission|Playlist;
|
|
103
|
+
windowWidth?: number;
|
|
104
|
+
justifyCenter?: boolean;
|
|
105
|
+
/** Display the icons with just the octopus primary color */
|
|
106
|
+
mono?: boolean;
|
|
107
|
+
/** If set, limit the number of icons (will not display plus button) */
|
|
108
|
+
limit?: number;
|
|
109
|
+
/** Disable the RSS icon */
|
|
110
|
+
noRss?: boolean;
|
|
111
|
+
/** Smaller icons */
|
|
112
|
+
small?: boolean;
|
|
112
113
|
}>(), {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
windowWidth: 0,
|
|
115
|
+
justifyCenter: true,
|
|
116
|
+
mono: false,
|
|
117
|
+
limit: undefined,
|
|
118
|
+
noRss: false,
|
|
119
|
+
small: false
|
|
119
120
|
});
|
|
120
121
|
|
|
121
|
-
//Data
|
|
122
|
-
const lastWindowWidth = ref(420);
|
|
123
|
-
const hiddenLinks: Ref<Array<Link>> = ref([]);
|
|
124
|
-
const subscribeButtonsContainerRef = useTemplateRef('subscribeButtonsContainer');
|
|
125
|
-
|
|
126
|
-
|
|
127
122
|
//Composables
|
|
128
123
|
const { t } = useI18n();
|
|
129
124
|
const apiStore = useApiStore();
|
|
130
125
|
const { getPlatformsWithLinks, initPlatforms } = useSharePlatforms();
|
|
126
|
+
const { isPhone } = useResizePhone();
|
|
131
127
|
|
|
132
128
|
//Computed
|
|
129
|
+
const maxElements = computed((): number => {
|
|
130
|
+
let number = 5;
|
|
131
|
+
if (isPhone.value) {
|
|
132
|
+
number = 3;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (props.noRss) {
|
|
136
|
+
number += 1;
|
|
137
|
+
}
|
|
138
|
+
if (subscriptionsDisplay.value.length <= number + 1) {
|
|
139
|
+
number = subscriptionsDisplay.value.length;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (props.limit !== undefined) {
|
|
143
|
+
return Math.min(number, props.limit);
|
|
144
|
+
} else {
|
|
145
|
+
return number;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
133
149
|
const subscriptionsDisplay = computed(() => {
|
|
134
|
-
|
|
150
|
+
return getPlatformsWithLinks(props.content.annotations);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const shownLinks = computed((): Array<Link> => {
|
|
154
|
+
return subscriptionsDisplay.value.slice(0, maxElements.value);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const hiddenLinks = computed((): Array<Link> => {
|
|
158
|
+
return subscriptionsDisplay.value.slice(maxElements.value);
|
|
135
159
|
});
|
|
136
160
|
|
|
137
161
|
const rssUrl = computed(() => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
162
|
+
const api = apiStore.apiUrl + "rss/";
|
|
163
|
+
if ((props.content as Emission).emissionId) {
|
|
164
|
+
return api + "emission/" + (props.content as Emission).emissionId + ".rss";
|
|
165
|
+
}
|
|
166
|
+
if ((props.content as Playlist).playlistId) {
|
|
167
|
+
return api + "playlist/" + (props.content as Playlist).playlistId + ".rss";
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
146
170
|
});
|
|
147
171
|
|
|
148
172
|
const iconSize = computed((): number => {
|
|
149
|
-
|
|
173
|
+
return props.small ? 20 : 24;
|
|
150
174
|
});
|
|
151
175
|
|
|
152
|
-
//Watch
|
|
153
|
-
watch(()=>props.windowWidth, () =>resizeWindow());
|
|
154
|
-
|
|
155
176
|
onMounted(() => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
initPlatforms(orga.id);
|
|
177
|
+
const orga = 'orga' in props.content ? props.content.orga : props.content.organisation;
|
|
178
|
+
initPlatforms(orga.id);
|
|
159
179
|
});
|
|
160
180
|
|
|
161
|
-
//Methods
|
|
162
|
-
function showAllElements() {
|
|
163
|
-
subscriptionsDisplay.value.forEach((element: Link) => {
|
|
164
|
-
const el = subscribeButtonsContainerRef?.value?.querySelector('#subLink' + element.name);
|
|
165
|
-
if (!el) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (el.classList.contains("hid")) {
|
|
169
|
-
el.classList.remove("hid");
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
function hideOnlyNecessaryElements() {
|
|
174
|
-
let parentWidth = 0;
|
|
175
|
-
subscriptionsDisplay.value.forEach((element: Link, index: number) => {
|
|
176
|
-
const el = subscribeButtonsContainerRef?.value?.querySelector('#subLink' + element.name);
|
|
177
|
-
if (!el) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
if (!parentWidth) {
|
|
181
|
-
const buttonMoreWidth = el.clientWidth + 20;
|
|
182
|
-
parentWidth =
|
|
183
|
-
(el.parentElement?.clientWidth ?? 0) +
|
|
184
|
-
(el.parentElement?.offsetLeft ?? 0) -
|
|
185
|
-
buttonMoreWidth;
|
|
186
|
-
}
|
|
187
|
-
if (el.offsetLeft + el.clientWidth + 20 < parentWidth && (props.limit === undefined || index < props.limit)) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
hiddenLinks.value.push(element);
|
|
191
|
-
if (!el.classList.contains("hid")) {
|
|
192
|
-
el.className += " hid";
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
function resizeWindow() {
|
|
197
|
-
if (props.windowWidth > 420 && lastWindowWidth.value > 420) {
|
|
198
|
-
lastWindowWidth.value = props.windowWidth;
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
const subscribeList = subscribeButtonsContainerRef?.value as HTMLElement;
|
|
202
|
-
if (
|
|
203
|
-
null === subscribeList ||
|
|
204
|
-
!subscribeList ||
|
|
205
|
-
"none" === subscribeList?.parentElement?.style.display
|
|
206
|
-
) {
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
lastWindowWidth.value = props.windowWidth;
|
|
210
|
-
subscribeList.style.justifyContent = "flex-start";
|
|
211
|
-
subscribeList.style.flexGrow = "1";
|
|
212
|
-
hiddenLinks.value.length = 0;
|
|
213
|
-
showAllElements();
|
|
214
|
-
hideOnlyNecessaryElements();
|
|
215
|
-
if (!hiddenLinks.value.length && props.justifyCenter) {
|
|
216
|
-
subscribeList.style.justifyContent = "center";
|
|
217
|
-
}
|
|
218
|
-
subscribeList.style.flexGrow = "0";
|
|
219
|
-
}
|
|
220
|
-
|
|
221
181
|
function fillColor(link?: Link): string|undefined {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
182
|
+
if (props.mono === true) {
|
|
183
|
+
return 'white';
|
|
184
|
+
} else {
|
|
185
|
+
return link?.color;
|
|
186
|
+
}
|
|
227
187
|
}
|
|
228
188
|
</script>
|
|
229
189
|
|
|
230
190
|
<style scoped lang="scss">
|
|
231
|
-
.
|
|
232
|
-
.subscribe-buttons-container {
|
|
233
|
-
max-width: 420px;
|
|
191
|
+
.subscribe-buttons-container {
|
|
234
192
|
align-self: center;
|
|
235
193
|
display: inline-flex;
|
|
236
194
|
width: 100%;
|
|
237
195
|
|
|
238
196
|
&.justify-center {
|
|
239
|
-
|
|
197
|
+
justify-content: center;
|
|
240
198
|
}
|
|
241
199
|
|
|
242
200
|
& > div {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
201
|
+
display: inline-flex;
|
|
202
|
+
justify-content: flex-start;
|
|
203
|
+
overflow: hidden;
|
|
204
|
+
width: fit-content;
|
|
247
205
|
}
|
|
248
206
|
|
|
249
207
|
@media (width <= 960px) {
|
|
250
|
-
|
|
208
|
+
margin-top: 0.8rem;
|
|
251
209
|
}
|
|
252
|
-
}
|
|
253
210
|
}
|
|
254
211
|
|
|
255
212
|
.share-btn {
|
|
@@ -11,6 +11,8 @@ import { Chaptering, ChapteringPercent } from "./class/chaptering/chaptering";
|
|
|
11
11
|
import classicApi from "../api/classicApi";
|
|
12
12
|
|
|
13
13
|
import { state as sdkParams } from "./ParamSdkStore";
|
|
14
|
+
import { Canal } from "./class/radio/canal";
|
|
15
|
+
import { Conference } from "./class/conference/conference";
|
|
14
16
|
|
|
15
17
|
interface Transcript {
|
|
16
18
|
actual: number;
|
|
@@ -92,10 +94,18 @@ export const usePlayerStore = defineStore("PlayerStore", {
|
|
|
92
94
|
return chapteringPercent;
|
|
93
95
|
},
|
|
94
96
|
playerHeight() {
|
|
95
|
-
if ("STOPPED" === this.playerStatus)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (
|
|
97
|
+
if ("STOPPED" === this.playerStatus) {
|
|
98
|
+
return '0px';
|
|
99
|
+
}
|
|
100
|
+
if (this.playerVideo) {
|
|
101
|
+
return "0px" /* "281px" */;
|
|
102
|
+
}
|
|
103
|
+
if (this.playerLargeVersion) {
|
|
104
|
+
return "27rem";
|
|
105
|
+
}
|
|
106
|
+
if (window.innerWidth > 450) {
|
|
107
|
+
return "6rem";
|
|
108
|
+
}
|
|
99
109
|
return "3.5rem";
|
|
100
110
|
},
|
|
101
111
|
|
|
@@ -182,19 +192,27 @@ export const usePlayerStore = defineStore("PlayerStore", {
|
|
|
182
192
|
* @param param The data
|
|
183
193
|
* @param isVideo If true, enable video mode
|
|
184
194
|
*/
|
|
185
|
-
async playerPlay(param?:
|
|
195
|
+
async playerPlay(param?: Podcast|Media|Canal|Conference, isVideo = false) {
|
|
186
196
|
if (!param) {
|
|
187
197
|
this.stop();
|
|
188
198
|
return;
|
|
189
199
|
}
|
|
190
200
|
if (
|
|
191
|
-
(
|
|
201
|
+
(
|
|
202
|
+
this.playerPodcast &&
|
|
203
|
+
'podcastId' in param &&
|
|
192
204
|
this.playerPodcast.podcastId === param.podcastId &&
|
|
193
|
-
isVideo === this.playerVideo
|
|
194
|
-
|
|
195
|
-
|
|
205
|
+
isVideo === this.playerVideo
|
|
206
|
+
) || (
|
|
207
|
+
this.playerMedia &&
|
|
208
|
+
'mediaId' in param &&
|
|
209
|
+
this.playerMedia.mediaId === param.mediaId
|
|
210
|
+
) || (
|
|
211
|
+
this.playerLive &&
|
|
212
|
+
'conferenceId' in param &&
|
|
196
213
|
this.playerLive.conferenceId === param.conferenceId &&
|
|
197
|
-
isVideo === this.playerVideo
|
|
214
|
+
isVideo === this.playerVideo
|
|
215
|
+
)
|
|
198
216
|
) {
|
|
199
217
|
//Do nothing
|
|
200
218
|
return;
|
|
@@ -215,6 +233,7 @@ export const usePlayerStore = defineStore("PlayerStore", {
|
|
|
215
233
|
this.playerChaptering = undefined;
|
|
216
234
|
|
|
217
235
|
if (
|
|
236
|
+
'conferenceId' in param &&
|
|
218
237
|
param.conferenceId &&
|
|
219
238
|
(!param.podcastId || param.processingStatus !== "READY")
|
|
220
239
|
) {
|
|
@@ -223,24 +242,28 @@ export const usePlayerStore = defineStore("PlayerStore", {
|
|
|
223
242
|
this.playerCurrentChange = null;
|
|
224
243
|
return;
|
|
225
244
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
245
|
+
|
|
246
|
+
if ('podcastId' in param && param.podcastId) {
|
|
247
|
+
const podcast = param as Podcast;
|
|
248
|
+
this.playerPodcast = podcast;
|
|
249
|
+
this.playerCurrentChange = podcast.podcastId;
|
|
250
|
+
if (podcast.annotations?.chaptering) {
|
|
230
251
|
this.playerChaptering = await classicApi.fetchData<Chaptering>({
|
|
231
|
-
api:4,
|
|
232
|
-
path:
|
|
233
|
-
isNotAuth:true
|
|
252
|
+
api: 4,
|
|
253
|
+
path: podcast.annotations.chaptering as string,
|
|
254
|
+
isNotAuth: true
|
|
234
255
|
});
|
|
235
256
|
}
|
|
236
257
|
return;
|
|
237
258
|
}
|
|
238
|
-
|
|
259
|
+
|
|
260
|
+
if ('mediaId' in param && param.mediaId) {
|
|
239
261
|
this.playerMedia = param;
|
|
240
262
|
this.playerCurrentChange = null;
|
|
241
263
|
return;
|
|
242
264
|
}
|
|
243
|
-
|
|
265
|
+
|
|
266
|
+
if ('canalId' in param && param.canalId) {
|
|
244
267
|
this.playerRadio = { ...param, isInit: false };
|
|
245
268
|
this.playerCurrentChange = -param.canalId;
|
|
246
269
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Person } from "../user/person";
|
|
2
2
|
|
|
3
|
+
export enum MonetisationOptions {
|
|
4
|
+
YES = 'YES',
|
|
5
|
+
NO = 'NO'
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
export type OrganisationAttributes = {
|
|
4
9
|
//[key: string]: string | number | boolean | undefined;
|
|
5
10
|
automation?: string;
|
|
@@ -13,6 +18,10 @@ export type OrganisationAttributes = {
|
|
|
13
18
|
'translation-config'?: string;
|
|
14
19
|
/** Language of the RSS */
|
|
15
20
|
'rss-language'?: string;
|
|
21
|
+
/** Monetisation of the organisation */
|
|
22
|
+
MONETISABLE?: MonetisationOptions;
|
|
23
|
+
/** Privacy parameters (JSON) */
|
|
24
|
+
PRIVATE?: string;
|
|
16
25
|
};
|
|
17
26
|
|
|
18
27
|
export interface Organisation {
|
|
@@ -26,7 +35,7 @@ export interface Organisation {
|
|
|
26
35
|
longitude: number;
|
|
27
36
|
latitude: number;
|
|
28
37
|
};
|
|
29
|
-
monetisable?:
|
|
38
|
+
monetisable?: MonetisationOptions;
|
|
30
39
|
name: string;
|
|
31
40
|
notSeenOnKeycloak?: number;
|
|
32
41
|
score?: number;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
export enum OrganisationPrivacy {
|
|
2
|
+
SECURED = 'SECURED',
|
|
3
|
+
PRIVATE = 'PRIVATE',
|
|
4
|
+
PUBLIC = 'PUBLIC'
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
export interface PrivateOrganisation {
|
|
2
|
-
privacy:
|
|
8
|
+
privacy: OrganisationPrivacy;
|
|
3
9
|
accountCreation: string; // ENABLED DISABLED
|
|
4
10
|
referrers: Array<string>;
|
|
5
11
|
cidrs: Array<string>;
|
|
@@ -8,7 +14,7 @@ export interface PrivateOrganisation {
|
|
|
8
14
|
|
|
9
15
|
export function emptyPrivateOrganisation(): PrivateOrganisation {
|
|
10
16
|
return {
|
|
11
|
-
privacy:
|
|
17
|
+
privacy: OrganisationPrivacy.PUBLIC,
|
|
12
18
|
accountCreation: "DISABLED",
|
|
13
19
|
referrers: [],
|
|
14
20
|
cidrs: [],
|