Skip to content

Commit 9b9c8e7

Browse files
committed
wips
1 parent 8a27d3b commit 9b9c8e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+3487
-1179
lines changed

.github/workflows/ci.yml

+7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ jobs:
4646
# yarn prepublishOnly
4747
yarn test
4848
49+
- name: Testing @paplico/editor
50+
continue-on-error: true
51+
run: |
52+
cd pkgs/editor
53+
# yarn prepublishOnly
54+
yarn test
55+
4956
- name: Testing @paplico/web2
5057
continue-on-error: true
5158
run: |

.github/workflows/deploy.yml

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515
- uses: actions/checkout@v4
1616

1717
- uses: ./.github/actions/setup
18+
env:
19+
BUILD_TARGET_ENV: 'production'
1820
with:
1921
node-version: ${{ matrix.node-version }}
2022

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"pkgs/*"
77
],
88
"scripts": {
9-
"dev": "wsrun -p @paplico/shared-lib @paplico/web2 @paplico/core-new @paplico/editor -c dev",
10-
"build": "wsrun -p @paplico/shared-lib @paplico/web2 @paplico/core-new @paplico/editor -c build",
9+
"dev": "BUILD_TARGET_ENV=development wsrun -p @paplico/shared-lib @paplico/web2 @paplico/core-new @paplico/editor -c dev",
10+
"build": "BUILD_TARGET_ENV=production wsrun -p @paplico/shared-lib @paplico/web2 @paplico/core-new @paplico/editor -c build",
1111
"start": "cd pkgs/web; yarn start",
1212
"prepare": "husky install"
1313
},

pkgs/chat/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"devDependencies": {
2424
"@rollup/plugin-typescript": "^9.0.2",
25+
"@types/pusher-js": "^5.1.0",
2526
"rollup-plugin-node-externals": "^6.1.2",
2627
"typescript": "^5.0.4",
2728
"vite": "^4.5.0",
@@ -33,8 +34,7 @@
3334
"@paplico/core": "*",
3435
"ws": "^8.14.2"
3536
},
36-
"peerDependencies": {
37-
"ag-psd": "^17.0.6",
38-
"react": "*"
37+
"optionalDependencies": {
38+
"pusher-js": "^8.3.0"
3939
}
4040
}

pkgs/chat/src/client.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { paplicoChat } from '@/client/bind'
22
export { PaplicoChatWebSocketBackend } from '@/client/websocketBackend'
3+
export { PaplicoChatPusherBackend } from '@/client/pusherBackend'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ClientSentPayloads } from '@/shared/client-sent-payloads'
2+
import { Paplico } from '@paplico/core-new'
3+
4+
export interface IPaplicoChatBackend {
5+
dispose(): void
6+
7+
connect(pap: Paplico): Promise<void>
8+
9+
requestJoin(roomId?: string): Promise<void>
10+
11+
putStrokeComplete(
12+
data: Omit<ClientSentPayloads.StrokeCompletePayload, 'type'>,
13+
): void
14+
}

