Skip to content

Commit

Permalink
Merge pull request #344 from illa-family/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
AruSeito authored Sep 8, 2022
2 parents abefef4 + 941e4ed commit 054b64b
Show file tree
Hide file tree
Showing 110 changed files with 2,005 additions and 1,068 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# thx chakra ui template
name: "Bug Report"
description: "File a bug report"
labels: [ "Type: Bug 🐛", "needs triage" ]
labels: ["Type: Bug 🐛", "needs triage"]
body:
- type: "markdown"
attributes:
Expand Down Expand Up @@ -38,7 +38,7 @@ body:
attributes:
label: "ILLA Builder Version"
description: "The version of ILLA Builder you use."
placeholder: "1.6.4"
placeholder: "1.0.0"
validations:
required: true
- type: "input"
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<div align="center">
<img alt="ILLA Design Logo" width="120px" height="120px" src="https://cdn.illafamily.com/logo.svg"/>
</div>
Expand Down Expand Up @@ -48,8 +47,7 @@ Join ILLA Community to share your ideas, suggestions, or questions and connect w

## 🌱 Contributing

Thinking about contributing? All kinds of contributions to ILLA are greatly appreciated and welcomed! Check
out [Contributing Guide](./CONTRIBUTING.md) for details about how you can get involved.
Thinking about contributing? All kinds of contributions to ILLA are greatly appreciated and welcomed! Check out [Contributing Guide](./CONTRIBUTING.md) for details about how you can get involved.

## 🔥 We're Hiring

Expand Down
3 changes: 0 additions & 3 deletions apps/builder/.env.dev

This file was deleted.

2 changes: 1 addition & 1 deletion apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "Apache-2.0",
"version": "0.0.0",
"scripts": {
"dev": "vite --mode dev",
"dev": "vite --mode cloud",
"build-cloud": "vite build --mode cloud",
"build-self": "vite build --mode self",
"preview": "vite preview",
Expand Down
235 changes: 174 additions & 61 deletions apps/builder/src/api/ws/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
Broadcast,
Callback,
ILLAWebSocket,
ILLAWebSocketComponentPayload,
Room,
RoomType,
Signal,
Expand All @@ -16,6 +18,31 @@ import {
REMOVE_DISPLAY_NAME,
UPDATE_DISPLAY_NAME,
} from "@/utils/generators/generateDisplayName"
import { ComponentNode } from "@/redux/currentApp/editor/components/componentsState"

export function transformComponentReduxPayloadToWsPayload(
componentNodes: ComponentNode[] | ComponentNode,
): ILLAWebSocketComponentPayload[] {
if (Array.isArray(componentNodes)) {
return componentNodes.map(node => {
return {
before: {
displayName: node.displayName,
},
after: node,
}
})
}
if (!componentNodes) return []
return [
{
before: {
displayName: componentNodes.displayName,
},
after: componentNodes,
},
]
}

export function getPayload<T>(
signal: Signal,
Expand All @@ -28,70 +55,15 @@ export function getPayload<T>(
signal,
target,
option: broadcast ? 1 : 0,
payload,
broadcast: reduxBroadcast,
payload,
})
}

function generateWs(wsUrl: string): WebSocket {
const ws = new WebSocket(wsUrl)
ws.onclose = () => {
Connection.roomMap.delete(wsUrl)
}
ws.onmessage = (event) => {
const message = event.data
if (typeof message !== "string") {
return
}
const dataList = message.split("\n")
dataList.forEach((data: string) => {
let callback: Callback<any> = JSON.parse(data)
if (callback.errorCode === 0) {
if (callback.broadcast != null) {
let broadcast = callback.broadcast
let type = broadcast.type
let payload = broadcast.payload
switch (type) {
case `${ADD_DISPLAY_NAME}/remote`:
;(payload as string[]).forEach((name) => {
DisplayNameGenerator.displayNameList.add(name)
})
break
case `${REMOVE_DISPLAY_NAME}/remote`:
;(payload as string[]).forEach((name) => {
DisplayNameGenerator.displayNameList.delete(name)
})
break
case `${UPDATE_DISPLAY_NAME}/remote`:
DisplayNameGenerator.displayNameList.delete(payload[0])
DisplayNameGenerator.displayNameList.add(payload[1])
break
default:
try {
store.dispatch({
type,
payload,
})
} catch (ignore) {}
}
}
}
})
}
ws.onopen = () => {
ws.send(
getPayload(Signal.SIGNAL_ENTER, Target.TARGET_NOTHING, false, null, [
{
authToken: getLocalStorage("token"),
},
]),
)
}
return ws
}
export const wsMap = new Map()

