@saooti/octopus-sdk 41.10.6 → 41.10.8
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 41.10.8 (29/05/2026)
|
|
4
|
+
|
|
5
|
+
**Fixes**
|
|
6
|
+
|
|
7
|
+
- **14524** - Accès aux aggrégateurs sans authentification
|
|
8
|
+
|
|
9
|
+
## 41.10.7 (28/05/2026)
|
|
10
|
+
|
|
11
|
+
**Fixes**
|
|
12
|
+
|
|
13
|
+
- **14534** - Correction affichage boutons de plateformes
|
|
14
|
+
|
|
15
|
+
**Misc**
|
|
16
|
+
|
|
17
|
+
- Mise à jour dépendances
|
|
18
|
+
|
|
3
19
|
## 41.10.6 (27/05/2026)
|
|
4
20
|
|
|
5
21
|
**Fixes**
|
package/package.json
CHANGED
|
@@ -47,7 +47,22 @@ async function getAll(organisationId?: string): Promise<Array<Aggregator>> {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Return the list of all user-defined aggregators, without filter data.
|
|
52
|
+
* This doesn't require to be authenticated.
|
|
53
|
+
* @param organisationId If defined, the aggregators will be filtered for this
|
|
54
|
+
* organisation
|
|
55
|
+
*/
|
|
56
|
+
async function getAllNoAuth(organisationId?: string): Promise<Array<PredefinedAggregator>> {
|
|
57
|
+
return classicApi.fetchData<Array<Aggregator>>({
|
|
58
|
+
api: ModuleApi.DEFAULT,
|
|
59
|
+
path: 'rss/aggregator/noauth/list',
|
|
60
|
+
parameters: organisationId ? { organisationId } : undefined
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
export const aggregatorsApi = {
|
|
51
65
|
getPredefined,
|
|
52
|
-
getAll
|
|
66
|
+
getAll,
|
|
67
|
+
getAllNoAuth
|
|
53
68
|
};
|
|
@@ -13,7 +13,7 @@ import PodbeanIcon from "../../icons/PodbeanIcon.vue";
|
|
|
13
13
|
import YoutubeIcon from "vue-material-design-icons/Youtube.vue";
|
|
14
14
|
import SpotifyIcon from "vue-material-design-icons/Spotify.vue";
|
|
15
15
|
import { Annotations } from "@/stores/class/general";
|
|
16
|
-
import { h, markRaw, ref, type Component
|
|
16
|
+
import { h, markRaw, ref, type Component } from "vue";
|
|
17
17
|
import { aggregatorsApi } from "../../../api/aggregatorsApi";
|
|
18
18
|
import { useNotificationStore } from "../../../stores/NotificationStore";
|
|
19
19
|
import ClassicAvatar from "../../misc/ClassicAvatar.vue";
|
|
@@ -136,7 +136,7 @@ export const useSharePlatforms = () => {
|
|
|
136
136
|
platforms.value = [...PREDEFINED_PLATFORMS];
|
|
137
137
|
|
|
138
138
|
try {
|
|
139
|
-
const customPlatforms = await aggregatorsApi.
|
|
139
|
+
const customPlatforms = await aggregatorsApi.getAllNoAuth(organisationId);
|
|
140
140
|
customPlatforms.forEach(platform => {
|
|
141
141
|
platforms.value.push({
|
|
142
142
|
name: platform.name,
|
|
@@ -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 {
|