@piedata/pieui 1.0.1 → 1.1.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.
Files changed (134) hide show
  1. package/dist/cli.js +11 -9
  2. package/dist/components/Buttons/AjaxButtonCard/ui/AjaxButtonCard.d.ts +2 -2
  3. package/dist/components/Buttons/AjaxButtonCard/ui/AjaxButtonCard.d.ts.map +1 -1
  4. package/dist/components/Chats/ChatCard/ui/components/AttachFileButton.d.ts.map +1 -1
  5. package/dist/components/Chats/ChatCard/ui/components/ChatCardInput.d.ts +1 -0
  6. package/dist/components/Chats/ChatCard/ui/components/ChatCardInput.d.ts.map +1 -1
  7. package/dist/components/Chats/ChatCard/ui/components/Markdown.d.ts +0 -1
  8. package/dist/components/Chats/ChatCard/ui/components/Markdown.d.ts.map +1 -1
  9. package/dist/components/Containers/AjaxGroupCard/ui/AjaxGroupCard.d.ts +2 -2
  10. package/dist/components/Containers/AjaxGroupCard/ui/AjaxGroupCard.d.ts.map +1 -1
  11. package/dist/components/Containers/SequenceCard/ui/SequenceCard.d.ts.map +1 -1
  12. package/dist/components/Containers/UnionCard/ui/UnionCard.d.ts.map +1 -1
  13. package/dist/components/PieCard/index.d.ts.map +1 -1
  14. package/dist/components/PieRoot/index.d.ts +1 -2
  15. package/dist/components/PieRoot/index.d.ts.map +1 -1
  16. package/dist/components/PieRoot/types/index.d.ts +3 -0
  17. package/dist/components/PieRoot/types/index.d.ts.map +1 -1
  18. package/dist/components/PieTelegramRoot/index.d.ts.map +1 -1
  19. package/dist/components/UI/index.d.ts.map +1 -1
  20. package/dist/components/index.esm.js +24 -26
  21. package/dist/components/index.js +33 -36
  22. package/dist/index.d.ts +1 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.esm.js +30 -32
  25. package/dist/index.js +43 -46
  26. package/dist/providers/CentrifugeIOInitProvider.d.ts.map +1 -1
  27. package/dist/providers/SocketIOInitProvider.d.ts.map +1 -1
  28. package/dist/types/index.d.ts +7 -0
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/dist/util/ajaxCommonUtils.d.ts.map +1 -1
  31. package/dist/util/centrifuge.d.ts +1 -1
  32. package/dist/util/centrifuge.d.ts.map +1 -1
  33. package/dist/util/initializeComponents.d.ts.map +1 -1
  34. package/dist/util/pieConfig.d.ts +12 -0
  35. package/dist/util/pieConfig.d.ts.map +1 -0
  36. package/dist/util/registry.d.ts.map +1 -1
  37. package/dist/util/socket.d.ts +1 -1
  38. package/dist/util/socket.d.ts.map +1 -1
  39. package/dist/util/useIsSupported.d.ts +1 -1
  40. package/dist/util/useIsSupported.d.ts.map +1 -1
  41. package/dist/util/useWebApp.d.ts +2 -2
  42. package/dist/util/useWebApp.d.ts.map +1 -1
  43. package/dist/util/waitForSidAvailable.d.ts +1 -2
  44. package/dist/util/waitForSidAvailable.d.ts.map +1 -1
  45. package/dist/util/webrtcClient.d.ts.map +1 -1
  46. package/package.json +22 -18
  47. package/src/components/Buttons/AjaxButtonCard/index.ts +1 -0
  48. package/src/components/Buttons/AjaxButtonCard/types/index.ts +17 -0
  49. package/src/components/Buttons/AjaxButtonCard/ui/AjaxButtonCard.tsx +38 -0
  50. package/src/components/Chats/ChatCard/index.ts +1 -0
  51. package/src/components/Chats/ChatCard/types/annyang.d.ts +11 -0
  52. package/src/components/Chats/ChatCard/types/index.ts +59 -0
  53. package/src/components/Chats/ChatCard/ui/ChatCard.tsx +130 -0
  54. package/src/components/Chats/ChatCard/ui/components/AttachFileButton.tsx +48 -0
  55. package/src/components/Chats/ChatCard/ui/components/AttachedFileView.tsx +29 -0
  56. package/src/components/Chats/ChatCard/ui/components/ChatCardInput.tsx +177 -0
  57. package/src/components/Chats/ChatCard/ui/components/ChatOption.tsx +25 -0
  58. package/src/components/Chats/ChatCard/ui/components/Markdown.tsx +21 -0
  59. package/src/components/Chats/ChatCard/ui/components/MessageAvatar.tsx +17 -0
  60. package/src/components/Chats/ChatCard/ui/components/MessageCard.tsx +80 -0
  61. package/src/components/Chats/ChatCard/ui/components/MessageContent.tsx +27 -0
  62. package/src/components/Chats/ChatCard/ui/components/MessagesBoard.tsx +61 -0
  63. package/src/components/Chats/ChatCard/ui/components/Options.tsx +20 -0
  64. package/src/components/Chats/ChatCard/ui/components/ResizableTextarea.tsx +59 -0
  65. package/src/components/Chats/ChatCard/ui/components/SendButton.tsx +37 -0
  66. package/src/components/Chats/ChatCard/ui/components/VoiceListeningButton.tsx +35 -0
  67. package/src/components/Chats/ChatCard/ui/components/icons/AttachFileIcon.tsx +18 -0
  68. package/src/components/Chats/ChatCard/ui/components/icons/AttachedFileIcon.tsx +18 -0
  69. package/src/components/Chats/ChatCard/ui/components/icons/CancelFileIcon.tsx +14 -0
  70. package/src/components/Chats/ChatCard/ui/components/icons/DefaultAvatar.tsx +10 -0
  71. package/src/components/Chats/ChatCard/ui/components/icons/SendIcon.tsx +18 -0
  72. package/src/components/Chats/ChatCard/ui/components/icons/VoiceRecordIcon.tsx +15 -0
  73. package/src/components/Containers/AjaxGroupCard/index.ts +1 -0
  74. package/src/components/Containers/AjaxGroupCard/types/index.ts +17 -0
  75. package/src/components/Containers/AjaxGroupCard/ui/AjaxGroupCard.tsx +96 -0
  76. package/src/components/Containers/SequenceCard/index.ts +1 -0
  77. package/src/components/Containers/SequenceCard/types/index.ts +10 -0
  78. package/src/components/Containers/SequenceCard/ui/SequenceCard.tsx +32 -0
  79. package/src/components/Containers/UnionCard/index.ts +1 -0
  80. package/src/components/Containers/UnionCard/types/index.ts +8 -0
  81. package/src/components/Containers/UnionCard/ui/UnionCard.tsx +27 -0
  82. package/src/components/PieCard/index.tsx +149 -0
  83. package/src/components/PieCard/types/index.ts +18 -0
  84. package/src/components/PieRoot/index.tsx +154 -0
  85. package/src/components/PieRoot/types/index.ts +14 -0
  86. package/src/components/PieTelegramRoot/index.tsx +161 -0
  87. package/src/components/UI/index.tsx +70 -0
  88. package/src/components/index.ts +6 -0
  89. package/src/index.ts +15 -0
  90. package/src/providers/CentrifugeIOInitProvider.tsx +42 -0
  91. package/src/providers/SocketIOInitProvider.tsx +52 -0
  92. package/src/types/index.ts +139 -0
  93. package/src/util/ajaxCommonUtils.ts +137 -0
  94. package/src/util/centrifuge.ts +33 -0
  95. package/src/util/fallback.tsx +6 -0
  96. package/src/util/initializeComponents.ts +84 -0
  97. package/src/util/lazy.ts +25 -0
  98. package/src/util/mitt.ts +11 -0
  99. package/src/util/pieConfig.ts +43 -0
  100. package/src/util/registry.ts +81 -0
  101. package/src/util/socket.ts +24 -0
  102. package/src/util/sx2radium.ts +15 -0
  103. package/src/util/tailwindCommonUtils.ts +6 -0
  104. package/src/util/useIsSupported.ts +17 -0
  105. package/src/util/useOpenAIWebRTC.ts +176 -0
  106. package/src/util/useWebApp.ts +32 -0
  107. package/src/util/waitForSidAvailable.ts +21 -0
  108. package/src/util/webrtcClient.ts +247 -0
  109. package/dist/cli.d.ts +0 -3
  110. package/dist/cli.d.ts.map +0 -1
  111. package/dist/components/PieBaseRoot/index.d.ts +0 -5
  112. package/dist/components/PieBaseRoot/index.d.ts.map +0 -1
  113. package/dist/components/PieBaseRoot/types/index.d.ts +0 -6
  114. package/dist/components/PieBaseRoot/types/index.d.ts.map +0 -1
  115. package/dist/components/PieStaticRoot/index.d.ts +0 -5
  116. package/dist/components/PieStaticRoot/index.d.ts.map +0 -1
  117. package/dist/components/PieStaticRoot/types/index.d.ts +0 -7
  118. package/dist/components/PieStaticRoot/types/index.d.ts.map +0 -1
  119. package/dist/config/constant.d.ts +0 -10
  120. package/dist/config/constant.d.ts.map +0 -1
  121. package/dist/util/axiosWithCache.d.ts +0 -3
  122. package/dist/util/axiosWithCache.d.ts.map +0 -1
  123. package/dist/util/globalForm.d.ts +0 -3
  124. package/dist/util/globalForm.d.ts.map +0 -1
  125. package/dist/util/queryClient.d.ts +0 -3
  126. package/dist/util/queryClient.d.ts.map +0 -1
  127. package/dist/util/useBodyStyles.d.ts +0 -5
  128. package/dist/util/useBodyStyles.d.ts.map +0 -1
  129. package/dist/util/useImage.d.ts +0 -5
  130. package/dist/util/useImage.d.ts.map +0 -1
  131. package/dist/util/useScreenSize.d.ts +0 -6
  132. package/dist/util/useScreenSize.d.ts.map +0 -1
  133. package/dist/util/useTitle.d.ts +0 -2
  134. package/dist/util/useTitle.d.ts.map +0 -1