pkgs/chat/src/client/bind.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export function paplicoChat(
1414
pap.on('strokePreComplete', (e) => {
1515
backend.putStrokeComplete({
1616
uiStroke: e.stroke,
17-
strokeSettings: pap.state.currentStroke,
18-
targetLayerUid: pap.state.activeLayer!.layerUid,
17+
strokeSettings: pap.getBrushSetting(),
18+
targetNode: pap.getStrokingTarget()!.nodePath,
1919
})
2020
})
2121

@@ -25,8 +25,8 @@ export function paplicoChat(
2525
backend.dispose()
2626
}
2727
return {
28-
joinRoom: (roomId?: string) => {
29-
backend.requestJoin(roomId)
28+
joinRoom: async (roomId?: string) => {
29+
await backend.requestJoin(roomId)
3030
},
3131
dispose,
3232
}

pkgs/chat/src/client/pusherBackend.ts

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import Pusher, { Options, Channel } from 'pusher-js'
2+
import { ClientSentPayloads } from '@/shared/client-sent-payloads'
3+
import { ServerSentPayloads } from '@/shared/server-sent-payloads'
4+
import { Document, Paplico, UIStroke } from '@paplico/core-new'
5+
import { IPaplicoChatBackend } from './IPaplicoChatBackend'
6+
7+
const serialize = (payload: ClientSentPayloads) => JSON.stringify(payload)
8+
9+
export class PaplicoChatPusherBackend implements IPaplicoChatBackend {
10+
protected pplc: Paplico | null = null
11+
protected psr: Pusher | null = null
12+
protected channel: Channel | null = null
13+
14+
protected appKey: string
15+
protected pusherOptions: Options
16+
17+
constructor(appKey: string, options: Options) {
18+
this.appKey = appKey
19+
this.pusherOptions = options
20+
}
21+
22+
public dispose() {
23+
this.channel?.disconnect()
24+
this.psr?.disconnect()
25+
}
26+
27+
public async connect(pplc: Paplico) {
28+
this.pplc = pplc
29+
this.psr = await new Promise<Pusher>((resolve, reject) => {
30+
const psr = new Pusher(this.appKey, this.pusherOptions)
31+
resolve(psr)
32+
})
33+
}
34+
35+
public async requestJoin(roomId?: string) {
36+
const channel = (this.channel = this.psr!.subscribe(`private-${roomId}`))
37+
38+
this.channel = await new Promise<Channel>((resolve, reject) => {
39+
channel.bind('pusher:subscription_succeeded', () => {
40+
resolve(channel)
41+
})
42+
43+
channel.bind('pusher:subscription_error', (e) => {
44+
reject(e)
45+
})
46+
})
47+
48+
this.channel.bind('pplc-event', (data: string) => {
49+
const message: ServerSentPayloads = JSON.parse(data)
50+
51+
switch (message.type) {
52+
case 'joined': {
53+
const { roomId, layerIds, canvasSize } = message
54+
55+
const doc = Document.visu.createDocument(canvasSize)
56+
57+
layerIds.forEach((layerId: string, idx: number) => {
58+
const layer = Document.visu.createCanvasVisually({
59+
width: canvasSize.width,
60+
height: canvasSize.height,
61+
name: `Layer ${idx + 1}`,
62+
})
63+
64+
layer.uid = layerId
65+
doc.layerNodes.addLayerNode(layer)
66+
})
67+
68+
this.pplc!.loadDocument(doc)
69+
this.pplc!.setStrokingTarget([layerIds[0]])
70+
71+
console.info(`⚡ Joined room: ${roomId}`)
72+
break
73+
}
74+
case 'strokeComplete': {
75+
console.log('⚡ receive strokeComplete')
76+
const {
77+
uiStroke,
78+
targetLayerUid,
79+
brushSetting: strokeSettings,
80+
} = message
81+
82+
this.pplc!.putStrokeComplete(
83+
Object.assign(new UIStroke(), uiStroke),
84+
{
85+
pathToTargetVisu: [targetLayerUid],
86+
brushSetting: strokeSettings,
87+
},
88+
)
89+
break
90+
}
91+
}
92+
})
93+
94+
return new Promise<void>((resolve, reject) => {
95+
const onError = (e: Event) => {
96+
reject(e)
97+
}
98+
99+
// this.psr!.addEventListener('open', () => {
100+
// this.psr!.removeEventListener('error', onError)
101+
// resolve()
102+
// })
103+
104+
// this.psr!.addEventListener('error', onError)
105+
// })
106+
107+
// this.psr?.send(
108+
// serialize({
109+
// type: 'join',
110+
// }),
111+
// )
112+
})
113+
}
114+
115+
public putStrokeComplete(
116+
data: Omit<ClientSentPayloads.StrokeCompletePayload, 'type'>,
117+
) {
118+
this.psr?.send(
119+
serialize({
120+
type: 'strokeComplete',
121+
...data,
122+
}),
123+
)
124+
}
125+
}

pkgs/chat/src/client/websocketBackend.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { ClientSentPayloads } from '@/shared/client-sent-payloads'
22
import { ServerSentPayloads } from '@/shared/server-sent-payloads'
33
import { Document, Paplico, UIStroke } from '@paplico/core-new'
4+
import { IPaplicoChatBackend } from './IPaplicoChatBackend'
45

56
const serialize = (payload: ClientSentPayloads) => JSON.stringify(payload)
67

7-
export class PaplicoChatWebSocketBackend {
8+
export class PaplicoChatWebSocketBackend implements IPaplicoChatBackend {
89
protected ws: WebSocket | null = null
910
protected wsUrl: string
1011

@@ -48,7 +49,11 @@ export class PaplicoChatWebSocketBackend {
4849
}
4950
case 'strokeComplete': {
5051
console.log('⚡ receive strokeComplete')
51-
const { uiStroke, targetLayerUid, strokeSettings } = message
52+
const {
53+
uiStroke,
54+
targetLayerUid,
55+
brushSetting: strokeSettings,
56+
} = message
5257

5358
pap.putStrokeComplete(Object.assign(new UIStroke(), uiStroke), {
5459
targetLayerUid,
@@ -73,7 +78,7 @@ export class PaplicoChatWebSocketBackend {
7378
})
7479
}
7580

76-
public requestJoin(roomId?: string) {
81+
public async requestJoin(roomId?: string) {
7782
this.ws?.send(
7883
serialize({
7984
type: 'join',

pkgs/chat/src/server/main.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ export function startPaplicoChatServer({
8080
break
8181
}
8282
case 'strokeComplete': {
83-
const { uiStroke, targetLayerUid, strokeSettings } = request
83+
const {
84+
uiStroke,
85+
targetNode: targetLayerUid,
86+
strokeSettings,
87+
} = request
8488
const { roomId } = clients.get(ws) ?? {}
8589
if (roomId == null) return
8690

@@ -96,7 +100,7 @@ export function startPaplicoChatServer({
96100
type: 'strokeComplete',
97101
uiStroke,
98102
targetLayerUid,
99-
strokeSettings,
103+
brushSetting: strokeSettings,
100104
}),
101105
)
102106
}

pkgs/chat/src/shared/client-sent-payloads.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { Document } from '@paplico/core-new'
12
import { UIStrokeJSON } from './structs'
2-
import { VectorStrokeSetting } from '@paplico/core-new/dist/Document'
33

44
export type ClientSentPayloads =
55
| ClientSentPayloads.JoinRoomRequestPayload
@@ -14,7 +14,7 @@ export namespace ClientSentPayloads {
1414
export type StrokeCompletePayload = {
1515
type: 'strokeComplete'
1616
uiStroke: UIStrokeJSON
17-
strokeSettings: VectorStrokeSetting<any> | null
18-
targetLayerUid: string
17+
strokeSettings: Document.VisuFilter.Structs.BrushSetting | null
18+
targetNode: string[]
1919
}
2020
}

pkgs/chat/src/shared/server-sent-payloads.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { VectorStrokeSetting } from '@paplico/core-new/dist/Document'
1+
import { Document } from '@paplico/core-new'
22
import { UIStrokeJSON } from './structs'
33

44
export type ServerSentPayloads = RoomJoinedPayload | StrokeCompletePayload
@@ -13,6 +13,6 @@ export type RoomJoinedPayload = {
1313
export type StrokeCompletePayload = {
1414
type: 'strokeComplete'
1515
uiStroke: UIStrokeJSON
16-
strokeSettings: VectorStrokeSetting<any> | null
16+
brushSetting: Document.VisuFilter.StrokeFilter<any> | null
1717
targetLayerUid: string
1818
}

pkgs/core/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
"types": "./dist/index-math-utils.d.ts",
2727
"require": "./dist/math-utils.js"
2828
},
29+
"./expr-webgl": {
30+
"import": "./dist/expr-webgl.mjs",
31+
"types": "./dist/index-expr-webgl.d.ts",
32+
"require": "./dist/expr-webgl.js"
33+
},
2934
"./extras": {
3035
"import": "./dist/extras.mjs",
3136
"types": "./dist/index-extras.d.ts",

pkgs/core/src/Brushes/CircleBrush.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const CircleBrush = createBrush(
4747
brushSetting: { size, color, opacity, specific },
4848
destSize,
4949
}: BrushContext<CircleBrush.Settings>): Promise<BrushLayoutData> {
50-
const metrices: BrushLayoutData = []
50+
const metrices: BrushLayoutData[] = []
5151
const sp = mergeToNew(CircleBrush.getInitialSetting(), specific)
5252

5353
const bbox: BrushLayoutData['bbox'] = {
@@ -57,6 +57,8 @@ export const CircleBrush = createBrush(
5757
bottom: 0,
5858
}
5959

60+
ctx.beginPath()
61+
6062
ctx.translate(destSize.width / 2, destSize.height / 2)
6163
ctx.translate(transform.translate.x, transform.translate.y)
6264
ctx.scale(transform.scale.x, transform.scale.y)

pkgs/core/src/Commands/CommandGroup.ts

+15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
1+
import { PPLCCommandExecutionError } from '@/Errors'
12
import { ICommand } from '../Engine/History/ICommand'
23
import { DocumentContext } from '@/Engine'
34

45
export class CommandGroup implements ICommand {
56
public readonly name = 'CommandGroup'
67

78
protected commands: ICommand[] = []
9+
protected docx: DocumentContext | null = null
810

911
constructor(commands: ICommand[]) {
1012
this.commands = commands
1113
}
1214

15+
public async doAndAddCommand(command: ICommand) {
16+
if (!this.docx) {
17+
throw new PPLCCommandExecutionError(
18+
'CommandGroup must be execute before doAndAddCommand',
19+
)
20+
}
21+
22+
await command.do(this.docx)
23+
this.commands.push(command)
24+
}
25+
1326
public async do(docx: DocumentContext): Promise<void> {
27+
this.docx = docx
28+
1429
for (const command of this.commands) {
1530
await command.do(docx)
1631
}

pkgs/core/src/Commands/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ICommand } from '..'
2+
13
export { CanvasVisuUpdateBitmap } from './CanvasVisuUpdateBitmap'
24
export { VectorUpdateLayer } from './_VectorUpdateLayer'
35
export { VisuUpdateAttributes as VisuUpdateAttributes } from './VisuUpdateAttributes'
@@ -6,3 +8,5 @@ export { VectorVisuUpdateAttributes } from './VectorVisuUpdateAttributes'
68
export { DocumentManipulateLayerNodes } from './DocumentManipulateLayerNodes'
79
export { CommandGroup } from './CommandGroup'
810
export { VisuManipulateFilters } from './VisuManipulateFilters'
11+
12+
export type AnyCommand = ICommand

0 commit comments

Comments
 (0)