@bbki.ng/site 5.5.16 → 5.5.17

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,11 @@
1
1
  # @bbki.ng/site
2
2
 
3
+ ## 5.5.17
4
+
5
+ ### Patch Changes
6
+
7
+ - ae8b5c4: add cd plugin
8
+
3
9
  ## 5.5.16
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/site",
3
- "version": "5.5.16",
3
+ "version": "5.5.17",
4
4
  "description": "code behind bbki.ng",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -57,7 +57,7 @@
57
57
  "vite-plugin-mdx": "^3.5.8",
58
58
  "vite-plugin-pwa": "0.19",
59
59
  "workbox-window": "^6.3.0",
60
- "@bbki.ng/config": "1.0.6"
60
+ "@bbki.ng/config": "1.0.7"
61
61
  },
62
62
  "author": "bbbottle",
63
63
  "license": "MIT",
package/src/blog/app.tsx CHANGED
@@ -1,18 +1,18 @@
1
- import React, { useContext, useEffect } from 'react';
1
+ import React, { useContext } from 'react';
2
2
  import { Outlet, Route, Routes } from 'react-router-dom';
3
- import { Cover, Streaming } from './pages';
4
3
  import { Nav, NotFound, Page, Grid, ErrorBoundary, Container } from '@bbki.ng/ui';
5
4
 
5
+ import { usePaths } from '@/hooks';
6
6
  import ArticlePage from '@/pages/extensions/txt/article';
7
7
  import Txt from '@/pages/extensions/txt';
8
-
9
- import { usePaths } from '@/hooks';
10
- import { SWR } from '@/swr';
11
8
  import { GlobalLoadingContext } from '@/context/global_loading_state_provider';
12
9
  import { BotRedirect } from '@/pages/bot';
13
10
  import { BBContext } from '@/context/bbcontext';
14
11
  import { Slot } from '#/core/components/SlotComp';
15
12
  import { usePlugins } from '#/core/hooks/use_plugins';
13
+ import { SWR } from '@/swr';
14
+
15
+ import { Cover, Streaming } from './pages';
16
16
  import { useDynamicLogo } from './hooks/use_dynamic_logo';
17
17
 