@@ -0,0 +1,161 @@
1
+ import React, {useEffect, useMemo} from 'react'
2
+ import {QueryClient, QueryClientProvider, useQuery} from '@tanstack/react-query'
3
+
4
+ import Radium from "radium";
5
+ import {PieRootProps} from '../PieRoot/types'
6
+
7
+ import MittContext, {emitter} from "../../util/mitt"
8
+ import SocketIOContext, {getSocket} from "../../util/socket"
9
+ import CentrifugeIOContext, {getCentrifuge} from "../../util/centrifuge"
10
+
11
+ import SocketIOInitProvider from "../../providers/SocketIOInitProvider"
12
+ import CentrifugeIOInitProvider from "../../providers/CentrifugeIOInitProvider"
13
+ import FallbackContext from "../../util/fallback";
14
+ import {UIConfigType} from "../../types";
15
+ import {AxiosError} from "axios";
16
+ import UI from "../UI";
17
+ import { createAxiosDateTransformer } from "axios-date-transformer";
18
+ import {
19
+ getApiServer,
20
+ isRenderingLogEnabled,
21
+ getCentrifugeServer,
22
+ PieConfigContext
23
+ } from "../../util/pieConfig";
24
+ import {initializePieComponents, isPieComponentsInitialized} from "../../util/initializeComponents.ts";
25
+ import {useWebApp} from "../../util/useWebApp.ts";
26
+
27
+
28
+ const PieTelegramRootContent: React.FC<PieRootProps> = ({ location, fallback, onError, initializePie }) => {
29
+ const apiServer = getApiServer()
30
+ const centrifugeServer = getCentrifugeServer()
31
+ const renderingLogEnabled = isRenderingLogEnabled()
32
+
33
+ useEffect(() => {
34
+ if (isPieComponentsInitialized()) {
35
+ return
36
+ }
37
+ initializePieComponents()
38
+ initializePie()
39
+ }, [])
40
+
41
+ const axiosInstance = useMemo(() => createAxiosDateTransformer({
42
+ baseURL: apiServer,
43
+ }), [])
44
+
45
+ if (renderingLogEnabled) {
46
+ console.log('[PieRoot] Rendering with location:', location)
47
+ console.log('[PieRoot] API_SERVER:', apiServer)
48
+ console.log('[PieRoot] Fallback provided:', !!fallback)
49
+ }
50
+
51
+ if (!apiServer) {
52
+ throw Error("Set PIE_API_SERVER and PIE_CENTRIFUGE_SERVER")
53
+ }
54
+
55
+ // if (!isPieComponentsInitialized()) {
56
+ // throw Error("Pie components are not initialized. Use initializePieComponents() at the top of page file")
57
+ // }
58
+
59
+ const webApp = useWebApp()
60
+
61
+ const {
62
+ data: uiConfiguration,
63
+ isLoading,
64
+ error,
65
+ } = useQuery<UIConfigType, AxiosError>({
66
+ queryKey: ['uiConfig', location.pathname + location.search, webApp?.initData, isPieComponentsInitialized()],
67
+ queryFn: async () => {
68
+ if (!isPieComponentsInitialized()) {
69
+ return
70
+ }
71
+ const querySymbol = location.search ? '&' : '?'
72
+ const initData = webApp?.initData
73
+ ? `${querySymbol}initData=${encodeURIComponent(webApp.initData)}`
74
+ : ''
75
+ const apiEndpoint = '/api/content' + location.pathname + location.search + initData
76
+
77
+ if (renderingLogEnabled) {
78
+ console.log('[PieRoot] Fetching UI configuration from:', apiEndpoint)
79
+ }
80
+ const response = await axiosInstance.get(apiEndpoint, {
81
+ headers: {
82
+ 'Access-Control-Allow-Origin': '*',
83
+ 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
84
+ 'Content-type': 'application/json',
85
+ },
86
+ withCredentials: true,
87
+ })
88
+ if (renderingLogEnabled) {
89
+ console.log('[PieRoot] Received UI configuration:', response.data)
90
+ }
91
+ return response.data
92
+ },
93
+ staleTime: Infinity,
94
+ gcTime: Infinity,
95
+ refetchOnWindowFocus: false,
96
+ refetchOnMount: false,
97
+ refetchOnReconnect: false,
98
+ retry: true,
99
+ retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000),
100
+ })
101
+
102
+ if (error && renderingLogEnabled) {
103
+ console.error('[PieRoot] Error fetching UI configuration:', error)
104
+ console.error('[PieRoot] Error details:', {
105
+ message: error.message,
106
+ status: error.response?.status,
107
+ data: error.response?.data
108
+ })
109
+ onError?.()
110
+ return fallback
111
+ }
112
+
113
+
114
+ if (isLoading || !uiConfiguration) {
115
+ if (renderingLogEnabled) {
116
+ console.log('[PieRoot] Loading state:', { isLoading, hasUiConfiguration: !!uiConfiguration })
117
+ }
118
+ return fallback
119
+ }
120
+
121
+ if (renderingLogEnabled) {
122
+ console.log('[PieRoot] UI configuration loaded successfully:', uiConfiguration)
123
+ console.log('[PieRoot] Rendering UI with configuration')
124
+ }
125
+
126
+ return (
127
+ <MittContext.Provider value={emitter}>
128
+ <SocketIOContext.Provider value={getSocket(apiServer)}>
129
+ <CentrifugeIOContext.Provider value={getCentrifuge(apiServer, centrifugeServer)}>
130
+ <FallbackContext.Provider value={fallback ?? <></>}>
131
+ <SocketIOInitProvider>
132
+ <CentrifugeIOInitProvider>
133
+
134
+ <Radium.StyleRoot>
135
+ <UI uiConfig={uiConfiguration} />
136
+ </Radium.StyleRoot>
137
+
138
+ </CentrifugeIOInitProvider>
139
+ </SocketIOInitProvider>
140
+ </FallbackContext.Provider>
141
+ </CentrifugeIOContext.Provider>
142
+ </SocketIOContext.Provider>
143
+ </MittContext.Provider>
144
+ )
145
+ }
146
+
147
+
148
+
149
+ const PieTelegramRoot: React.FC<PieRootProps> = (props) => {
150
+ const queryClient = new QueryClient()
151
+ return (
152
+ <PieConfigContext.Provider value={props.config}>
153
+ <QueryClientProvider client={queryClient}>
154
+ <PieTelegramRootContent {...props} />
155
+ </QueryClientProvider>
156
+ </PieConfigContext.Provider>
157
+ )
158
+ }
159
+
160
+
161
+ export default PieTelegramRoot
@@ -0,0 +1,70 @@
1
+ import { UIConfigType, SetUiAjaxConfigurationType } from '../../types'
2
+ import { getRegistryEntry } from "../../util/registry";
3
+ import {Suspense, useContext, ReactNode} from "react";
4
+ import FallbackContext from "../../util/fallback";
5
+ import { isRenderingLogEnabled } from '../../util/pieConfig';
6
+
7
+
8
+ function UI({
9
+ uiConfig,
10
+ setUiAjaxConfiguration,
11
+ }: {
12
+ uiConfig: UIConfigType
13
+ setUiAjaxConfiguration?: SetUiAjaxConfigurationType
14
+ }) {
15
+ const Fallback: ReactNode = useContext(FallbackContext)
16
+ const renderingLogEnabled = isRenderingLogEnabled()
17
+
18
+ if (renderingLogEnabled) {
19
+ console.log('[UI] Rendering component:', uiConfig.card)
20
+ console.log('[UI] Component data:', uiConfig.data)
21
+ console.log('[UI] Component content:', uiConfig.content)
22
+ console.log('[UI] Has setUiAjaxConfiguration:', !!setUiAjaxConfiguration)
23
+ }
24
+
25
+ const entry = getRegistryEntry(uiConfig.card)
26
+ if (!entry?.component) {
27
+ if (renderingLogEnabled) {
28
+ console.warn(`[UI] Component not found in registry: ${uiConfig.card}`)
29
+ console.log('[UI] Returning fallback component')
30
+ }
31
+ return Fallback
32
+ }
33
+
34
+ if (renderingLogEnabled) {
35
+ console.log('[UI] Found component in registry:', {
36
+ name: entry.name,
37
+ isLazy: entry.isLazy,
38
+ hasMetadata: !!entry.metadata
39
+ })
40
+ }
41
+
42
+ const Component = entry.component
43
+
44
+ const node = (
45
+ <Component
46
+ data={uiConfig.data}
47
+ content={uiConfig.content}
48
+ setUiAjaxConfiguration={setUiAjaxConfiguration}
49
+ />
50
+ )
51
+
52
+ if (entry.isLazy) {
53
+ if (renderingLogEnabled) {
54
+ console.log('[UI] Rendering lazy component with Suspense:', entry.name)
55
+ }
56
+ return (
57
+ <Suspense key={`${entry.name}`} fallback={entry.fallback ?? Fallback}>
58
+ {node}
59
+ </Suspense>
60
+ )
61
+ }
62
+
63
+ if (renderingLogEnabled) {
64
+ console.log('[UI] Rendering component directly:', entry.name)
65
+ }
66
+
67
+ return node
68
+ }
69
+
70
+ export default UI
@@ -0,0 +1,6 @@
1
+ export { default as PieCard } from './PieCard';
2
+ export { default as UI } from './UI';
3
+ export { default as ChatCard } from './Chats/ChatCard';
4
+ export { default as AjaxButtonCard } from './Buttons/AjaxButtonCard'
5
+ export { default as SequenceCard } from './Containers/SequenceCard'
6
+ export { default as UnionCard } from './Containers/UnionCard'
package/src/index.ts ADDED
@@ -0,0 +1,15 @@
1
+ export { default as UI } from './components/UI'
2
+ export { default as PieRoot } from './components/PieRoot'
3
+ export { default as PieTelegramRoot } from './components/PieTelegramRoot'
4
+ export { default as PieCard } from './components/PieCard'
5
+ export { registerPieComponent } from './util/registry'
6
+ export { initializePieComponents, isPieComponentsInitialized } from './util/initializeComponents'
7
+
8
+ export type {
9
+ PieSimpleComponentProps,
10
+ PieComplexComponentProps,
11
+ PieContainerComponentProps,
12
+ PieComplexContainerComponentProps,
13
+ PieConfig
14
+ } from './types'
15
+
@@ -0,0 +1,42 @@
1
+ import { ReactNode, useContext, useEffect } from 'react'
2
+ import CentrifugeIOContext from '../util/centrifuge'
3
+ import { useIsSupported } from '../util/useIsSupported'
4
+ import { getApiServer } from "../util/pieConfig";
5
+
6
+
7
+ const CentrifugeIOInitProvider = ({ children }: { children: ReactNode }) => {
8
+ const centrifuge = useContext(CentrifugeIOContext)
9
+ const apiServer = getApiServer()
10
+
11
+ const isCentrifugeSupported = useIsSupported(apiServer, 'centrifuge')
12
+
13
+ useEffect(() => {
14
+ if (!centrifuge) {
15
+ return
16
+ }
17
+
18
+ const onConnectEvent = () => {
19
+ console.log('Centrifuge connected')
20
+ }
21
+
22
+ const onDisconnectEvent = (event: any) => {
23
+ console.log(`Centrifuge disconnected:`, event)
24
+ }
25
+
26
+ if (isCentrifugeSupported) {
27
+ centrifuge.on('connected', onConnectEvent)
28
+ centrifuge.on('disconnected', onDisconnectEvent)
29
+ centrifuge.connect()
30
+ }
31
+
32
+ return () => {
33
+ if (isCentrifugeSupported) {
34
+ centrifuge.disconnect()
35
+ }
36
+ }
37
+ }, [centrifuge, isCentrifugeSupported])
38
+
39
+ return children
40
+ }
41
+
42
+ export default CentrifugeIOInitProvider
@@ -0,0 +1,52 @@
1
+ import { ReactNode, useContext, useEffect } from 'react'
2
+ import SocketIOContext from '../util/socket'
3
+ import { useIsSupported } from '../util/useIsSupported'
4
+ import { Socket } from 'socket.io-client'
5
+ import { getApiServer } from "../util/pieConfig";
6
+
7
+
8
+ const SocketIOInitProvider = ({ children }: { children: ReactNode }) => {
9
+ const socket: Socket | null = useContext(SocketIOContext)
10
+ const apiServer = getApiServer()
11
+ const isSocketIOSupported = useIsSupported(apiServer, 'socketIO')
12
+
13
+ const onPieInitEvent = (event: any) => {
14
+ if (typeof window !== 'undefined') {
15
+ window.sid = event.sid
16
+ console.log(`SocketIO initialized: ${window.sid}`)
17
+ }
18
+ }
19
+
20
+ useEffect(() => {
21
+ if (!socket) {
22
+ return
23
+ }
24
+ const onConnectEvent = () => {
25
+ console.log('SocketIO connected')
26
+ }
27
+
28
+ const onDisconnectEvent = (event: any) => {
29
+ console.log(`SocketIO disconnected: ${event}`)
30
+ socket.connect()
31
+ }
32
+
33
+ if (isSocketIOSupported) {
34
+ socket.on(`pieinit`, onPieInitEvent)
35
+ socket.on('connect', onConnectEvent)
36
+ socket.on('disconnect', onDisconnectEvent)
37
+ socket.connect()
38
+ }
39
+ return () => {
40
+ if (isSocketIOSupported) {
41
+ socket.off(`pieinit`, onPieInitEvent)
42
+ socket.off('connect', onConnectEvent)
43
+ socket.off('disconnect', onDisconnectEvent)
44
+ socket.disconnect()
45
+ }
46
+ }
47
+ }, [socket, isSocketIOSupported])
48
+
49
+ return children
50
+ }
51
+
52
+ export default SocketIOInitProvider
@@ -0,0 +1,139 @@
1
+ import {ComponentType, ReactNode} from "react";
2
+
3
+ export type WebAppUser = {
4
+ id: string
5
+ username: string
6
+ photo_url: string
7
+ }
8
+
9
+ export type MainButtonType = {
10
+ show: () => void
11
+ onClick: (callback: () => void) => void
12
+ offClick: (callback: () => void) => void
13
+ setText: (text: string) => void
14
+ hide: () => void
15
+ }
16
+
17
+ export type BackButtonType = {
18
+ show: () => void
19
+ onClick: (callback: () => void) => void
20
+ hide: () => void
21
+ }
22
+
23
+ export type WebAppInitData = {
24
+ user: WebAppUser
25
+ start_param?: string
26
+ chat_type?: 'sender' | 'private' | 'group' | 'supergroup' | 'channel'
27
+ chat_instance?: string
28
+ auth_date: number
29
+ hash: string
30
+ }
31
+
32
+ export type WebApp = {
33
+ sendData: (data: string) => void
34
+ showAlert: (message: string) => void
35
+ MainButton: MainButtonType
36
+ BackButton: BackButtonType
37
+ initDataUnsafe: WebAppInitData
38
+ initData: string
39
+ ready: () => void
40
+ close: () => void
41
+ openLink: (link: string, option: string) => void
42
+ platform: 'ios' | 'android' | 'web'
43
+ expand: () => void
44
+ }
45
+
46
+ export type Telegram = {
47
+ WebApp: WebApp
48
+ }
49
+
50
+ export type InitDataUnsafe = {
51
+ user?: WebAppUser
52
+ }
53
+
54
+ export type InitData = string
55
+
56
+
57
+ export interface UIConfigType {
58
+ card: string
59
+ data: any
60
+ content: UIConfigType | Array<UIConfigType>
61
+ }
62
+
63
+ export interface UIEventType {
64
+ name: string
65
+ data: Record<any, any>
66
+ }
67
+
68
+ export type SetUiAjaxConfigurationType =
69
+ | ((content: UIConfigType | null) => void)
70
+ | ((events: Array<UIEventType> | null) => void)
71
+
72
+ export interface PieEvent {
73
+ cardName: string
74
+ name: string
75
+ eventName: string
76
+ data: any
77
+ }
78
+
79
+ export type PieEventEmitter = (event: PieEvent) => void
80
+
81
+ declare global {
82
+ interface Window {
83
+ sid: string
84
+ Telegram: Telegram
85
+ }
86
+ }
87
+
88
+
89
+ export interface ComponentMetadata {
90
+ author?: string
91
+ version?: string
92
+ description?: string
93
+ tags?: string[]
94
+ }
95
+
96
+
97
+ export interface PieComplexContainerComponentProps<TData = unknown> {
98
+ data: TData
99
+ content: Array<UIConfigType>
100
+ setUiAjaxConfiguration?: SetUiAjaxConfigurationType
101
+ }
102
+
103
+ export interface PieContainerComponentProps<TData = unknown> {
104
+ data: TData
105
+ content: UIConfigType
106
+ setUiAjaxConfiguration?: SetUiAjaxConfigurationType
107
+ }
108
+
109
+ export interface PieComplexComponentProps<TData = unknown> {
110
+ data: TData
111
+ setUiAjaxConfiguration?: SetUiAjaxConfigurationType
112
+ }
113
+
114
+ export interface PieSimpleComponentProps<TData = unknown> {
115
+ data: TData
116
+ }
117
+
118
+ export type PieComponentProps<TData = unknown> =
119
+ | PieSimpleComponentProps<TData>
120
+ | PieContainerComponentProps<TData>
121
+ | PieComplexContainerComponentProps<TData>
122
+
123
+
124
+ export interface ComponentRegistration<TProps> {
125
+ name: string
126
+ component?: ComponentType<TProps>
127
+ fallback?: ReactNode
128
+ loader?: () => Promise<{ default: ComponentType<TProps> }>
129
+ metadata?: ComponentMetadata
130
+ isLazy?: boolean
131
+ }
132
+
133
+
134
+ export interface PieConfig {
135
+ apiServer: string
136
+ centrifugeServer?: string
137
+ enableRenderingLog?: boolean
138
+ pageProcessor?: string
139
+ }
@@ -0,0 +1,137 @@
1
+ import {getApiServer, isRenderingLogEnabled} from './pieConfig'
2
+ import '../types'
3
+ import { SetUiAjaxConfigurationType, UIEventType } from '../types'
4
+ import waitForSidAvailable from './waitForSidAvailable'
5
+
6
+
7
+ export const getAjaxSubmit = (
8
+ setUiAjaxConfiguration?: SetUiAjaxConfigurationType,
9
+ kwargs: Record<string, any> = {},
10
+ depsNames: Array<string> = [],
11
+ pathname?: string,
12
+ ) => {
13
+ const renderingLogEnabled = isRenderingLogEnabled()
14
+
15
+ if (renderingLogEnabled) {
16
+ console.log('Registering AJAX: ', pathname, kwargs, depsNames)
17
+ }
18
+
19
+ if (!pathname || !setUiAjaxConfiguration) {
20
+ if (renderingLogEnabled) {
21
+ console.warn('Registration FAILED: pathname or setUiAjaxConfiguration is missing!')
22
+ }
23
+ return () => {}
24
+ }
25
+
26
+ return async (extraKwargs: Record<string, any> = {}) => {
27
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
28
+ if (renderingLogEnabled) {
29
+ console.warn('getAjaxSubmit called on server, skipping DOM-dependent logic')
30
+ }
31
+ return
32
+ }
33
+
34
+ if (depsNames.includes('sid')) {
35
+ await waitForSidAvailable()
36
+ }
37
+
38
+ const data = new FormData()
39
+ for (const [key, value] of Object.entries({ ...kwargs, ...extraKwargs })) {
40
+ data.append(key, value)
41
+ }
42
+
43
+ for (const depName of depsNames) {
44
+ if (depName === 'sid') {
45
+ if (!window.sid) throw new Error("SocketIO isn't initialized properly")
46
+ data.append('sid', window.sid)
47
+ } else {
48
+ const inputs = document.getElementsByName(depName)
49
+ if (!inputs.length) {
50
+ if (renderingLogEnabled) {
51
+ console.warn(`No input found with name ${depName}`)
52
+ }
53
+ continue
54
+ }
55
+ const input = inputs[0]
56
+ if (input instanceof HTMLInputElement) {
57
+ if (input.type === 'file' && input.files) {
58
+ Array.from(input.files).forEach((file) => data.append(depName, file))
59
+ } else {
60
+ data.append(depName, input.value)
61
+ }
62
+ } else if (input instanceof HTMLTextAreaElement) {
63
+ data.append(depName, input.value)
64
+ }
65
+ }
66
+ }
67
+
68
+ const apiEndpoint = getApiServer() + 'api/ajax_content' + pathname
69
+
70
+ setUiAjaxConfiguration(null)
71
+ return await fetch(apiEndpoint, {
72
+ method: 'POST',
73
+ body: data,
74
+ })
75
+ .then(async (response) => {
76
+ const contentType = response.headers.get('content-type') || ''
77
+ const isJson = contentType.includes('application/json')
78
+ const isStream = !!response.body?.getReader && !isJson
79
+
80
+ if (isStream) {
81
+ const reader = response.body!.getReader()
82
+ const decoder = new TextDecoder()
83
+ let buffer = ''
84
+
85
+ // eslint-disable-next-line no-constant-condition
86
+ while (true) {
87
+ const { done, value } = await reader.read()
88
+ if (done) break
89
+ buffer += decoder.decode(value, { stream: true })
90
+
91
+ const lines = buffer.split('\n')
92
+ buffer = lines.pop() ?? ''
93
+
94
+ for (const line of lines) {
95
+ const trimmed = line.trim()
96
+ if (!trimmed) continue
97
+ try {
98
+ const currentEvent = JSON.parse(trimmed) as UIEventType
99
+ ;(setUiAjaxConfiguration as (events: UIEventType[]) => void)([
100
+ currentEvent,
101
+ ])
102
+ } catch (err) {
103
+ if (renderingLogEnabled) {
104
+ console.warn('Failed to parse streamed line:', trimmed)
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ if (buffer.trim()) {
111
+ try {
112
+ const currentEvent = JSON.parse(buffer) as UIEventType
113
+ ;(setUiAjaxConfiguration as (events: UIEventType[]) => void)([
114
+ currentEvent,
115
+ ])
116
+ } catch (err) {
117
+ if (renderingLogEnabled) {
118
+ console.warn('Failed to parse final streamed line:', buffer)
119
+ }
120
+ }
121
+ }
122
+ return {}
123
+ } else {
124
+ const data = await response.json()
125
+ setUiAjaxConfiguration(data)
126
+ return data
127
+ }
128
+ })
129
+ .catch((err) => {
130
+ if (renderingLogEnabled) {
131
+ console.error('AJAX request failed:', err)
132
+ }
133
+ setUiAjaxConfiguration(null)
134
+ return err
135
+ })
136
+ }
137
+ }
@@ -0,0 +1,33 @@
1
+ import { createContext } from 'react'
2
+ import { Centrifuge } from 'centrifuge'
3
+
4
+
5
+ export const getCentrifuge = (apiServer: string, centrifugeServer?: string) => {
6
+
7
+ async function getToken() {
8
+ const res = await fetch(apiServer + 'api/centrifuge/gen_token')
9
+ if (!res.ok) {
10
+ if (res.status === 403) {
11
+ throw new Centrifuge.UnauthorizedError('Backend is not answering')
12
+ }
13
+ throw new Error(`Unexpected status code ${res.status}`)
14
+ }
15
+ const data = await res.json()
16
+ return data.token
17
+ }
18
+
19
+ return centrifugeServer ?
20
+ new Centrifuge(centrifugeServer || '', {
21
+ getToken,
22
+ }): null
23
+ }
24
+
25
+
26
+ // export const centrifuge =
27
+ // getCentrifugeServer() ?
28
+ // new Centrifuge(getCentrifugeServer() || '', {
29
+ // getToken,
30
+ // }): null
31
+
32
+ const CentrifugeIOContext = createContext<Centrifuge | null>(null)
33
+ export default CentrifugeIOContext
@@ -0,0 +1,6 @@
1
+ import {createContext, ReactNode} from "react";
2
+
3
+
4
+ const FallbackContext = createContext<ReactNode>(<></>)
5
+
6
+ export default FallbackContext