PluginProbe
Code Snippets / 4.0.0-beta.1
Code Snippets v4.0.0-beta.1
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / EditMenu / SnippetForm / WithSnippetFormContext.tsx

WithSnippetFormContext.tsx in Code Snippets 4.0.0-beta.1, at js/components/EditMenu/SnippetForm/WithSnippetFormContext.tsx

75 lines 2.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { isAxiosError } from 'axios'
2 import React, { useCallback, useMemo, useState } from 'react'
3 import { createContextHook } from '../../../utils/bootstrap'
4 import { isLicensed } from '../../../utils/screen'
5 import { isProSnippet } from '../../../utils/snippets/snippets'
6 import type { Dispatch, PropsWithChildren, SetStateAction } from 'react'
7 import type { ScreenNotice } from '../../../types/ScreenNotice'
8 import type { Snippet } from '../../../types/Snippet'
9 import type { CodeEditorInstance } from '../../../types/WordPressCodeEditor'
10
11 export interface SnippetFormContext {
12 snippet: Snippet
13 isWorking: boolean
14 isReadOnly: boolean
15 setSnippet: Dispatch<SetStateAction<Snippet>>
16 updateSnippet: Dispatch<SetStateAction<Snippet>>
17 setIsWorking: Dispatch<SetStateAction<boolean>>
18 currentNotice: ScreenNotice | undefined
19 setCurrentNotice: Dispatch<SetStateAction<ScreenNotice | undefined>>
20 codeEditorInstance: CodeEditorInstance | undefined
21 handleRequestError: (error: unknown, message?: string) => void
22 setCodeEditorInstance: Dispatch<SetStateAction<CodeEditorInstance | undefined>>
23 }
24
25 const [Context, useSnippetForm] = createContextHook<SnippetFormContext>('useSnippetForm')
26
27 export interface WithSnippetFormContextProps extends PropsWithChildren {
28 initialSnippet: () => Snippet
29 }
30
31 export const WithSnippetFormContext: React.FC<WithSnippetFormContextProps> = ({ children, initialSnippet }) => {
32 const [snippet, setSnippet] = useState<Snippet>(initialSnippet)
33 const [isWorking, setIsWorking] = useState(false)
34 const [currentNotice, setCurrentNotice] = useState<ScreenNotice>()
35 const [codeEditorInstance, setCodeEditorInstance] = useState<CodeEditorInstance>()
36
37 const isReadOnly = useMemo(
38 () => snippet.locked || !isLicensed() && isProSnippet({ scope: snippet.scope }),
39 [snippet.locked, snippet.scope]
40 )
41
42 const handleRequestError = useCallback((error: unknown, message?: string) => {
43 console.error('Request failed', error)
44 setIsWorking(false)
45 setCurrentNotice(['error', [message, isAxiosError(error) ? error.message : ''].filter(Boolean).join(' ')])
46 }, [setIsWorking, setCurrentNotice])
47
48 const updateSnippet: Dispatch<SetStateAction<Snippet>> = useCallback((value: SetStateAction<Snippet>) => {
49 setSnippet(previous => {
50 const updated = 'object' === typeof value ? value : value(previous)
51 codeEditorInstance?.codemirror.setValue(updated.code)
52 window.tinymce?.activeEditor.setContent(updated.desc)
53 return updated
54 })
55 }, [codeEditorInstance?.codemirror])
56
57 const value: SnippetFormContext = {
58 snippet,
59 isWorking,
60 isReadOnly,
61 setSnippet,
62 setIsWorking,
63 updateSnippet,
64 currentNotice,
65 setCurrentNotice,
66 codeEditorInstance,
67 handleRequestError,
68 setCodeEditorInstance
69 }
70
71 return <Context.Provider value={value}>{children}</Context.Provider>
72 }
73
74 export { useSnippetForm }
75