18
18
  const Layout = () => {
@@ -59,7 +59,7 @@ const Layout = () => {
59
59
  };
60
60
 
61
61
  export const App = () => {
62
- usePlugins(['sticker', 'fontstyler']);
62
+ usePlugins(['sticker', 'fontstyler', 'extra-cd']);
63
63
 
64
64
  return (
65
65
  <SWR>
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
- import { useLoading } from '@/hooks';
2
+ import { useGlobalLoading } from '@/hooks';
3
3
 
4
4
  export const Spinner = (props: { disableDotIndicator?: boolean }) => {
5
5
  const { disableDotIndicator } = props;
6
6
 
7
- useLoading('spinner', !disableDotIndicator);
7
+ useGlobalLoading('spinner', !disableDotIndicator);
8
8
 
9
9
  return <div className="h-full w-full grid place-items-center"></div>;
10
10
  };
@@ -1,5 +1,4 @@
1
1
  import React, { ReactNode, useContext, useMemo } from 'react';
2
-
3
2
  import { EffectLayer, grain, paper, spiral, watermark, Effect } from '@bbki.ng/ui';
4
3
 
5
4
  import { GlobalLoadingContext } from '@/context/global_loading_state_provider';
@@ -1,6 +1,7 @@
1
1
  import React, { ReactNode } from 'react';
2
+
2
3
  import { GlobalLoadingStateProvider } from '@/context/global_loading_state_provider';
3
- import { GlobalRoutesContext, GlobalRoutesProvider } from '@/context/global_routes_provider';
4
+ import { GlobalRoutesProvider } from '@/context/global_routes_provider';
4
5
  import { EffectContextProvider } from '@/components/effect-layer/EffectContextProvider';
5
6
 
6
7
  export const BBContext = (props: { children: ReactNode }) => {
@@ -1,4 +1,5 @@
1
1
  import React, { createContext, ReactNode, useState, useCallback, useMemo } from 'react';
2
+
2
3
  import { useFontLoading } from '@/hooks/use_font_loading';
3
4
 
4
5
  type LoadingStates = Map<string, boolean>;
@@ -48,8 +49,8 @@ export const GlobalLoadingStateProvider = (props: { children: ReactNode }) => {
48
49
  }, []);
49
50
 
50
51
  const isLoading = useMemo(() => {
51
- return Array.from(loadingStates.values()).some(Boolean);
52
- }, [loadingStates]);
52
+ return Array.from(loadingStates.values()).some(Boolean) || isFontLoading;
53
+ }, [loadingStates, isFontLoading]);
53
54
 
54
55
  const contextValue = useMemo(
55
56
  () => ({
@@ -1,4 +1,4 @@
1
1
  export { usePaths } from './use_paths';
2
2
  export { useStreaming } from './use_streaming';
3
3
  export type { StreamingItem } from './use_streaming';
4
- export { useLoading } from './use_loading';
4
+ export { useGlobalLoading } from './use_loading';
@@ -1,4 +1,5 @@
1
1
  import { useContext, useEffect } from 'react';
2
+
2
3
  import { GlobalLoadingContext } from '@/context/global_loading_state_provider';
3
4
 
4
5
  /**
@@ -7,23 +8,19 @@ import { GlobalLoadingContext } from '@/context/global_loading_state_provider';
7
8
  *
8
9
  * @param id - Unique identifier for this loading state
9
10
  * @param loading - Whether this specific loading state is active
10
- *
11
- * @example
12
- * // In a data fetching hook
13
- * useLoading('posts', isDataLoading);
14
- *
15
- * @example
16
- * // In a component
17
- * useLoading('spinner', true);
18
11
  */
19
- export function useLoading(id: string, loading: boolean) {
20
- const { register, setLoading, unregister } = useContext(GlobalLoadingContext);
12
+ export function useGlobalLoading(id: string | undefined, loading: boolean | undefined) {
13
+ const { register, setLoading, unregister, isLoading } = useContext(GlobalLoadingContext);
21
14
 
22
15
  useEffect(() => {
16
+ if (!id || loading === undefined) return;
17
+
23
18
  register(id);
24
19
  setLoading(id, loading);
25
20
  return () => {
26
21
  unregister(id);
27
22
  };
28
- }, [id, loading, register, setLoading, unregister]);
23
+ }, [id, loading]);
24
+
25
+ return isLoading;
29
26
  }
@@ -1,13 +1,12 @@
1
1
  import useSWR from 'swr';
2
2
  import { useMemo } from 'react';
3
- import { useLoading } from '@/hooks';
3
+
4
+ import { useGlobalLoading } from '@/hooks';
4
5
  import { baseFetcher } from '@/utils';
5
6
  import { API_ENDPOINT } from '@/constants/routes';
6
7
  import { useMiddlewareTransData } from '#/core/hooks';
7
8
 
8
- // In dev, use /api prefix to leverage Vite proxy to localhost:8787
9
9
  const isProd = true;
10
- // const isProd = typeof window !== 'undefined' && /^https:\/\/bbki\.ng/.test(window.location.href);
11
10
  const POSTS_API = !isProd ? '/api/posts' : `${API_ENDPOINT}/posts`;
12
11
 
13
12
  export interface TitleListItem {
@@ -23,25 +22,17 @@ export const usePosts = (name: string = '', suspense?: boolean) => {
23
22
  suspense,
24
23
  });
25
24
 
26
- // Extract posts array from API response { status: "success", data: [...] }
27
25
  const data = response?.data;
28
26
  const isDataLoading = !data && !swrError;
29
27
 
30
- // Build base title list from posts data
31
28
  const baseTitleList: TitleListItem[] = useMemo(() => {
32
29
  if (!data || swrError) return [];
33
- return [
34
- ...data.map((p: any) => ({
35
- name: p.title,
36
- to: p.title,
37
- children: p.title,
38
- })),
39
- {
40
- name: 'cd ~',
41
- to: '/',
42
- children: 'cd ~',
43
- },
44
- ];
30
+
31
+ return data.map((p: any) => ({
32
+ name: p.title,
33
+ to: p.title,
34
+ children: p.title,
35
+ }));
45
36
  }, [data, swrError]);
46
37
 
47
38
  // Use middleware hook to transform title list
@@ -55,7 +46,7 @@ export const usePosts = (name: string = '', suspense?: boolean) => {
55
46
  immediate: baseTitleList.length > 0,
56
47
  });
57
48
 
58
- useLoading('posts', isDataLoading || isTransforming);
49
+ const gLoading = useGlobalLoading('posts', isDataLoading || isTransforming);
59
50
 
60
51
  const posts =
61
52
  isDataLoading || name === '' || swrError || !data
@@ -66,6 +57,6 @@ export const usePosts = (name: string = '', suspense?: boolean) => {
66
57
  posts,
67
58
  titleList: titleList ?? [],
68
59
  isError: swrError || transformError,
69
- isLoading: isDataLoading || (baseTitleList.length > 0 && isTransforming),
60
+ isLoading: gLoading,
70
61
  };
71
62
  };
@@ -1,9 +1,10 @@
1
1
  import useSWR from 'swr';
2
- import useSWRInfinite from 'swr/infinite';
3
- import { baseFetcher, withBBApi } from '@/utils';
2
+ import { useEffect, useState } from 'react';
3
+
4
+ import { baseFetcher } from '@/utils';
4
5
  import { API_ENDPOINT } from '@/constants/routes';
5
- import { useEffect, useState, useCallback } from 'react';
6
- import { useLoading } from '@/hooks';
6
+
7
+ import { useGlobalLoading } from './use_loading';
7
8
 
8
9
  // In dev, use /api prefix to leverage Vite proxy to localhost:8787
9
10
  // const isProd = typeof window !== 'undefined' && /^https:\/\/bbki.ng/.test(window.location.href);
@@ -101,7 +102,7 @@ export function useStreaming(options: UseStreamingOptions = {}) {
101
102
  });
