@bbki.ng/site 5.5.23 → 5.5.25

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,17 @@
1
1
  # @bbki.ng/site
2
2
 
3
+ ## 5.5.25
4
+
5
+ ### Patch Changes
6
+
7
+ - 942ce66: hide icon on fonts loading
8
+
9
+ ## 5.5.24
10
+
11
+ ### Patch Changes
12
+
13
+ - 48e4f2d: add new transformer to xwy plugin
14
+
3
15
  ## 5.5.23
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/site",
3
- "version": "5.5.23",
3
+ "version": "5.5.25",
4
4
  "description": "code behind bbki.ng",
5
5
  "main": "index.js",
6
6
  "type": "module",
Binary file
@@ -5,6 +5,7 @@ import { useParams } from 'react-router-dom';
5
5
  import { usePosts } from '@/hooks/use_posts';
6
6
  import { ArticlePage } from '@/components/article';
7
7
  import { useBlogScrollReset } from '@/hooks/use_blog_scroll_pos_restoration';
8
+ import { useMiddlewareTransformedData } from '#/core/hooks/useMiddlewareTransData';
8
9
 
9
10
  function TxtArticle() {
10
11
  const { title } = useParams();
@@ -12,6 +13,8 @@ function TxtArticle() {
12
13
 
13
14
  useBlogScrollReset();
14
15
 
16
+ const transformedContent = useMiddlewareTransformedData('transformPostContent', posts?.content);
17
+
15
18
  if (!title) {
16
19
  return <NotFound />;
17
20
  }
@@ -28,7 +31,7 @@ function TxtArticle() {
28
31
 
29
32
  return (
30
33
  <ArticlePage title={title} date={date}>
31
- <div dangerouslySetInnerHTML={{ __html: posts.content }} />
34
+ <div dangerouslySetInnerHTML={{ __html: transformedContent }} />
32
35
  </ArticlePage>
33
36
  );
34
37
  }
@@ -53,18 +53,16 @@ export function useMiddlewareRunner<T>({
53
53
  return { loading, error, run };
54
54
  }
55
55
 
56
- export const useMiddlewareTransformedData = <T>(hookPoint: HookPoint, defaultValue: Array<T>) => {
57
- const [result, setResult] = useState<Array<T>>(defaultValue);
56
+ export const useMiddlewareTransformedData = <T>(hookPoint: HookPoint, defaultValue: T) => {
57
+ const [result, setResult] = useState<T>(defaultValue);
58
58
 
59
- const runRef = useRef<(input: Array<T>) => Promise<Array<T>>>(() =>
60
- Promise.resolve(defaultValue)
61
- );
59
+ const runRef = useRef<(input: T) => Promise<T>>(() => Promise.resolve(defaultValue));
62
60
 
63
61
  const onMiddlewareChange = useCallback(() => {
64
62
  runRef.current(defaultValue).then(setResult);
65
63
  }, [defaultValue]);
66
64
 
67
- const { run } = useMiddlewareRunner<Array<T>>({
65
+ const { run } = useMiddlewareRunner<T>({
68
66
  hookPoint,
69
67
  onMiddlewareChange,
70
68
  });
@@ -1,5 +1,7 @@
1
1
  import { FontRule } from '../types';
2
2
 
3
+ export const LOADING_CLASS = 'fonts-loading';
4
+
3
5
  export const FontRules: Array<FontRule> = [
4
6
  {
5
7
  match: '小乌鸦合集',
@@ -12,4 +14,14 @@ export const FontRules: Array<FontRule> = [
12
14
  extraCls: 'text-2xl w-[81px]',
13
15
  variant: 'special',
14
16
  },
17
+ {
18
+ match: '',
19
+ fontFamily: 'xwy-icon',
20
+ fontConfig: {
21
+ name: 'xwy-icon',
22
+ src: '/fonts/yao-icons.woff2',
23
+ format: 'woff2',
24
+ hideGlyphOnLoading: true,
25
+ },
26
+ },
15
27
  ];
@@ -1,11 +1,12 @@
1
+ import { PathObj } from '@bbki.ng/ui';
2
+
1
3
  import { IHostContext } from '#/types/hostApi';
2
4
  import { IPlugin } from '#/types/plugin';
3
5
  import { TitleListItem } from '#/types/posts';
4
- import { PathObj } from '@bbki.ng/ui';
5
- import { SpecialTitle } from './components/article';
6
6
 
7
+ import { SpecialTitle } from './components/article';
7
8
  import { XwyLogo } from './components/logo';
8
- import { FontRules } from './const';
9
+ import { FontRules, LOADING_CLASS } from './const';
9
10
  import { loadFont } from './utils';
10
11
 
11
12
  class XwyPlugin implements IPlugin {
@@ -18,6 +19,9 @@ class XwyPlugin implements IPlugin {
18
19
  private loadedFonts = new Set<string>();
19
20
 
20
21
  onInstall = (ctx: IHostContext) => {
22
+ // add font loading listener
23
+ this.initFontLoadingListener();
24
+
21
25
  // 加载所有需要的字体文件
22
26
  FontRules.forEach(rule => {
23
27
  if (rule.fontConfig && !this.loadedFonts.has(rule.fontConfig.name)) {
@@ -42,6 +46,14 @@ class XwyPlugin implements IPlugin {
42
46
  10 // weight
43
47
  );
44
48
 
49
+ // 注册中间件,修改文章内容
50
+ ctx.api.registerMiddleware(
51
+ 'transformPostContent',
52
+ this.transformPostContent,
53
+ this.id,
54
+ 10 // weight
55
+ );
56
+
45
57
  // 注册logo插槽组件
46
58
  ctx.api.registerSlot('logo', XwyLogo, this.id);
47
59
 
@@ -49,6 +61,27 @@ class XwyPlugin implements IPlugin {
49
61
  ctx.api.registerSlot('articleTitle', SpecialTitle, this.id);
50
62
  };
51
63
 
64
+ private initFontLoadingListener() {
65
+ // listen font loading status and add class to body for styling
66
+ document.documentElement.classList.add(LOADING_CLASS);
67
+ document.fonts.ready.then(() => {
68
+ document.documentElement.classList.remove(LOADING_CLASS);
69
+ });
70
+ }
71
+
72
+ private transformPostContent = (content: string) => {
73
+ // 在文章内容中替换特定关键词为特殊样式
74
+ return content
75
+ .replace(
76
+ /小乌鸦/g,
77
+ `<span class="font-xwy text-content-special text-[1.6rem] align-middle">小乌鸦</span>`
78
+ )
79
+ .replace(
80
+ /公园/,
81
+ `公园 <span class="font-xwy-icon text-[#679867] text-[1.6rem] align-middle">&#xE01A&#xE003</span>`
82
+ );
83
+ };
84
+
52
85
  private transformBreadcrumbPaths = (paths: PathObj[]) => {
53
86
  const result = paths.map(p => {
54
87
  if (p.name === '小乌鸦合集') {
@@ -4,6 +4,7 @@ export interface FontConfig {
4
4
  format: 'woff2' | 'woff' | 'ttf' | 'otf';
5
5
  fontWeight?: string;
6
6
  fontStyle?: string;
7
+ hideGlyphOnLoading?: boolean;
7
8
  }
8
9
 
9
10
  export interface FontRule {
@@ -1,9 +1,18 @@
1
+ import { LOADING_CLASS } from '../const';
1
2
  import { type FontConfig } from '../types';
2
3
 
3
4
  export const loadFont = (config: FontConfig) => {
4
5
  const styleId = `font-${config.name}`;
5
6
  if (document.getElementById(styleId)) return;
6
7
 
8
+ const hideCssRule = config.hideGlyphOnLoading
9
+ ? `
10
+ .${LOADING_CLASS} .font-${config.name} {
11
+ visibility: hidden;
12
+ }
13
+ `
14
+ : '';
15
+
7
16
  const style = document.createElement('style');
8
17
  style.id = styleId;
9
18
  style.textContent = `
@@ -12,11 +21,12 @@ export const loadFont = (config: FontConfig) => {
12
21
  src: url('${config.src}') format('${config.format}');
13
22
  font-weight: ${config.fontWeight || 'normal'};
14
23
  font-style: ${config.fontStyle || 'normal'};
15
- font-display: swap;
24
+ font-display: block;
16
25
  }
17
26
  .font-${config.name} {
18
27
  font-family: '${config.name}', monospace;
19
28
  }
29
+ ${hideCssRule}
20
30
  `;
21
31
  document.head.appendChild(style);
22
32
  };