erudit 2.0.0-dev.8 → 3.0.0-dev.1
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/.nuxtrc +1 -1
- package/app/components/SiteMain.vue +2 -2
- package/app/components/aside/major/panes/Search.vue +10 -2
- package/app/components/aside/minor/AsideMinorContributor.vue +1 -1
- package/app/components/aside/minor/AsideMinorPane.vue +2 -3
- package/app/components/aside/minor/topic/TopicToc.vue +2 -1
- package/app/components/aside/minor/topic/TopicTocItem.vue +3 -3
- package/app/components/bitran/BitranContent.vue +20 -21
- package/app/components/bitran/RenderWrapper.vue +2 -4
- package/app/components/main/topic/MainTopic.vue +1 -1
- package/app/components/main/utils/ContentDescription.vue +3 -4
- package/app/components/main/utils/ContentFlag.vue +3 -4
- package/app/components/main/utils/ContentReferences.vue +16 -22
- package/app/components/main/utils/ContentSection.vue +21 -18
- package/app/components/main/utils/ContentTitle.vue +12 -10
- package/app/components/main/utils/reference/ReferenceGroup.vue +5 -8
- package/app/components/main/utils/reference/ReferenceItem.vue +25 -21
- package/app/components/main/utils/reference/ReferenceSource.vue +42 -36
- package/app/components/preview/PreviewLoading.vue +2 -3
- package/app/components/preview/display/Unique.vue +2 -2
- package/app/components/transition/Fade.vue +4 -7
- package/app/components/tree/TreeContainer.vue +2 -3
- package/app/composables/bitran.ts +127 -132
- package/app/composables/bitranContent.ts +37 -36
- package/app/composables/bitranLocation.ts +7 -7
- package/app/composables/contentData.ts +36 -36
- package/app/composables/contentPage.ts +156 -156
- package/app/composables/contentRoute.ts +45 -45
- package/app/composables/darkMagic.ts +24 -24
- package/app/composables/externalApi.ts +63 -63
- package/app/composables/favicon.ts +8 -8
- package/app/composables/formatText.ts +86 -86
- package/app/composables/majorPane.ts +60 -60
- package/app/composables/theme.ts +29 -29
- package/app/composables/url.ts +33 -33
- package/app/pages/article/[...articleId].vue +1 -1
- package/app/pages/group/[...groupId].vue +2 -1
- package/app/pages/members.vue +2 -3
- package/app/pages/practice/[...practice].vue +1 -1
- package/app/pages/summary/[...summaryId].vue +1 -1
- package/app/public/favicon/article.svg +9 -9
- package/app/public/favicon/default.svg +9 -9
- package/app/public/favicon/practice.svg +9 -9
- package/app/public/favicon/summary.svg +9 -9
- package/app/public/logotype.svg +16 -16
- package/app/public/user.svg +9 -9
- package/app/scripts/_immediate.js +7 -2
- package/app/scripts/aside/index.ts +59 -59
- package/app/scripts/aside/major/nav.ts +26 -26
- package/app/scripts/aside/minor/state.ts +37 -37
- package/app/scripts/aside/minor/topic.ts +3 -3
- package/app/scripts/preview/build.ts +73 -84
- package/app/scripts/preview/data/alert.ts +19 -19
- package/app/scripts/preview/data/custom.ts +8 -8
- package/app/scripts/preview/data/genericLink.ts +24 -24
- package/app/scripts/preview/data/pageLink.ts +20 -20
- package/app/scripts/preview/data/unique.ts +70 -70
- package/app/scripts/preview/data.ts +24 -26
- package/app/scripts/preview/display.ts +37 -39
- package/app/scripts/preview/footer.ts +9 -9
- package/app/scripts/preview/request.ts +51 -51
- package/app/scripts/preview/state.ts +63 -63
- package/app/styles/_immediate.css +6 -2
- package/app/styles/_util.scss +13 -20
- package/app/styles/app.scss +91 -91
- package/app/styles/def/_bp.scss +27 -24
- package/app/styles/def/_size.scss +7 -7
- package/app/styles/def/_z.scss +5 -5
- package/app/styles/default.scss +33 -35
- package/app/styles/normalize.scss +63 -63
- package/app/styles/partials/_darkMagic.scss +3 -5
- package/app/styles/partials/_fnav.scss +4 -7
- package/app/styles/partials/_preview.scss +3 -5
- package/globals/bitran.ts +47 -39
- package/globals/content.ts +22 -22
- package/globals/contributor.ts +5 -5
- package/module/bitran.ts +34 -34
- package/module/index.ts +12 -0
- package/module/paths.ts +22 -22
- package/nuxt.config.ts +20 -5
- package/package.json +9 -6
- package/server/api/contributor/count.ts +6 -6
- package/server/api/fake/content.ts +6 -6
- package/server/api/preview/page/[...parts].ts +1 -1
- package/server/plugin/bitran/content.ts +187 -176
- package/server/plugin/bitran/location.ts +25 -25
- package/server/plugin/bitran/products/include.ts +230 -229
- package/server/plugin/bitran/products/link.ts +116 -114
- package/server/plugin/bitran/setup.ts +9 -10
- package/server/plugin/bitran/toc.ts +83 -82
- package/server/plugin/bitran/transpiler.ts +46 -0
- package/server/plugin/build/jobs/content/builderArgs.ts +8 -8
- package/server/plugin/build/jobs/content/generic.ts +176 -176
- package/server/plugin/build/jobs/content/parse.ts +100 -90
- package/server/plugin/build/jobs/content/path.ts +6 -6
- package/server/plugin/build/jobs/content/type/book.ts +9 -9
- package/server/plugin/build/jobs/content/type/group.ts +37 -37
- package/server/plugin/build/jobs/content/type/topic.ts +36 -36
- package/server/plugin/build/jobs/contributors.ts +66 -66
- package/server/plugin/build/jobs/nav.ts +209 -209
- package/server/plugin/content/absoluteId.ts +94 -94
- package/server/plugin/content/context.ts +112 -112
- package/server/plugin/db/entities/Book.ts +7 -7
- package/server/plugin/db/entities/Content.ts +49 -49
- package/server/plugin/db/entities/Contribution.ts +10 -10
- package/server/plugin/db/entities/Contributor.ts +16 -16
- package/server/plugin/db/entities/Group.ts +14 -14
- package/server/plugin/db/entities/Hash.ts +15 -15
- package/server/plugin/db/entities/Topic.ts +20 -20
- package/server/plugin/db/entities/Unique.ts +21 -21
- package/server/plugin/db/setup.ts +34 -34
- package/server/plugin/nav/node.ts +26 -26
- package/server/plugin/nav/utils.ts +129 -129
- package/server/plugin/repository/book.ts +21 -21
- package/server/plugin/repository/content.ts +238 -238
- package/server/plugin/repository/contributor.ts +8 -8
- package/server/plugin/repository/frontNav.ts +148 -148
- package/server/plugin/repository/topic.ts +32 -32
- package/shared/aside/minor.ts +50 -50
- package/shared/asset.ts +15 -15
- package/shared/bitran/context.ts +8 -7
- package/shared/bitran/default.ts +46 -0
- package/shared/bitran/{products/link/render → link}/Link.vue +167 -174
- package/shared/bitran/link/factory.ts +24 -0
- package/shared/bitran/link/languages/en.ts +7 -0
- package/shared/bitran/link/languages/ru.ts +7 -0
- package/shared/bitran/link/renderer.ts +21 -0
- package/shared/bitran/link/shared.ts +17 -0
- package/shared/bitran/{products/link → link}/target.ts +134 -134
- package/shared/bitran/link/transpiler.ts +10 -0
- package/shared/bitran/location.ts +166 -166
- package/shared/bitran/toc.ts +8 -8
- package/shared/contributor.ts +5 -5
- package/shared/frontNav.ts +41 -41
- package/shared/icons.ts +38 -38
- package/shared/image.ts +5 -5
- package/shared/utils/objectsEqual.ts +4 -4
- package/shared/utils/stringColor.ts +9 -9
- package/test/bitran/{products/link → link}/target.test.ts +141 -138
- package/test/bitran/location.test.ts +143 -143
- package/server/plugin/bitran/core.ts +0 -51
- package/shared/bitran/alias.ts +0 -17
- package/shared/bitran/products/alias/core/factory.ts +0 -46
- package/shared/bitran/products/alias/core/index.ts +0 -13
- package/shared/bitran/products/alias/render/Alias.vue +0 -10
- package/shared/bitran/products/alias/render/icon.svg +0 -3
- package/shared/bitran/products/alias/render/index.ts +0 -17
- package/shared/bitran/products/alias/render/languages/en.ts +0 -5
- package/shared/bitran/products/alias/render/languages/ru.ts +0 -5
- package/shared/bitran/products/alias/shared.ts +0 -11
- package/shared/bitran/products/heading/core/factory.ts +0 -53
- package/shared/bitran/products/heading/core/index.ts +0 -19
- package/shared/bitran/products/heading/render/Heading.vue +0 -47
- package/shared/bitran/products/heading/render/icon.svg +0 -3
- package/shared/bitran/products/heading/render/index.ts +0 -17
- package/shared/bitran/products/heading/render/languages/en.ts +0 -5
- package/shared/bitran/products/heading/render/languages/ru.ts +0 -5
- package/shared/bitran/products/heading/shared.ts +0 -13
- package/shared/bitran/products/include/core/factory.ts +0 -61
- package/shared/bitran/products/include/core/index.ts +0 -13
- package/shared/bitran/products/include/render/Include.vue +0 -13
- package/shared/bitran/products/include/render/icon.svg +0 -3
- package/shared/bitran/products/include/render/index.ts +0 -18
- package/shared/bitran/products/include/render/languages/en.ts +0 -5
- package/shared/bitran/products/include/render/languages/ru.ts +0 -5
- package/shared/bitran/products/include/shared.ts +0 -15
- package/shared/bitran/products/link/core/factory.ts +0 -20
- package/shared/bitran/products/link/core/index.ts +0 -17
- package/shared/bitran/products/link/render/index.ts +0 -17
- package/shared/bitran/products/link/render/languages/en.ts +0 -5
- package/shared/bitran/products/link/render/languages/ru.ts +0 -5
- package/shared/bitran/products/link/shared.ts +0 -15
- package/test/bitran/alias.test.ts +0 -44
- package/test/bitran/products/alias.test.ts +0 -83
- package/test/bitran/products/heading.test.ts +0 -119
- package/test/bitran/products/include.test.ts +0 -77
- package/test/bitran/products/link/factory.test.ts +0 -30
- /package/shared/bitran/{products/link/render → link}/icon.svg +0 -0
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
import eruditConfig from '#erudit/config';
|
|
2
|
-
|
|
3
|
-
import { createOgImageTags, defaultOgImage } from '@app/scripts/og';
|
|
4
|
-
import type { ContentData } from '@shared/content/data';
|
|
5
|
-
|
|
6
|
-
export function useContentPage(contentData: Ref<ContentData>) {
|
|
7
|
-
const contentRoute = useContentRoute();
|
|
8
|
-
const siteUrl = useSiteUrl();
|
|
9
|
-
const favicon = useFavicon();
|
|
10
|
-
|
|
11
|
-
const phrasePromise = usePhrases(
|
|
12
|
-
'article',
|
|
13
|
-
'summary',
|
|
14
|
-
'practice',
|
|
15
|
-
'site_info_title',
|
|
16
|
-
'seo_article_description',
|
|
17
|
-
'seo_summary_description',
|
|
18
|
-
'seo_practice_description',
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
// Favicon
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
const contentFavicon = () => {
|
|
26
|
-
setTimeout(() => {
|
|
27
|
-
const newFavicon = (() => {
|
|
28
|
-
switch (contentRoute.value?.type) {
|
|
29
|
-
case 'topic':
|
|
30
|
-
const topicPart = contentRoute.value.topicPart;
|
|
31
|
-
return (
|
|
32
|
-
eruditConfig.site?.favicon?.[topicPart] ||
|
|
33
|
-
eruditAsset(`favicon/${topicPart}.svg`)
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return defaultFavicon;
|
|
38
|
-
})();
|
|
39
|
-
|
|
40
|
-
favicon.value = newFavicon;
|
|
41
|
-
}, 500);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
// SEO
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
let seoTitlePromise: Promise<void>, seoDescriptionPromise: Promise<void>;
|
|
49
|
-
|
|
50
|
-
const seo = {
|
|
51
|
-
title: ref<string>(),
|
|
52
|
-
description: ref<string>(),
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const setupSeoTitle = () => {
|
|
56
|
-
seoTitlePromise = (async () => {
|
|
57
|
-
const phrase = await phrasePromise;
|
|
58
|
-
|
|
59
|
-
let title: string = '';
|
|
60
|
-
title +=
|
|
61
|
-
contentData.value.generic?.seo?.title ||
|
|
62
|
-
contentData.value.generic.title ||
|
|
63
|
-
contentData.value.generic.contentId.split('/').pop();
|
|
64
|
-
|
|
65
|
-
if (contentData.value.type !== 'book') {
|
|
66
|
-
const bookTitle = contentData.value?.bookTitle;
|
|
67
|
-
title += bookTitle ? ` | ${bookTitle}` : '';
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (contentRoute.value!.type === 'topic') {
|
|
71
|
-
const topicPart = contentRoute.value!.topicPart;
|
|
72
|
-
|
|
73
|
-
if (topicPart !== 'article') title += ` | ${phrase[topicPart]}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
title +=
|
|
77
|
-
' - ' + eruditConfig.seo?.title ||
|
|
78
|
-
eruditConfig.site?.title ||
|
|
79
|
-
phrase.site_info_title;
|
|
80
|
-
|
|
81
|
-
seo.title.value = title;
|
|
82
|
-
})();
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const setupSeoDescription = () => {
|
|
86
|
-
seoDescriptionPromise = (async () => {
|
|
87
|
-
const phrase = await phrasePromise;
|
|
88
|
-
const customDescription =
|
|
89
|
-
contentData.value.generic?.seo?.description ||
|
|
90
|
-
contentData.value.generic?.description;
|
|
91
|
-
|
|
92
|
-
if (customDescription) {
|
|
93
|
-
seo.description.value = customDescription;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (contentRoute.value!.type === 'topic') {
|
|
98
|
-
const phraseFunc =
|
|
99
|
-
phrase[`seo_${contentRoute.value!.topicPart}_description`];
|
|
100
|
-
seo.description.value = phraseFunc(
|
|
101
|
-
contentData.value.generic?.seo?.title ||
|
|
102
|
-
contentData.value.generic.title!,
|
|
103
|
-
);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
seo.description.value = '';
|
|
108
|
-
})();
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
useSeoMeta({
|
|
112
|
-
// @ts-ignore
|
|
113
|
-
title: seo.title,
|
|
114
|
-
ogTitle: seo.title,
|
|
115
|
-
description: seo.description,
|
|
116
|
-
ogDescription: seo.description,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
const meta = computed(() => {
|
|
120
|
-
return [
|
|
121
|
-
...createOgImageTags(siteUrl, defaultOgImage),
|
|
122
|
-
...(contentData.value.generic?.ogImage
|
|
123
|
-
? createOgImageTags(siteUrl, contentData.value.generic?.ogImage)
|
|
124
|
-
: []),
|
|
125
|
-
];
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
useHead({
|
|
129
|
-
meta,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
watchEffect(() => {
|
|
137
|
-
setupSeoTitle();
|
|
138
|
-
setupSeoDescription();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
onMounted(() => {
|
|
142
|
-
watchEffect(() => {
|
|
143
|
-
contentFavicon();
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
onBeforeUnmount(() => {
|
|
148
|
-
favicon.value = defaultFavicon;
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
return Promise.all([seoTitlePromise!, seoDescriptionPromise!]);
|
|
156
|
-
}
|
|
1
|
+
import eruditConfig from '#erudit/config';
|
|
2
|
+
|
|
3
|
+
import { createOgImageTags, defaultOgImage } from '@app/scripts/og';
|
|
4
|
+
import type { ContentData } from '@shared/content/data';
|
|
5
|
+
|
|
6
|
+
export function useContentPage(contentData: Ref<ContentData>) {
|
|
7
|
+
const contentRoute = useContentRoute();
|
|
8
|
+
const siteUrl = useSiteUrl();
|
|
9
|
+
const favicon = useFavicon();
|
|
10
|
+
|
|
11
|
+
const phrasePromise = usePhrases(
|
|
12
|
+
'article',
|
|
13
|
+
'summary',
|
|
14
|
+
'practice',
|
|
15
|
+
'site_info_title',
|
|
16
|
+
'seo_article_description',
|
|
17
|
+
'seo_summary_description',
|
|
18
|
+
'seo_practice_description',
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
// Favicon
|
|
23
|
+
//
|
|
24
|
+
|
|
25
|
+
const contentFavicon = () => {
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
const newFavicon = (() => {
|
|
28
|
+
switch (contentRoute.value?.type) {
|
|
29
|
+
case 'topic':
|
|
30
|
+
const topicPart = contentRoute.value.topicPart;
|
|
31
|
+
return (
|
|
32
|
+
eruditConfig.site?.favicon?.[topicPart] ||
|
|
33
|
+
eruditAsset(`favicon/${topicPart}.svg`)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return defaultFavicon;
|
|
38
|
+
})();
|
|
39
|
+
|
|
40
|
+
favicon.value = newFavicon;
|
|
41
|
+
}, 500);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//
|
|
45
|
+
// SEO
|
|
46
|
+
//
|
|
47
|
+
|
|
48
|
+
let seoTitlePromise: Promise<void>, seoDescriptionPromise: Promise<void>;
|
|
49
|
+
|
|
50
|
+
const seo = {
|
|
51
|
+
title: ref<string>(),
|
|
52
|
+
description: ref<string>(),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const setupSeoTitle = () => {
|
|
56
|
+
seoTitlePromise = (async () => {
|
|
57
|
+
const phrase = await phrasePromise;
|
|
58
|
+
|
|
59
|
+
let title: string = '';
|
|
60
|
+
title +=
|
|
61
|
+
contentData.value.generic?.seo?.title ||
|
|
62
|
+
contentData.value.generic.title ||
|
|
63
|
+
contentData.value.generic.contentId.split('/').pop();
|
|
64
|
+
|
|
65
|
+
if (contentData.value.type !== 'book') {
|
|
66
|
+
const bookTitle = contentData.value?.bookTitle;
|
|
67
|
+
title += bookTitle ? ` | ${bookTitle}` : '';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (contentRoute.value!.type === 'topic') {
|
|
71
|
+
const topicPart = contentRoute.value!.topicPart;
|
|
72
|
+
|
|
73
|
+
if (topicPart !== 'article') title += ` | ${phrase[topicPart]}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
title +=
|
|
77
|
+
' - ' + eruditConfig.seo?.title ||
|
|
78
|
+
eruditConfig.site?.title ||
|
|
79
|
+
phrase.site_info_title;
|
|
80
|
+
|
|
81
|
+
seo.title.value = title;
|
|
82
|
+
})();
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const setupSeoDescription = () => {
|
|
86
|
+
seoDescriptionPromise = (async () => {
|
|
87
|
+
const phrase = await phrasePromise;
|
|
88
|
+
const customDescription =
|
|
89
|
+
contentData.value.generic?.seo?.description ||
|
|
90
|
+
contentData.value.generic?.description;
|
|
91
|
+
|
|
92
|
+
if (customDescription) {
|
|
93
|
+
seo.description.value = customDescription;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (contentRoute.value!.type === 'topic') {
|
|
98
|
+
const phraseFunc =
|
|
99
|
+
phrase[`seo_${contentRoute.value!.topicPart}_description`];
|
|
100
|
+
seo.description.value = phraseFunc(
|
|
101
|
+
contentData.value.generic?.seo?.title ||
|
|
102
|
+
contentData.value.generic.title!,
|
|
103
|
+
);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
seo.description.value = '';
|
|
108
|
+
})();
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
useSeoMeta({
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
title: seo.title,
|
|
114
|
+
ogTitle: seo.title,
|
|
115
|
+
description: seo.description,
|
|
116
|
+
ogDescription: seo.description,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const meta = computed(() => {
|
|
120
|
+
return [
|
|
121
|
+
...createOgImageTags(siteUrl, defaultOgImage),
|
|
122
|
+
...(contentData.value.generic?.ogImage
|
|
123
|
+
? createOgImageTags(siteUrl, contentData.value.generic?.ogImage)
|
|
124
|
+
: []),
|
|
125
|
+
];
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
useHead({
|
|
129
|
+
meta,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
//
|
|
133
|
+
//
|
|
134
|
+
//
|
|
135
|
+
|
|
136
|
+
watchEffect(() => {
|
|
137
|
+
setupSeoTitle();
|
|
138
|
+
setupSeoDescription();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
onMounted(() => {
|
|
142
|
+
watchEffect(() => {
|
|
143
|
+
contentFavicon();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
onBeforeUnmount(() => {
|
|
148
|
+
favicon.value = defaultFavicon;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
//
|
|
152
|
+
//
|
|
153
|
+
//
|
|
154
|
+
|
|
155
|
+
return Promise.all([seoTitlePromise!, seoDescriptionPromise!]);
|
|
156
|
+
}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import type { ContentType, TopicPart } from 'erudit-cog/schema';
|
|
2
|
-
|
|
3
|
-
interface ContentRouteBase {
|
|
4
|
-
type: ContentType;
|
|
5
|
-
contentId: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface TopicRoute extends ContentRouteBase {
|
|
9
|
-
type: 'topic';
|
|
10
|
-
topicPart: TopicPart;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface ContentRoute extends ContentRouteBase {
|
|
14
|
-
type: Exclude<ContentType, 'topic'>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function useContentRoute(): ComputedRef<
|
|
18
|
-
TopicRoute | ContentRoute | undefined
|
|
19
|
-
> {
|
|
20
|
-
const route = useRoute();
|
|
21
|
-
return computed(() => {
|
|
22
|
-
const match = route.path.match(/\/(.+?)\/(.+)/);
|
|
23
|
-
|
|
24
|
-
if (!match || !match[1] || !match[2]) return undefined;
|
|
25
|
-
|
|
26
|
-
switch (match[1]) {
|
|
27
|
-
case 'article':
|
|
28
|
-
case 'summary':
|
|
29
|
-
case 'practice':
|
|
30
|
-
return <TopicRoute>{
|
|
31
|
-
type: 'topic',
|
|
32
|
-
contentId: match[2],
|
|
33
|
-
topicPart: match[1],
|
|
34
|
-
};
|
|
35
|
-
case 'group':
|
|
36
|
-
case 'book':
|
|
37
|
-
return <ContentRoute>{
|
|
38
|
-
type: match[1],
|
|
39
|
-
contentId: match[2],
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return undefined;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
1
|
+
import type { ContentType, TopicPart } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
interface ContentRouteBase {
|
|
4
|
+
type: ContentType;
|
|
5
|
+
contentId: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TopicRoute extends ContentRouteBase {
|
|
9
|
+
type: 'topic';
|
|
10
|
+
topicPart: TopicPart;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ContentRoute extends ContentRouteBase {
|
|
14
|
+
type: Exclude<ContentType, 'topic'>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useContentRoute(): ComputedRef<
|
|
18
|
+
TopicRoute | ContentRoute | undefined
|
|
19
|
+
> {
|
|
20
|
+
const route = useRoute();
|
|
21
|
+
return computed(() => {
|
|
22
|
+
const match = route.path.match(/\/(.+?)\/(.+)/);
|
|
23
|
+
|
|
24
|
+
if (!match || !match[1] || !match[2]) return undefined;
|
|
25
|
+
|
|
26
|
+
switch (match[1]) {
|
|
27
|
+
case 'article':
|
|
28
|
+
case 'summary':
|
|
29
|
+
case 'practice':
|
|
30
|
+
return <TopicRoute>{
|
|
31
|
+
type: 'topic',
|
|
32
|
+
contentId: match[2],
|
|
33
|
+
topicPart: match[1],
|
|
34
|
+
};
|
|
35
|
+
case 'group':
|
|
36
|
+
case 'book':
|
|
37
|
+
return <ContentRoute>{
|
|
38
|
+
type: match[1],
|
|
39
|
+
contentId: match[2],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return undefined;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
declare let Ya: any;
|
|
2
|
-
|
|
3
|
-
const getElementId = (bannerId: string) => {
|
|
4
|
-
return `DarkMagic_${bannerId}`;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const registerBanner = (bannerId: string) => {
|
|
8
|
-
const { binaryTheme } = useTheme();
|
|
9
|
-
|
|
10
|
-
(window['yaContextCb'] ||= []).push(() => {
|
|
11
|
-
Ya.Context.AdvManager.render({
|
|
12
|
-
renderTo: getElementId(bannerId),
|
|
13
|
-
blockId: bannerId,
|
|
14
|
-
darkTheme: binaryTheme.value === 'dark',
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export function useDarkMagic() {
|
|
20
|
-
return {
|
|
21
|
-
getElementId,
|
|
22
|
-
registerBanner,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
1
|
+
declare let Ya: any;
|
|
2
|
+
|
|
3
|
+
const getElementId = (bannerId: string) => {
|
|
4
|
+
return `DarkMagic_${bannerId}`;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const registerBanner = (bannerId: string) => {
|
|
8
|
+
const { binaryTheme } = useTheme();
|
|
9
|
+
|
|
10
|
+
(window['yaContextCb'] ||= []).push(() => {
|
|
11
|
+
Ya.Context.AdvManager.render({
|
|
12
|
+
renderTo: getElementId(bannerId),
|
|
13
|
+
blockId: bannerId,
|
|
14
|
+
darkTheme: binaryTheme.value === 'dark',
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function useDarkMagic() {
|
|
20
|
+
return {
|
|
21
|
+
getElementId,
|
|
22
|
+
registerBanner,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import type { EruditConfigDebug } from 'erudit-cog/schema';
|
|
2
|
-
|
|
3
|
-
import eruditConfig from '#erudit/config';
|
|
4
|
-
|
|
5
|
-
function useFakeUrl(
|
|
6
|
-
fakeApiTarget: keyof EruditConfigDebug['fakeApi'],
|
|
7
|
-
): boolean {
|
|
8
|
-
return eruditConfig.debug?.fakeApi?.[fakeApiTarget] ?? import.meta.dev;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function getPayload() {
|
|
12
|
-
const nuxt = useNuxtApp();
|
|
13
|
-
const payloadKey = 'external-api';
|
|
14
|
-
const payload =
|
|
15
|
-
(nuxt.static.data[payloadKey] ||=
|
|
16
|
-
nuxt.payload.data[payloadKey] ||=
|
|
17
|
-
{});
|
|
18
|
-
|
|
19
|
-
return payload;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function useExternalApiLanguages() {
|
|
23
|
-
const sharedUrl = eruditConfig.repository?.sharedUrl;
|
|
24
|
-
if (!sharedUrl) return {};
|
|
25
|
-
|
|
26
|
-
const payload = getPayload();
|
|
27
|
-
const fake = useFakeUrl('languages');
|
|
28
|
-
|
|
29
|
-
if (fake) {
|
|
30
|
-
payload.languages ||= await $fetch('/api/fake/shared/languages');
|
|
31
|
-
} else {
|
|
32
|
-
payload.languages ||= await $fetch(
|
|
33
|
-
`https://api.github.com/repos/${sharedUrl}/contents/languages.json`,
|
|
34
|
-
{
|
|
35
|
-
headers: { Accept: 'application/vnd.github.v3.raw' },
|
|
36
|
-
responseType: 'json',
|
|
37
|
-
//transform: (response: string) => JSON.parse(response),
|
|
38
|
-
},
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return payload.languages;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function useExternalApiRepository() {
|
|
46
|
-
const repositoryName = eruditConfig.repository?.name;
|
|
47
|
-
const repositoryBranch = eruditConfig.repository?.branch;
|
|
48
|
-
|
|
49
|
-
if (!repositoryName || !repositoryBranch) return undefined;
|
|
50
|
-
|
|
51
|
-
const payload = getPayload();
|
|
52
|
-
const fake = useFakeUrl('repository');
|
|
53
|
-
|
|
54
|
-
if (fake) {
|
|
55
|
-
payload.repository ||= await $fetch('/api/fake/content');
|
|
56
|
-
} else {
|
|
57
|
-
payload.repository ||= await $fetch(
|
|
58
|
-
`https://api.github.com/repos/${repositoryName}/branches/${repositoryBranch}`,
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return payload.repository;
|
|
63
|
-
}
|
|
1
|
+
import type { EruditConfigDebug } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
import eruditConfig from '#erudit/config';
|
|
4
|
+
|
|
5
|
+
function useFakeUrl(
|
|
6
|
+
fakeApiTarget: keyof EruditConfigDebug['fakeApi'],
|
|
7
|
+
): boolean {
|
|
8
|
+
return eruditConfig.debug?.fakeApi?.[fakeApiTarget] ?? import.meta.dev;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getPayload() {
|
|
12
|
+
const nuxt = useNuxtApp();
|
|
13
|
+
const payloadKey = 'external-api';
|
|
14
|
+
const payload =
|
|
15
|
+
(nuxt.static.data[payloadKey] ||=
|
|
16
|
+
nuxt.payload.data[payloadKey] ||=
|
|
17
|
+
{});
|
|
18
|
+
|
|
19
|
+
return payload;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function useExternalApiLanguages() {
|
|
23
|
+
const sharedUrl = eruditConfig.repository?.sharedUrl;
|
|
24
|
+
if (!sharedUrl) return {};
|
|
25
|
+
|
|
26
|
+
const payload = getPayload();
|
|
27
|
+
const fake = useFakeUrl('languages');
|
|
28
|
+
|
|
29
|
+
if (fake) {
|
|
30
|
+
payload.languages ||= await $fetch('/api/fake/shared/languages');
|
|
31
|
+
} else {
|
|
32
|
+
payload.languages ||= await $fetch(
|
|
33
|
+
`https://api.github.com/repos/${sharedUrl}/contents/languages.json`,
|
|
34
|
+
{
|
|
35
|
+
headers: { Accept: 'application/vnd.github.v3.raw' },
|
|
36
|
+
responseType: 'json',
|
|
37
|
+
//transform: (response: string) => JSON.parse(response),
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return payload.languages;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function useExternalApiRepository() {
|
|
46
|
+
const repositoryName = eruditConfig.repository?.name;
|
|
47
|
+
const repositoryBranch = eruditConfig.repository?.branch;
|
|
48
|
+
|
|
49
|
+
if (!repositoryName || !repositoryBranch) return undefined;
|
|
50
|
+
|
|
51
|
+
const payload = getPayload();
|
|
52
|
+
const fake = useFakeUrl('repository');
|
|
53
|
+
|
|
54
|
+
if (fake) {
|
|
55
|
+
payload.repository ||= await $fetch('/api/fake/content');
|
|
56
|
+
} else {
|
|
57
|
+
payload.repository ||= await $fetch(
|
|
58
|
+
`https://api.github.com/repos/${repositoryName}/branches/${repositoryBranch}`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return payload.repository;
|
|
63
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import eruditConfig from '#erudit/config';
|
|
2
|
-
|
|
3
|
-
export const defaultFavicon =
|
|
4
|
-
eruditConfig.site?.favicon?.default || eruditAsset('favicon/default.svg');
|
|
5
|
-
|
|
6
|
-
export function useFavicon() {
|
|
7
|
-
return useState('favicon', () => defaultFavicon);
|
|
8
|
-
}
|
|
1
|
+
import eruditConfig from '#erudit/config';
|
|
2
|
+
|
|
3
|
+
export const defaultFavicon =
|
|
4
|
+
eruditConfig.site?.favicon?.default || eruditAsset('favicon/default.svg');
|
|
5
|
+
|
|
6
|
+
export function useFavicon() {
|
|
7
|
+
return useState('favicon', () => defaultFavicon);
|
|
8
|
+
}
|