102
103
  }, []);
103
104
 
104
- useLoading('streaming', isLoading);
105
+ useGlobalLoading('streaming', isLoading);
105
106
 
106
107
  return {
107
108
  streaming: data?.data ?? [],
@@ -1,5 +1,7 @@
1
- import { SlotName } from 'src/types/slots';
2
- import { useEffect, useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ import { SlotName } from '#/types/slots';
4
+
3
5
  import { registry } from '../registry';
4
6
 
5
7
  export const useSlotComp = (slotName: SlotName) => {
@@ -1,6 +1,7 @@
1
1
  import { useEffect } from 'react';
2
2
 
3
3
  import { pluginManager } from '#/core/pluginManager';
4
+ import { PluginID } from '#/types/plugin';
4
5
 
5
6
  /**
6
7
  * 通用插件管理 hook
@@ -11,7 +12,7 @@ import { pluginManager } from '#/core/pluginManager';
11
12
  * @example
12
13
  * usePlugins(['sticker', 'fontstyler']);
13
14
  */
14
- export const usePlugins = (pluginIds: string[]) => {
15
+ export const usePlugins = (pluginIds: Array<PluginID>) => {
15
16
  useEffect(() => {
16
17
  // 加载指定的插件
17
18
  pluginIds.forEach(id => {
@@ -0,0 +1,38 @@
1
+ import { IHostContext } from '#/types/hostApi';
2
+ import { IPlugin } from '#/types/plugin';
3
+ import { TitleListItem } from '#/types/posts';
4
+
5
+ class ExtraCd implements IPlugin {
6
+ id: string = 'extra-cd';
7
+ name: string = 'Extra CD';
8
+ description: string =
9
+ 'Provides additional change directory functionalities for enhanced user experience.';
10
+ version: string = '1.0.0';
11
+ author: string = 'bbki.ng';
12
+
13
+ async onInstall(ctx: IHostContext): Promise<void> {
14
+ // Initialize any required resources or settings
15
+ ctx.api.registerMiddleware('transformTitleList', this.transformTitleList, this.id, 10);
16
+ }
17
+
18
+ async onDisable(): Promise<void> {
19
+ // Clean up active operations
20
+ }
21
+
22
+ onDestroy(): void {
23
+ // Release all resources
24
+ }
25
+
26
+ private transformTitleList = (titleList: Array<TitleListItem>) => {
27
+ return [
28
+ ...titleList,
29
+ {
30
+ name: 'cd ~',
31
+ to: '/',
32
+ children: 'cd ~',
33
+ },
34
+ ];
35
+ };
36
+ }
37
+
38
+ export default new ExtraCd();
@@ -11,6 +11,13 @@ export const PLUGIN_MANIFEST = [
11
11
  version: '0.1.0',
12
12
  description: 'A sticker plugin',
13
13
  },
14
+ {
15
+ name: 'extra-cd',
16
+ id: 'extra-cd',
17
+ version: '0.1.0',
18
+ description:
19
+ 'Provides additional change directory functionalities for enhanced user experience.',
20
+ },
14
21
  {
15
22
  name: 'fontstyler',
16
23
  id: 'fontstyler',
@@ -1,5 +1,6 @@
1
1
  import { IHostContext } from '#/types/hostApi';
2
2
  import { IPlugin } from '#/types/plugin';
3
+
3
4
  import { Emoji } from './components/emoji';
4
5
 
5
6
  class TestPlugin implements IPlugin {
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
- import { HookPoint, SlotName } from './slots';
4
3
  import { type FingerprintData } from '@/utils/fingerprints';
5
4
 
5
+ import { HookPoint, SlotName } from './slots';
6
+
6
7
  export interface IHostApi {
7
8
  getDeviceId: () => Promise<{ id: string; fp: FingerprintData }>;
8
9
  registerMiddleware: <T>(
@@ -11,3 +11,5 @@ export interface IPlugin {
11
11
  onDisable?: () => Promise<void> | void;
12
12
  onDestroy?: () => void;
13
13
  }
14
+
15
+ export type PluginID = 'sticker' | 'fontstyler' | 'extra-cd';
@@ -0,0 +1,6 @@
1
+ export interface TitleListItem {
2
+ name: string;
3
+ to: string;
4
+ children: string;
5
+ className?: string;
6
+ }
package/tsconfig.json CHANGED
@@ -5,6 +5,7 @@
5
5
  "jsx": "react",
6
6
  "noEmit": true,
7
7
  "moduleResolution": "bundler",
8
+ "ignoreDeprecations": "6.0",
8
9
  "baseUrl": ".",
9
10
  "paths": {
10
11
  "@/*": ["src/blog/*"],