export class Connection {
static roomMap: Map<string, WebSocket> = new Map()
static roomMap: Map<string, ILLAWebSocket> = new Map()

static enterRoom(
type: RoomType,
Expand Down Expand Up @@ -120,11 +92,11 @@ export class Connection {
}
Api.request<Room>(
config,
(response) => {
response => {
let ws = generateWs(response.data.wsURL)
this.roomMap.set(type + roomId, ws)
},
(error) => {},
error => {},
() => {},
loading,
errorState,
Expand All @@ -141,7 +113,148 @@ export class Connection {
ws.send(
getPayload(Signal.SIGNAL_LEAVE, Target.TARGET_NOTHING, false, null, []),
)
ws.close()
ws.close(1000)
}
}
}

function onMessage(this: ILLAWebSocket, event: MessageEvent) {
resetHeartbeat(this)
const message = event.data
if (typeof message !== "string") {
return
}

const dataList = message.split("\n")
dataList.forEach((data: string) => {
let callback: Callback<unknown> = JSON.parse(data)
if (callback.errorCode === 0) {
if (callback.broadcast != null) {
let broadcast = callback.broadcast
let type = broadcast.type
let payload = broadcast.payload
switch (type) {
case `${ADD_DISPLAY_NAME}/remote`: {
;(payload as string[]).forEach(name => {
DisplayNameGenerator.displayNameList.add(name)
})
break
}
case `${REMOVE_DISPLAY_NAME}/remote`: {
;(payload as string[]).forEach(name => {
DisplayNameGenerator.displayNameList.delete(name)
})
break
}
case `${UPDATE_DISPLAY_NAME}/remote`: {
DisplayNameGenerator.displayNameList.delete(payload[0])
DisplayNameGenerator.displayNameList.add(payload[1])
break
}
default: {
try {
store.dispatch({
type,
payload,
})
} catch (ignore) {}
}
}
}
}
})
}

function onError(this: ILLAWebSocket, event: Event) {
console.error(`[WS ERROR](${this.url} is error)`, event)
this.close(4000, "close with error")
}

function onClose(this: ILLAWebSocket, event: CloseEvent) {
if (event.code !== 1000) {
reconnect(this)
} else {
clearWSTimeout(this)
wsMap.delete(this.url)
}
console.warn(`[WS CLOSED](${this.url}) ${event.code}:${event.reason}`)
}

function onOpen(this: ILLAWebSocket, event: Event) {
this.offline = false
startHeartbeat(this)
console.log(`[WS OPENED](${this.url}) connection succeeded`)
this.send(
getPayload(Signal.SIGNAL_ENTER, Target.TARGET_NOTHING, false, null, [
{
authToken: getLocalStorage("token"),
},
]),
)
}

const HEARTBEAT_TIMEOUT = 2 * 1000
const HEARTBEAT_SERVER_TIMEOUT = 5 * 1000
const RECONNECT_TIMEOUT = 5 * 1000

function clearWSTimeout(ws: ILLAWebSocket) {
ws.timeout && clearTimeout(ws.timeout)
ws.serverTimeout && clearTimeout(ws.serverTimeout)
ws.debounceTimeout && clearTimeout(ws.debounceTimeout)
}

const pingMessage = JSON.stringify({
signal: 0,
option: 0,
target: 0,
payload: [],
broadcast: null,
})

function startHeartbeat(ws: ILLAWebSocket) {
ws.timeout = setTimeout(() => {
ws.send(pingMessage)
ws.serverTimeout = setTimeout(() => {
ws.offline = true
// TODO:MESSAGE
ws.close(4001)
}, HEARTBEAT_SERVER_TIMEOUT)
}, HEARTBEAT_TIMEOUT)
}

function resetHeartbeat(ws: ILLAWebSocket) {
clearWSTimeout(ws)
startHeartbeat(ws)
}

function reconnect(ws: ILLAWebSocket) {
clearWSTimeout(ws)
const callNow = !ws.debounceTimeout
ws.debounceTimeout = setTimeout(() => {
ws.debounceTimeout = null
reconnect(ws)
}, RECONNECT_TIMEOUT)
if (callNow) {
generateWs(ws.url)
}
}

function initWsConfig(ws: ILLAWebSocket) {
ws.timeout = null
ws.serverTimeout = null
ws.debounceTimeout = wsMap.get(ws.url)
? wsMap.get(ws.url).debounceTimeout
: null
ws.offline = wsMap.get(ws.url) ? wsMap.get(ws.url).offline : false
wsMap.set(ws.url, ws)
}

export function generateWs(url: string) {
const ws: ILLAWebSocket = new WebSocket(url)
ws.onopen = onOpen
ws.onerror = onError
ws.onclose = onClose
ws.onmessage = onMessage
initWsConfig(ws)
return ws
}
16 changes: 16 additions & 0 deletions apps/builder/src/api/ws/interface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ComponentNode } from "@/redux/currentApp/editor/components/componentsState"

export type RoomType = "dashboard" | "app"

export interface Room {
Expand Down Expand Up @@ -43,3 +45,17 @@ export interface Callback<T> {
// 0 success, not zero error
errorCode: number
}

export interface ILLAWebSocket extends WebSocket {
timeout?: any
serverTimeout?: any
debounceTimeout?: any
offline?: boolean
}

export interface ILLAWebSocketComponentPayload {
before: {
displayName: string
}
after: ComponentNode
}
2 changes: 1 addition & 1 deletion apps/builder/src/components/EditableText/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const EditableText: FC<EditableTextProps> = (props) => {
}
DisplayNameGenerator.updateDisplayName(inputValue, displayName)
updateDisplayNameByBlur(inputValue)
}, [inputValue])
}, [displayName, inputValue, t, updateDisplayNameByBlur])
return (
<div css={EditableTextWrapperStyle}>
{isFocusInput ? (
Expand Down
19 changes: 13 additions & 6 deletions apps/builder/src/components/PanelBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { FC, useCallback, useState, memo } from "react"
import { FC, memo, useCallback, useState } from "react"
import {
panelBarHeaderStyle,
applyPanelBarOpenedIconStyle,
panelBarTitleStyle,
panelBarItemContentStyle,
panelBarHeaderStyle,
panelBarItemAnimation,
panelBarItemContentStyle,
panelBarTitleStyle,
} from "./style"
import { PanelBarProps } from "./interface"
import { motion, AnimatePresence } from "framer-motion"
import { AnimatePresence, motion } from "framer-motion"
import { UpIcon } from "@illa-design/icon"

export const PanelBar: FC<PanelBarProps> = memo((props: PanelBarProps) => {
const { title, children, isOpened = true, saveToggleState } = props
const {
title,
children,
isOpened = true,
saveToggleState,
onIllaFocus,
} = props
const [isOpenedState, setIsOpenedState] = useState(isOpened)

const handleToggle = useCallback(() => {
Expand All @@ -38,6 +44,7 @@ export const PanelBar: FC<PanelBarProps> = memo((props: PanelBarProps) => {
animate={isOpenedState ? "enter" : "exit"}
exit="exit"
initial={false}
onClick={onIllaFocus}
>
{children}
</motion.div>
Expand Down
Loading

0 comments on commit 054b64b

Please sign in to comment.