@saooti/octopus-sdk 40.0.3 → 40.1.0
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/index.ts +31 -31
- package/package.json +1 -1
- package/plateform.conf +1 -1
- package/src/App.vue +9 -3
- package/src/api/classicApi.ts +1 -1
- package/src/components/composable/player/usePlayerDisplayTime.ts +33 -0
- package/src/components/composable/player/usePlayerLive.ts +150 -0
- package/src/components/composable/player/usePlayerLogic.ts +265 -0
- package/src/components/composable/player/usePlayerLogicProgress.ts +135 -0
- package/src/components/composable/player/usePlayerStitching.ts +213 -0
- package/src/components/composable/player/usePlayerTranscript.ts +120 -0
- package/src/components/composable/player/usePlayerVast.ts +207 -0
- package/src/components/composable/podcasts/useCountdown.ts +53 -0
- package/src/components/composable/podcasts/usePodcastView.ts +85 -0
- package/src/components/composable/radio/usefetchRadioData.ts +75 -0
- package/src/components/composable/route/useAdvancedParamInit.ts +165 -0
- package/src/components/composable/route/useRouteUpdateParams.ts +48 -0
- package/src/components/composable/route/useRubriquesFilterComputed.ts +24 -0
- package/src/components/composable/route/useRubriquesFilterParam.ts +32 -0
- package/src/components/composable/route/useSeoTitleUrl.ts +30 -0
- package/src/components/composable/route/useSimplePageParam.ts +50 -0
- package/src/components/composable/useErrorHandler.ts +25 -0
- package/src/components/composable/useImageProxy.ts +28 -0
- package/src/components/composable/useInit.ts +38 -0
- package/src/components/composable/useMetaTitle.ts +19 -0
- package/src/components/composable/useMetaTitleWatch.ts +14 -0
- package/src/components/composable/useOrgaComputed.ts +23 -0
- package/src/components/composable/useOrganisationFilter.ts +65 -0
- package/src/components/composable/useResizePhone.ts +27 -0
- package/src/components/composable/useSelenium.ts +10 -0
- package/src/components/composable/useTagOf.ts +21 -0
- package/src/components/display/accessibility/AccessibilityModal.vue +136 -0
- package/src/components/display/aggregator/RssSection.vue +1 -4
- package/src/components/display/categories/CategoryChooser.vue +1 -1
- package/src/components/display/categories/CategoryFilter.vue +7 -3
- package/src/components/display/categories/CategoryList.vue +5 -2
- package/src/components/display/comments/CommentInput.vue +0 -3
- package/src/components/display/comments/CommentList.vue +6 -2
- package/src/components/display/comments/CommentPlayer.vue +5 -2
- package/src/components/display/comments/CommentSection.vue +0 -2
- package/src/components/display/comments/item/CommentBasicView.vue +4 -4
- package/src/components/display/comments/item/CommentItem.vue +0 -4
- package/src/components/display/comments/item/CommentMoreActions.vue +6 -2
- package/src/components/display/emission/EmissionInlineList.vue +6 -6
- package/src/components/display/emission/EmissionItem.vue +13 -6
- package/src/components/display/emission/EmissionList.vue +5 -2
- package/src/components/display/emission/EmissionPlayerItem.vue +8 -5
- package/src/components/display/emission/EmissionPresentationItem.vue +16 -7
- package/src/components/display/emission/EmissionPresentationList.vue +10 -7
- package/src/components/display/filter/AdvancedSearch.vue +9 -6
- package/src/components/display/filter/CategorySearchFilter.vue +0 -2
- package/src/components/display/filter/ProductorSearch.vue +8 -3
- package/src/components/display/filter/RubriqueFilter.vue +6 -2
- package/src/components/display/list/ListPaginate.vue +9 -6
- package/src/components/display/list/SwiperList.vue +6 -5
- package/src/components/display/live/CountDown.vue +7 -15
- package/src/components/display/live/CountdownOctopus.vue +10 -30
- package/src/components/display/live/LiveItem.vue +0 -2
- package/src/components/display/live/LiveList.vue +9 -4
- package/src/components/display/live/RadioCurrently.vue +9 -5
- package/src/components/display/live/RadioImage.vue +6 -4
- package/src/components/display/live/RadioItem.vue +1 -2
- package/src/components/display/live/RadioList.vue +5 -3
- package/src/components/display/live/RadioPlanning.vue +10 -7
- package/src/components/display/organisation/OrganisationChooser.vue +8 -4
- package/src/components/display/participant/ParticipantInlineList.vue +5 -5
- package/src/components/display/participant/ParticipantItem.vue +13 -5
- package/src/components/display/participant/ParticipantList.vue +6 -3
- package/src/components/display/playlist/PlaylistItem.vue +12 -5
- package/src/components/display/playlist/PlaylistList.vue +6 -3
- package/src/components/display/playlist/PodcastList.vue +8 -4
- package/src/components/display/podcastmaker/PodcastmakerHeader.vue +6 -3
- package/src/components/display/podcasts/DownloadPodcastButton.vue +2 -4
- package/src/components/display/podcasts/PodcastImage.vue +6 -3
- package/src/components/display/podcasts/PodcastInlineListTemplate.vue +7 -4
- package/src/components/display/podcasts/PodcastItem.vue +1 -1
- package/src/components/display/podcasts/PodcastItemInfo.vue +6 -3
- package/src/components/display/podcasts/PodcastList.vue +6 -3
- package/src/components/display/podcasts/PodcastModuleBox.vue +22 -9
- package/src/components/display/podcasts/PodcastPlayBar.vue +1 -3
- package/src/components/display/podcasts/PodcastPlayButton.vue +1 -3
- package/src/components/display/podcasts/PodcastRawTranscript.vue +79 -10
- package/src/components/display/podcasts/PodcastRubriqueList.vue +4 -3
- package/src/components/display/podcasts/TagList.vue +5 -2
- package/src/components/display/podcasts/VideoModuleBox.vue +6 -3
- package/src/components/display/rubriques/RubriqueChooser.vue +0 -2
- package/src/components/display/rubriques/RubriqueList.vue +7 -5
- package/src/components/display/sharing/ShareButtons.vue +4 -2
- package/src/components/display/sharing/ShareDistribution.vue +4 -2
- package/src/components/form/ClassicEmojiPicker.vue +5 -3
- package/src/components/misc/ClassicLazy.vue +2 -2
- package/src/components/misc/FooterGarSection.vue +2 -3
- package/src/components/misc/FooterSection.vue +9 -5
- package/src/components/misc/MobileMenu.vue +5 -3
- package/src/components/misc/TopBar.vue +8 -6
- package/src/components/misc/TopBarMainContent.vue +8 -4
- package/src/components/misc/modal/ClassicModalInBody.vue +2 -3
- package/src/components/misc/modal/ClipboardModal.vue +4 -3
- package/src/components/misc/modal/NewsletterModal.vue +4 -3
- package/src/components/misc/modal/ShareModalPlayer.vue +4 -2
- package/src/components/misc/player/PlayerCompact.vue +30 -41
- package/src/components/misc/player/PlayerComponent.vue +69 -84
- package/src/components/misc/player/PlayerLarge.vue +43 -58
- package/src/components/misc/player/elements/PlayerImage.vue +6 -3
- package/src/components/misc/player/elements/PlayerTitle.vue +6 -2
- package/src/components/misc/player/radio/RadioHistory.vue +2 -4
- package/src/components/misc/player/video/PlayerVideoHls.vue +6 -7
- package/src/components/pages/EmissionPage.vue +19 -7
- package/src/components/pages/EmissionsPage.vue +31 -23
- package/src/components/pages/HomePage.vue +5 -2
- package/src/components/pages/PageLogout.vue +0 -2
- package/src/components/pages/PageNotFound.vue +11 -15
- package/src/components/pages/ParticipantPage.vue +18 -7
- package/src/components/pages/ParticipantsPage.vue +16 -21
- package/src/components/pages/PlaylistPage.vue +18 -7
- package/src/components/pages/PlaylistsPage.vue +20 -29
- package/src/components/pages/PodcastPage.vue +12 -6
- package/src/components/pages/PodcastsPage.vue +46 -48
- package/src/components/pages/RadioPage.vue +9 -6
- package/src/components/pages/RubriquePage.vue +41 -52
- package/src/components/pages/VideoPage.vue +152 -166
- package/src/helper/cookiesHelper.ts +20 -0
- package/src/helper/displayHelper.ts +15 -0
- package/src/helper/downloadHelper.ts +30 -0
- package/src/helper/{fetch.ts → fetchHelper.ts} +0 -1
- package/src/helper/loadScript.ts +22 -0
- package/src/helper/radio/radioHelper.ts +15 -0
- package/src/helper/{string.ts → stringHelper.ts} +5 -0
- package/src/locale/de.ts +4 -0
- package/src/locale/en.ts +4 -0
- package/src/locale/es.ts +4 -0
- package/src/locale/fr.ts +4 -0
- package/src/locale/it.ts +4 -0
- package/src/locale/sl.ts +4 -0
- package/src/stores/AuthStore.ts +1 -2
- package/src/stores/CommentStore.ts +8 -8
- package/src/stores/PlayerStore.ts +1 -1
- package/src/style/general.scss +15 -1
- package/src/components/mixins/cookies.ts +0 -22
- package/src/components/mixins/displayMethods.ts +0 -17
- package/src/components/mixins/download.ts +0 -33
- package/src/components/mixins/fetchParameters.ts +0 -16
- package/src/components/mixins/handle403.ts +0 -22
- package/src/components/mixins/imageProxy.ts +0 -28
- package/src/components/mixins/init.ts +0 -34
- package/src/components/mixins/loadScript.ts +0 -25
- package/src/components/mixins/metaTitle.ts +0 -15
- package/src/components/mixins/metaTitleWatch.ts +0 -26
- package/src/components/mixins/orgaComputed.ts +0 -23
- package/src/components/mixins/organisationFilter.ts +0 -56
- package/src/components/mixins/player/playerDisplayTime.ts +0 -35
- package/src/components/mixins/player/playerLive.ts +0 -144
- package/src/components/mixins/player/playerLogic.ts +0 -275
- package/src/components/mixins/player/playerLogicProgress.ts +0 -135
- package/src/components/mixins/player/playerStitching.ts +0 -202
- package/src/components/mixins/player/playerTranscript.ts +0 -113
- package/src/components/mixins/player/playerVast.ts +0 -198
- package/src/components/mixins/podcast/countdown.ts +0 -45
- package/src/components/mixins/podcast/podcastView.ts +0 -63
- package/src/components/mixins/radio/fetchRadioData.ts +0 -77
- package/src/components/mixins/resizePhone.ts +0 -26
- package/src/components/mixins/routeParam/advancedParamInit.ts +0 -202
- package/src/components/mixins/routeParam/paginateParamInit.ts +0 -43
- package/src/components/mixins/routeParam/routeParams.ts +0 -33
- package/src/components/mixins/routeParam/rubriquesFilterComputed.ts +0 -22
- package/src/components/mixins/routeParam/rubriquesFilterParam.ts +0 -29
- package/src/components/mixins/selenium.ts +0 -7
- package/src/components/mixins/seoTitleUrl.ts +0 -26
- package/src/components/mixins/tagOfMixins.ts +0 -19
- package/src/helper/uuidGenerator.ts +0 -7
- /package/src/{helper → components/composable}/useEventListener.ts +0 -0
- /package/src/{components/mixins/debounce.ts → helper/debounceHelper.ts} +0 -0
- /package/src/helper/{dom.ts → domHelper.ts} +0 -0
- /package/src/helper/{duration.ts → durationHelper.ts} +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {computed, onBeforeUnmount, onMounted, Ref, ref} from 'vue';
|
|
2
|
+
export const useCountdown = (timeRemaining: number|undefined)=>{
|
|
3
|
+
const days = ref(0);
|
|
4
|
+
const hours = ref(0);
|
|
5
|
+
const minutes = ref(0);
|
|
6
|
+
const seconds = ref(0);
|
|
7
|
+
const remainingSeconds = ref(0);
|
|
8
|
+
const countdownTimer : Ref<ReturnType<typeof setTimeout> | undefined> = ref(undefined);
|
|
9
|
+
|
|
10
|
+
const countdownValues = computed(() => {
|
|
11
|
+
return {
|
|
12
|
+
days: pad(days.value),
|
|
13
|
+
hours: pad(hours.value),
|
|
14
|
+
minutes: pad(minutes.value),
|
|
15
|
+
seconds: pad(remainingSeconds.value),
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
function timer(): void {
|
|
20
|
+
days.value = Math.floor(seconds.value / 24 / 60 / 60);
|
|
21
|
+
const hoursLeft = Math.floor(seconds.value - days.value * 86400);
|
|
22
|
+
hours.value = Math.floor(hoursLeft / 3600);
|
|
23
|
+
const minutesLeft = Math.floor(hoursLeft - hours.value * 3600);
|
|
24
|
+
minutes.value = Math.floor(minutesLeft / 60);
|
|
25
|
+
remainingSeconds.value = seconds.value % 60;
|
|
26
|
+
if (0 === seconds.value) {
|
|
27
|
+
clearInterval(countdownTimer.value as unknown as number);
|
|
28
|
+
countdownTimer.value = undefined;
|
|
29
|
+
} else {
|
|
30
|
+
seconds.value-=1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function pad(n: number): string {
|
|
34
|
+
return/* n < 10 ? "0" + n : */ n.toString();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onMounted(() => {
|
|
38
|
+
if (!timeRemaining || timeRemaining <= 0) return;
|
|
39
|
+
seconds.value = timeRemaining;
|
|
40
|
+
countdownTimer.value = setInterval(() => {
|
|
41
|
+
timer();
|
|
42
|
+
}, 1000);
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
onBeforeUnmount(() => {
|
|
46
|
+
clearInterval(countdownTimer.value as unknown as number);
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
countdownValues,
|
|
51
|
+
countdownTimer
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Conference } from '@/stores/class/conference/conference';
|
|
2
|
+
import { Podcast } from '@/stores/class/general/podcast';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
import duration from "dayjs/plugin/duration";
|
|
5
|
+
dayjs.extend(duration);
|
|
6
|
+
// @ts-expect-error Bibliothèque non typée
|
|
7
|
+
import humanizeDuration from "humanize-duration";
|
|
8
|
+
import {computed, Ref} from 'vue';
|
|
9
|
+
import { useI18n } from 'vue-i18n';
|
|
10
|
+
import {useOrgaComputed} from "../useOrgaComputed"
|
|
11
|
+
export const usePodcastView = (podcast: Ref<Podcast|undefined>, podcastConference: Ref<Conference|undefined>)=>{
|
|
12
|
+
|
|
13
|
+
const i18n = useI18n();
|
|
14
|
+
|
|
15
|
+
const {isEditRights, isPodcastmaker} = useOrgaComputed();
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const editRight = computed(() => {
|
|
19
|
+
return isEditRights(podcast.value?.organisation.id);
|
|
20
|
+
});
|
|
21
|
+
const isLiveReadyToRecord = computed(() => {
|
|
22
|
+
return (
|
|
23
|
+
undefined !== podcast.value &&
|
|
24
|
+
undefined !== podcast.value.conferenceId &&
|
|
25
|
+
0 !== podcast.value.conferenceId &&
|
|
26
|
+
"READY_TO_RECORD" === podcast.value.processingStatus
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
const isCounter = computed(() => {
|
|
30
|
+
return (
|
|
31
|
+
isLiveReadyToRecord.value &&
|
|
32
|
+
undefined !== podcastConference.value &&
|
|
33
|
+
("PLANNED" === podcastConference.value.status ||
|
|
34
|
+
"PENDING" === podcastConference.value.status)
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const timeRemaining = computed(() => {
|
|
39
|
+
return !podcast.value ? 0: dayjs(podcast.value.pubDate).diff(dayjs(), "seconds");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const isPlannedInProcessor = computed(() => "PLANNED" === podcast.value?.processingStatus);
|
|
43
|
+
|
|
44
|
+
const date = computed(() => {
|
|
45
|
+
if (!podcast.value || 1970 === dayjs(podcast.value.pubDate).year()) {
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
48
|
+
if (isLiveReadyToRecord.value) {
|
|
49
|
+
return dayjs(podcast.value.pubDate).format("D MMMM YYYY - HH:mm");
|
|
50
|
+
}
|
|
51
|
+
return dayjs(podcast.value.pubDate).format("D MMMM YYYY");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const duration = computed(() => {
|
|
55
|
+
if (!podcast.value || podcast.value.duration <= 1) return "";
|
|
56
|
+
if (podcast.value.duration > 600000) {
|
|
57
|
+
return humanizeDuration(podcast.value.duration, {
|
|
58
|
+
language: i18n.locale.value,
|
|
59
|
+
largest: 1,
|
|
60
|
+
round: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return humanizeDuration(podcast.value.duration, {
|
|
64
|
+
language: i18n.locale.value,
|
|
65
|
+
largest: 2,
|
|
66
|
+
round: true,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const durationIso = computed(() => {
|
|
71
|
+
if (!podcast.value || podcast.value.duration <= 1) return "";
|
|
72
|
+
return dayjs.duration({ milliseconds: podcast.value.duration }).toISOString();
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
isLiveReadyToRecord,
|
|
76
|
+
isCounter,
|
|
77
|
+
timeRemaining,
|
|
78
|
+
isPlannedInProcessor,
|
|
79
|
+
date,
|
|
80
|
+
duration,
|
|
81
|
+
durationIso,
|
|
82
|
+
editRight,
|
|
83
|
+
isPodcastmaker
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import classicApi from "../../../api/classicApi";
|
|
2
|
+
import { MediaRadio, MetadataRadio, NextAdvertising } from '@/stores/class/general/player';
|
|
3
|
+
import { Podcast } from '@/stores/class/general/podcast';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
import radioHelper from "../../../helper/radio/radioHelper";
|
|
6
|
+
import {onBeforeUnmount, Ref, ref} from 'vue';
|
|
7
|
+
export const useFetchRadio = ()=>{
|
|
8
|
+
|
|
9
|
+
const radioInterval : Ref<ReturnType<typeof setTimeout> | undefined> = ref(undefined);
|
|
10
|
+
|
|
11
|
+
async function fetchRadioMetadata(
|
|
12
|
+
canalId: number,
|
|
13
|
+
previousTitle: string,
|
|
14
|
+
callbackMetadata: (
|
|
15
|
+
metadata: MediaRadio,
|
|
16
|
+
podcast: Podcast | undefined,
|
|
17
|
+
history: Array<MediaRadio>
|
|
18
|
+
) => void,
|
|
19
|
+
callbackAdvertising?: (
|
|
20
|
+
nextAdvertising: NextAdvertising
|
|
21
|
+
) => void,
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const metadata = await classicApi.fetchData<MetadataRadio>({
|
|
24
|
+
api: 14,
|
|
25
|
+
path: "player/playing/" + canalId,
|
|
26
|
+
});
|
|
27
|
+
if(callbackAdvertising){
|
|
28
|
+
callbackAdvertising(metadata.nextAdvertising);
|
|
29
|
+
}
|
|
30
|
+
const arrayMetadata = metadata.previously;
|
|
31
|
+
arrayMetadata.unshift(metadata.currently);
|
|
32
|
+
for (let index = 0, len = arrayMetadata.length; index < len; index++) {
|
|
33
|
+
if (
|
|
34
|
+
dayjs().valueOf() - 18000 >
|
|
35
|
+
dayjs(arrayMetadata[index].startDate).valueOf()
|
|
36
|
+
) {
|
|
37
|
+
await useCallbackIfNewMetadata(previousTitle, arrayMetadata, index, len,callbackMetadata);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function useCallbackIfNewMetadata(previousTitle: string, arrayMetadata: Array<MediaRadio>, index:number, len: number, callbackMetadata: (
|
|
43
|
+
metadata: MediaRadio,
|
|
44
|
+
podcast: Podcast | undefined,
|
|
45
|
+
history: Array<MediaRadio>
|
|
46
|
+
) => void){
|
|
47
|
+
if (previousTitle !== arrayMetadata[index].title) {
|
|
48
|
+
const historyIndex = index + 1 < len ? index + 1 : index;
|
|
49
|
+
const history = arrayMetadata.slice(historyIndex, len);
|
|
50
|
+
if (arrayMetadata[index].podcastId) {
|
|
51
|
+
const data: Podcast = await classicApi.fetchData<Podcast>({
|
|
52
|
+
api: 0,
|
|
53
|
+
path: "podcast/" + arrayMetadata[index].podcastId,
|
|
54
|
+
});
|
|
55
|
+
callbackMetadata(arrayMetadata[index], data, history);
|
|
56
|
+
} else {
|
|
57
|
+
callbackMetadata(arrayMetadata[index], undefined, history);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function displayTitle(metadata: MediaRadio): string {
|
|
62
|
+
return radioHelper.displayTitle(metadata);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
onBeforeUnmount(() => {
|
|
67
|
+
clearInterval(radioInterval.value as unknown as number);
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
fetchRadioMetadata,
|
|
73
|
+
displayTitle
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { RubriquageFilter } from "@/stores/class/rubrique/rubriquageFilter";
|
|
2
|
+
import { useOrgaComputed } from "../useOrgaComputed";
|
|
3
|
+
import { useFilterStore } from "../../../stores/FilterStore";
|
|
4
|
+
import { useAuthStore } from "../../../stores/AuthStore";
|
|
5
|
+
import { useSimplePageParam } from './useSimplePageParam';
|
|
6
|
+
import { useRubriquesFilterParam } from './useRubriquesFilterParam';
|
|
7
|
+
import { computed, nextTick, onMounted, Ref, ref, watch } from "vue";
|
|
8
|
+
import dayjs from "dayjs";
|
|
9
|
+
|
|
10
|
+
export const useAdvancedParamInit = (props: any, isEmission: boolean)=>{
|
|
11
|
+
|
|
12
|
+
const { searchPattern,organisationId, searchMinSize, paginateFirst, initSearchPattern, initOrga} = useSimplePageParam(props);
|
|
13
|
+
const { isEditRights, isPodcastmaker } = useOrgaComputed();
|
|
14
|
+
const { stringifyRubriquesFilter } = useRubriquesFilterParam();
|
|
15
|
+
|
|
16
|
+
const filterStore = useFilterStore();
|
|
17
|
+
const authStore = useAuthStore();
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const isInit = ref(false);
|
|
21
|
+
const monetisable = ref("UNDEFINED");// UNDEFINED, YES, NO
|
|
22
|
+
const fromDate: Ref<string|undefined> = ref(undefined);
|
|
23
|
+
const toDate: Ref<string|undefined> = ref(undefined);
|
|
24
|
+
const includeHidden = ref(false);
|
|
25
|
+
const sort = ref("DATE"); // SCORE, DATE, POPULARITY, NAME, LAST_PODCAST_DESC
|
|
26
|
+
const validity = ref("true");
|
|
27
|
+
const iabId: Ref<number|undefined> = ref(undefined);
|
|
28
|
+
const rubriqueFilter: Ref<Array<RubriquageFilter>> = ref([]);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
const organisationRight = computed(() => isEditRights(organisationId.value));
|
|
32
|
+
const organisation = computed(() => organisationId.value ?? filterStore.filterOrgaId);
|
|
33
|
+
const rubriquesFilterArrayIds = computed(() => {
|
|
34
|
+
const allRubriquageId: Array<number> = [];
|
|
35
|
+
const noRubriquageId: Array<number> = [];
|
|
36
|
+
const rubriqueId: Array<number> = [];
|
|
37
|
+
for(const filter of rubriqueFilter.value){
|
|
38
|
+
if (-1 === filter.rubriqueId) {
|
|
39
|
+
noRubriquageId.push(filter.rubriquageId);
|
|
40
|
+
} else if (0 === filter.rubriqueId) {
|
|
41
|
+
allRubriquageId.push(filter.rubriquageId);
|
|
42
|
+
} else {
|
|
43
|
+
rubriqueId.push(filter.rubriqueId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
rubriquageId: allRubriquageId,
|
|
48
|
+
rubriqueId: rubriqueId,
|
|
49
|
+
noRubriquageId: noRubriquageId
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
watch(() => props.routeQuery, () => initSearchPattern());
|
|
54
|
+
watch(() => props.routeMonetisable, () => initMonetisable());
|
|
55
|
+
watch(() => props.routeSort, () => initSort());
|
|
56
|
+
watch(() => props.routeIncludeHidden, () => initIncludeHidden());
|
|
57
|
+
watch(() => props.routeValidity, () => initValidity());
|
|
58
|
+
watch(() => props.routeFrom, () => initFromDate());
|
|
59
|
+
watch(() => props.routeTo, () => initToDate());
|
|
60
|
+
watch(() => props.routeIab, () => {iabId.value = props.routeIab;});
|
|
61
|
+
watch(() => props.routeOrga, () => initOrga());
|
|
62
|
+
watch(() => props.routeRubriques, () => initRubriquageFilter());
|
|
63
|
+
watch(organisationId, () => {
|
|
64
|
+
if (!isInit.value) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// TODO si oldValue !=null
|
|
68
|
+
rubriqueFilter.value = [];
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
onMounted(() => {
|
|
72
|
+
initAdvancedParams();
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
function initAdvancedParams(){
|
|
76
|
+
iabId.value = filterStore.filterIab?.id ?? props.routeIab;
|
|
77
|
+
initRubriquageFilter();
|
|
78
|
+
initIncludeHidden();
|
|
79
|
+
initValidity();
|
|
80
|
+
initMonetisable();
|
|
81
|
+
initSort();
|
|
82
|
+
initFromDate();
|
|
83
|
+
initToDate();
|
|
84
|
+
nextTick(() => {
|
|
85
|
+
isInit.value = true;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function initFromDate(){
|
|
90
|
+
if(dayjs(props.routeFrom).isValid()){
|
|
91
|
+
fromDate.value = props.routeFrom;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function initToDate(){
|
|
96
|
+
if(dayjs(props.routeTo).isValid()){
|
|
97
|
+
toDate.value = props.routeTo;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function initMonetisable(){
|
|
102
|
+
if(["YES", "NO"].includes(props.routeMonetisable)){
|
|
103
|
+
monetisable.value = props.routeMonetisable;
|
|
104
|
+
}else{
|
|
105
|
+
monetisable.value = "UNDEFINED";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function initSort(){
|
|
110
|
+
if(["SCORE", "POPULARITY", "NAME", "DATE_ASC"].includes(props.routeSort)){
|
|
111
|
+
sort.value = props.routeSort;
|
|
112
|
+
}else{
|
|
113
|
+
sort.value = isEmission ? "LAST_PODCAST_DESC" : "DATE";
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function initIncludeHidden(){
|
|
118
|
+
includeHidden.value = undefined !== organisation.value && organisationRight.value && "false"!==props.routeIncludeHidden;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function initValidity(){
|
|
122
|
+
const cantDisplay = isPodcastmaker.value || isEmission || !includeHidden.value || !authStore.isRoleContribution || !organisationRight.value;
|
|
123
|
+
if(cantDisplay){
|
|
124
|
+
validity.value = "true";
|
|
125
|
+
}else{
|
|
126
|
+
validity.value = props.routeValidity;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function initRubriquageFilter(){
|
|
131
|
+
if(props.routeRubriques === stringifyRubriquesFilter(rubriqueFilter.value)){
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
const rubriqueFilterToUpdate = [];
|
|
135
|
+
if(props.routeRubriques.trim().length){
|
|
136
|
+
const arrayFilter = props.routeRubriques.split(",");
|
|
137
|
+
for(const filter of arrayFilter){
|
|
138
|
+
const rubriqueFilter = filter.split(":");
|
|
139
|
+
rubriqueFilterToUpdate.push({
|
|
140
|
+
rubriquageId: parseInt(rubriqueFilter[0]),
|
|
141
|
+
rubriqueId: parseInt(rubriqueFilter[1]),
|
|
142
|
+
nameRubriquage: "",
|
|
143
|
+
nameRubrique: "",
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
rubriqueFilter.value = rubriqueFilterToUpdate;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
organisationId,
|
|
152
|
+
searchPattern,
|
|
153
|
+
monetisable,
|
|
154
|
+
iabId,
|
|
155
|
+
sort,
|
|
156
|
+
includeHidden,
|
|
157
|
+
fromDate,
|
|
158
|
+
toDate,
|
|
159
|
+
rubriqueFilter,
|
|
160
|
+
searchMinSize,
|
|
161
|
+
paginateFirst,
|
|
162
|
+
validity,
|
|
163
|
+
rubriquesFilterArrayIds
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useRoute, useRouter } from 'vue-router';
|
|
2
|
+
export const useRouteUpdateParams = ()=>{
|
|
3
|
+
|
|
4
|
+
const router = useRouter();
|
|
5
|
+
const route = useRoute();
|
|
6
|
+
|
|
7
|
+
function checkPage(): boolean{
|
|
8
|
+
return ['podcasts', 'emissions', 'participants', 'playlists', 'productors', 'rubrique'].includes(route.name?.toString()??"");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function checkPageAdvanced(): boolean{
|
|
12
|
+
return ['podcasts', 'emissions'].includes(route.name?.toString()??"");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function updatePaginateSize(ps:number){
|
|
16
|
+
if(checkPage()){
|
|
17
|
+
router.push({query: {...route.query, ...{ps:ps, pr:1}}});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function updateRouteParam(update: {[key:string]: string|undefined}){
|
|
22
|
+
if(checkPage()){
|
|
23
|
+
router.push({query: {...route.query, ...update}});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function updateRouteParamAdvanced(update: {[key:string]: string|undefined}){
|
|
28
|
+
if(checkPageAdvanced()){
|
|
29
|
+
router.push({query: {...route.query, ...update}});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function updateFiltersParam(update: {[key:string]: string|undefined}, advancedUpdate: {[key:string]: string|undefined}){
|
|
34
|
+
if(checkPageAdvanced()){
|
|
35
|
+
router.push({query: {...route.query, ...update, ...advancedUpdate}});
|
|
36
|
+
}else{
|
|
37
|
+
router.push({query: {...route.query, ...update}});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
updatePaginateSize,
|
|
44
|
+
updateRouteParam,
|
|
45
|
+
updateRouteParamAdvanced,
|
|
46
|
+
updateFiltersParam
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RubriquageFilter } from '@/stores/class/rubrique/rubriquageFilter';
|
|
2
|
+
import { useFilterStore } from '../../../stores/FilterStore';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
|
|
5
|
+
export const useRubriquesFilterComputed = ()=>{
|
|
6
|
+
|
|
7
|
+
const filterStore = useFilterStore();
|
|
8
|
+
|
|
9
|
+
const rubriqueQueryParam = computed(() => {
|
|
10
|
+
if (filterStore.filterRubrique?.length) {
|
|
11
|
+
return filterStore.filterRubrique
|
|
12
|
+
.map(
|
|
13
|
+
(value: RubriquageFilter) =>
|
|
14
|
+
value.rubriquageId + ":" + value.rubriqueId,
|
|
15
|
+
)
|
|
16
|
+
.join();
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
rubriqueQueryParam
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { RubriquageFilter } from '@/stores/class/rubrique/rubriquageFilter';
|
|
2
|
+
import { useFilterStore } from '../../../stores/FilterStore';
|
|
3
|
+
import { useRouteUpdateParams } from './useRouteUpdateParams';
|
|
4
|
+
|
|
5
|
+
export const useRubriquesFilterParam = ()=>{
|
|
6
|
+
|
|
7
|
+
const { updateFiltersParam, updateRouteParamAdvanced } = useRouteUpdateParams();
|
|
8
|
+
|
|
9
|
+
const filterStore = useFilterStore();
|
|
10
|
+
|
|
11
|
+
function stringifyRubriquesFilter(filter :Array<RubriquageFilter>|undefined): string{
|
|
12
|
+
if(!filter){
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
return filter
|
|
16
|
+
.map((value) => value.rubriquageId + ":" + value.rubriqueId)
|
|
17
|
+
.join();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function modifyRubriquesFilter(modifyFunction: (a: Array<RubriquageFilter>)=> Array<RubriquageFilter>){
|
|
21
|
+
const newFilter = modifyFunction( Array.from(filterStore.filterRubrique));
|
|
22
|
+
const queryString = stringifyRubriquesFilter(newFilter);
|
|
23
|
+
const valToUpdate = "" !== queryString ? queryString : undefined;
|
|
24
|
+
updateFiltersParam({ rubriquesId: valToUpdate }, {r: valToUpdate});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
stringifyRubriquesFilter,
|
|
29
|
+
modifyRubriquesFilter,
|
|
30
|
+
updateRouteParamAdvanced
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useGeneralStore } from "../../../stores/GeneralStore";
|
|
2
|
+
import { useRoute, useRouter } from "vue-router";
|
|
3
|
+
export const useSeoTitleUrl = ()=>{
|
|
4
|
+
|
|
5
|
+
const router = useRouter();
|
|
6
|
+
const route = useRoute();
|
|
7
|
+
const generalStore = useGeneralStore();
|
|
8
|
+
|
|
9
|
+
function updatePathParams(text: string) {
|
|
10
|
+
const seoText = stringUrlEncode(text);
|
|
11
|
+
if(seoText !== route.params.title){
|
|
12
|
+
router.replace({ params: { ...route.params, ...{title:seoText}}, query: route.query});
|
|
13
|
+
}
|
|
14
|
+
document.title = text + " - "+ generalStore.metaTitle;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function stringUrlEncode(text: string): string {
|
|
18
|
+
if(!text.length){
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
const withoutSpecialChar = text.replaceAll(
|
|
22
|
+
/[!"`'#%&,:;<>=\-_@{}~$.()*+/\\?[\]^|]+/gm, ' ');
|
|
23
|
+
const trimText = withoutSpecialChar.trim();
|
|
24
|
+
return "-"+trimText.replaceAll(/\s+/gm, '-');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
updatePathParams
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useFilterStore } from '../../../stores/FilterStore';
|
|
2
|
+
import { useRouteUpdateParams } from './useRouteUpdateParams';
|
|
3
|
+
import { computed, onMounted, Ref, ref, watch } from "vue";
|
|
4
|
+
|
|
5
|
+
export const useSimplePageParam = (props: any)=>{
|
|
6
|
+
|
|
7
|
+
const { updateRouteParam } = useRouteUpdateParams();
|
|
8
|
+
|
|
9
|
+
const filterStore = useFilterStore();
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const searchPattern = ref("");
|
|
13
|
+
const organisationId: Ref<string|undefined> = ref(undefined);
|
|
14
|
+
|
|
15
|
+
const searchMinSize = computed(() => searchPattern.value.length>3 ? searchPattern.value : "");
|
|
16
|
+
const paginateFirst = computed(() => {
|
|
17
|
+
if(!props.pr){
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
return Math.max((props.pr - 1 ) * props.ps, 0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
watch(searchPattern, () => {
|
|
24
|
+
updateRouteParam({
|
|
25
|
+
q: searchMinSize.value.length ? searchMinSize.value : undefined,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
onMounted(() => {
|
|
30
|
+
initOrga();
|
|
31
|
+
initSearchPattern();
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
function initSearchPattern(){
|
|
35
|
+
searchPattern.value = props.routeQuery ?? "";
|
|
36
|
+
}
|
|
37
|
+
function initOrga(){
|
|
38
|
+
organisationId.value = filterStore.filterOrgaId ?? props.routeOrga;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
searchPattern,
|
|
44
|
+
organisationId,
|
|
45
|
+
searchMinSize,
|
|
46
|
+
paginateFirst,
|
|
47
|
+
initSearchPattern,
|
|
48
|
+
initOrga
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AxiosError } from "axios";
|
|
2
|
+
import { useAuthStore } from "../../stores/AuthStore";
|
|
3
|
+
import { useRouter } from "vue-router";
|
|
4
|
+
|
|
5
|
+
export const useErrorHandler = ()=>{
|
|
6
|
+
|
|
7
|
+
const authStore = useAuthStore();
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
|
|
10
|
+
function handle403(error: AxiosError): void {
|
|
11
|
+
if (403 === error.response?.status) {
|
|
12
|
+
if (undefined === authStore.authOrgaId) {
|
|
13
|
+
window.location.href = window.location.origin + "/sso/login";
|
|
14
|
+
} else {
|
|
15
|
+
router.push({
|
|
16
|
+
path: "/main/pub/error",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
handle403
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useApiStore } from "../../stores/ApiStore";
|
|
2
|
+
export const useImageProxy = ()=>{
|
|
3
|
+
|
|
4
|
+
const apiStore = useApiStore();
|
|
5
|
+
|
|
6
|
+
function useProxyImageUrl(url: string|undefined, width: string, height?: string): string {
|
|
7
|
+
if (!url) {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
10
|
+
if (apiStore.imageUrl && url.includes("http")) {
|
|
11
|
+
const size = height ? "height=" + height : "width=" + width;
|
|
12
|
+
const encode = btoa(url).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
13
|
+
return (
|
|
14
|
+
apiStore.imageUrl +
|
|
15
|
+
"image/" +
|
|
16
|
+
encode +
|
|
17
|
+
"?" +
|
|
18
|
+
size +
|
|
19
|
+
"&useWebp=true"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return url;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
useProxyImageUrl
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import classicApi from "../../api/classicApi";
|
|
3
|
+
import { useAuthStore } from "../../stores/AuthStore";
|
|
4
|
+
import { useGeneralStore } from "../../stores/GeneralStore";
|
|
5
|
+
import { Category } from "@/stores/class/general/category";
|
|
6
|
+
import { useI18n } from "vue-i18n";
|
|
7
|
+
|
|
8
|
+
export const useInit= ()=>{
|
|
9
|
+
|
|
10
|
+
const authStore = useAuthStore();
|
|
11
|
+
const generalStore = useGeneralStore();
|
|
12
|
+
|
|
13
|
+
const i18n = useI18n()
|
|
14
|
+
|
|
15
|
+
async function initSdk() {
|
|
16
|
+
classicApi.fetchData<Array<Category>>({
|
|
17
|
+
api: 0,
|
|
18
|
+
path:`iab/list${authStore.authOrgaId ? "/" + authStore.authOrgaId : ""}`,
|
|
19
|
+
parameters:{ lang: i18n.locale.value },
|
|
20
|
+
})
|
|
21
|
+
.then((data: Array<Category>) => {
|
|
22
|
+
if(data.length){
|
|
23
|
+
generalStore.storedUpdateCategories(data);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const captcha = document.getElementsByClassName(
|
|
27
|
+
"grecaptcha-badge",
|
|
28
|
+
)[0] as HTMLElement;
|
|
29
|
+
if (captcha) {
|
|
30
|
+
captcha.style.display = "none";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
initSdk
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useGeneralStore } from "../../stores/GeneralStore";
|
|
2
|
+
import { useRoute } from "vue-router";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
4
|
+
export const useMetaTitle = ()=>{
|
|
5
|
+
|
|
6
|
+
const route = useRoute();
|
|
7
|
+
const generalStore = useGeneralStore();
|
|
8
|
+
const {t} = useI18n();
|
|
9
|
+
|
|
10
|
+
function updateMetaTitle(){
|
|
11
|
+
if(""!==route.meta.title){
|
|
12
|
+
document.title = route.meta.title ? t(route.meta.title) +' - '+ generalStore.metaTitle: generalStore.metaTitle;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
updateMetaTitle
|
|
18
|
+
}
|
|
19
|
+
}
|