Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb50e2c0

Browse files
committed
support passing of messages to view
1 parentec2e0e0 commitb50e2c0

File tree

12 files changed

+161
-102
lines changed

12 files changed

+161
-102
lines changed

‎src/editor/ReactWebView.ts

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,10 @@ import * as vscode from 'vscode'
22
import*asCRfrom'typings'
33
import*aspathfrom'path'
44

5-
functiongetNonce():string{
6-
lettext=''
7-
constpossible='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
8-
for(leti=0;i<32;i++){
9-
text+=possible.charAt(Math.floor(Math.random()*possible.length))
10-
}
11-
returntext
12-
}
13-
14-
// TODO: move column into createOrShow
15-
16-
175
/**
186
* Manages React webview panels
197
*/
208
classReactWebView{
21-
/**
22-
* Track the currently panel. Only allow a single panel to exist at a time.
23-
*/
24-
publicstaticcurrentPanel:ReactWebView|undefined=undefined
25-
269
//@ts-ignore
2710
privatepanel:vscode.WebviewPanel
2811
privateextensionPath:string
@@ -32,53 +15,71 @@ class ReactWebView {
3215
publicconstructor(extensionPath:string,onReceive:any){
3316
this.extensionPath=extensionPath
3417
this.onReceive=onReceive
18+
19+
// Create and show a new webview panel
20+
this.panel=this.createWebviewPanel(vscode.ViewColumn.One)
21+
22+
// Set the webview's initial html content
23+
this.panel.webview.html=this.getHtmlForWebview()
24+
25+
// Listen for when the panel is disposed
26+
// This happens when the user closes the panel or when the panel is closed programatically
27+
this.panel.onDidDispose(()=>this.dispose(),null,this.disposables)
28+
29+
// Handle messages from the webview
30+
this.panel.webview.onDidReceiveMessage(this.onReceive,null,this.disposables)
31+
console.log('webview loaded')
3532
}
3633

37-
publicasynccreateOrShow(column:number=vscode.ViewColumn.One):Promise<void>{
34+
publicasynccreateOrShow(column:number):Promise<void>{
3835
// If we already have a panel, show it.
3936
// Otherwise, create a new panel.
40-
if(ReactWebView.currentPanel&&ReactWebView.currentPanel.panel){
41-
ReactWebView.currentPanel.panel.reveal(column)
37+
if(this.panel&&this.panel.webview){
38+
console.log('reveal')
39+
this.panel.reveal(column)
4240
}else{
43-
constviewType='CodeRoad'
44-
consttitle='CodeRoad'
45-
constconfig={
46-
// Enable javascript in the webview
47-
enableScripts:true,
48-
49-
// And restric the webview to only loading content from our extension's `media` directory.
50-
localResourceRoots:[vscode.Uri.file(path.join(this.extensionPath,'build'))],
41+
console.log('make new panel')
42+
this.panel=this.createWebviewPanel(column)
5143

52-
// prevents destroying the window when it is in the background
53-
retainContextWhenHidden:true,
54-
}
55-
// Create and show a new webview panel
56-
this.panel=vscode.window.createWebviewPanel(viewType,title,column,config)
57-
58-
// Set the webview's initial html content
59-
this.panel.webview.html=this.getHtmlForWebview()
44+
}
45+
}
6046

61-
// Listen for when the panel is disposed
62-
// This happens when the user closes the panel or when the panel is closed programatically
63-
this.panel.onDidDispose(()=>this.dispose(),null,this.disposables)
47+
privatecreateWebviewPanel(column:number):vscode.WebviewPanel{
48+
constviewType='CodeRoad'
49+
consttitle='CodeRoad'
50+
constconfig={
51+
// Enable javascript in the webview
52+
enableScripts:true,
53+
// And restric the webview to only loading content from our extension's `media` directory.
54+
localResourceRoots:[vscode.Uri.file(path.join(this.extensionPath,'build'))],
55+
// prevents destroying the window when it is in the background
56+
retainContextWhenHidden:true,
57+
}
58+
returnvscode.window.createWebviewPanel(viewType,title,column,config)
59+
}
6460

65-
// Handle messages from the webview
66-
this.panel.webview.onDidReceiveMessage(this.onReceive,null,this.disposables)
61+
privategetNonce():string{
62+
lettext=''
63+
constpossible='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
64+
for(leti=0;i<32;i++){
65+
text+=possible.charAt(Math.floor(Math.random()*possible.length))
6766
}
67+
returntext
6868
}
6969

7070
publicasyncpostMessage(action:CR.Action):Promise<void>{
71+
console.log('webview postMessage')
72+
console.log(action)
7173
// Send a message to the webview webview.
7274
// You can send any JSON serializable data.
7375
constsuccess=awaitthis.panel.webview.postMessage(action)
7476
if(!success){
7577
thrownewError(`Message post failure:${JSON.stringify(action)}`)
7678
}
79+
console.log('postMessage sent')
7780
}
7881

7982
publicdispose():void{
80-
ReactWebView.currentPanel=undefined
81-
8283
// Clean up our resources
8384
this.panel.dispose()
8485

@@ -108,9 +109,9 @@ class ReactWebView {
108109
conststyleUri=stylePathOnDisk.with({scheme:'vscode-resource'})
109110

110111
// Use a nonce to whitelist which scripts can be run
111-
constnonce=getNonce()
112-
constnonce2=getNonce()
113-
constnonce3=getNonce()
112+
constnonce=this.getNonce()
113+
constnonce2=this.getNonce()
114+
constnonce3=this.getNonce()
114115

115116
return`<!DOCTYPE html>
116117
<html lang="en">

‎src/editor/commands/index.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,65 @@ import * as CR from 'typings'
66

77
constCOMMANDS={
88
START:'coderoad.start',
9+
NEW_OR_CONTINUE:'coderoad.new_or_continue',
910
OPEN_WEBVIEW:'coderoad.open_webview',
11+
SEND_STATE:'coderoad.send_state',
1012
OPEN_FILE:'coderoad.open_file',
1113
RUN_TEST:'coderoad.test_run',
1214
}
1315

1416
interfaceCreateCommandProps{
1517
context:vscode.ExtensionContext,
16-
machine:CR.StateMachine
18+
machine:CR.StateMachine,
19+
storage:any,
20+
git:any
1721
}
1822

1923
// React panel webview
2024
letwebview:any;
25+
letinitialTutorial:CR.Tutorial|undefined
26+
letinitialProgress:CR.Progress={
27+
levels:{},
28+
stages:{},
29+
steps:{},
30+
complete:false,
31+
}
2132

22-
exportconstcreateCommands=({ context, machine}:CreateCommandProps)=>({
33+
exportconstcreateCommands=({ context, machine, storage, git}:CreateCommandProps)=>({
34+
// initialize
2335
[COMMANDS.START]:()=>{
2436
// set local storage workspace
2537
setStorage(context.workspaceState)
2638

2739
// activate machine
2840
webview=newReactWebView(context.extensionPath,machine.onReceive)
41+
console.log('webview',webview.panel.webview.postMessage)
2942
machine.activate()
3043
},
31-
[COMMANDS.OPEN_WEBVIEW]:()=>{
32-
webview.createOrShow();
44+
[COMMANDS.NEW_OR_CONTINUE]:async()=>{
45+
// verify that the user has a tutorial & progress
46+
// verify git is setup with a coderoad remote
47+
const[tutorial,progress,hasGit,hasGitRemote]=awaitPromise.all([
48+
storage.getTutorial(),
49+
storage.getProgress(),
50+
git.gitVersion(),
51+
git.gitCheckRemoteExists(),
52+
])
53+
initialTutorial=tutorial
54+
initialProgress=progress
55+
constcanContinue=!!(tutorial&&progress&&hasGit&&hasGitRemote)
56+
console.log('canContinue',canContinue)
57+
// if a tutorial exists, "CONTINUE"
58+
// otherwise start from "NEW"
59+
machine.send(canContinue ?'CONTINUE' :'NEW')
60+
},
61+
// open React webview
62+
[COMMANDS.OPEN_WEBVIEW]:(column:number=vscode.ViewColumn.One)=>{
63+
webview.createOrShow(column);
3364
},
65+
// open a file
3466
[COMMANDS.OPEN_FILE]:async(relativeFilePath:string)=>{
67+
console.log(`OPEN_FILE${JSON.stringify(relativeFilePath)}`)
3568
try{
3669
constworkspaceRoot=vscode.workspace.rootPath
3770
if(!workspaceRoot){
@@ -43,5 +76,17 @@ export const createCommands = ({ context, machine }: CreateCommandProps) => ({
4376
}catch(error){
4477
console.log(`Failed to open file${relativeFilePath}`,error)
4578
}
79+
},
80+
// send messages to webview
81+
[COMMANDS.SEND_STATE]:(action:CR.Action)=>{
82+
console.log(`SEND${JSON.stringify(action)}`)
83+
console.log('webview')
84+
console.log(webview)
85+
// console.log(webview.currentPanel)
86+
// if (!webview || !webview.currentPanel) {
87+
// throw new Error('No valid panel available')
88+
// }
89+
webview.postMessage(action)
90+
4691
}
4792
})

‎src/editor/commands/start.ts

Lines changed: 0 additions & 45 deletions
This file was deleted.

‎src/editor/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import*asvscodefrom'vscode'
22
import*asCRfrom'typings'
33
import{createCommands}from'./commands'
4+
import*asstoragefrom'../services/storage'
5+
import*asgitfrom'../services/git'
46

57
interfaceProps{
68
machine:CR.StateMachine,
@@ -29,6 +31,8 @@ class Editor {
2931
constcommands=createCommands({
3032
context:this.context,
3133
machine:this.machine,
34+
storage,
35+
git,
3236
})
3337
for(constcmdincommands){
3438
constcommand:vscode.Disposable=vscode.commands.registerCommand(cmd,commands[cmd])
@@ -53,6 +57,11 @@ class Editor {
5357
// shut down state machine
5458
this.machine.deactivate()
5559
}
60+
61+
// execute vscode command
62+
publicdispatch=(type:string,payload:any)=>{
63+
vscode.commands.executeCommand(type,payload)
64+
}
5665
}
5766

5867
exportdefaultEditor

‎src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { setWorkspaceRoot } from './services/node'
22
importStateMachinefrom'./state'
33
importEditorfrom'./editor'
44

5+
56
// state machine that governs application logic
67
exportconstmachine=newStateMachine()
78

‎src/services/git/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export async function gitLoadCommits(actions: CR.TutorialAction): Promise<void>
4141

4242
if(files){
4343
for(constfilePathoffiles){
44-
vscode.commands.executeCommand('coderoad.open_webview',filePath)
44+
vscode.commands.executeCommand('coderoad.open_file',filePath)
4545
}
4646
}
4747
}

‎src/state/actions/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,8 @@ export default {
4848
createWebview(){
4949
console.log('execute coderoad.open_webview')
5050
vscode.commands.executeCommand('coderoad.open_webview')
51+
},
52+
newOrContinue(){
53+
vscode.commands.executeCommand('coderoad.new_or_continue')
5154
}
5255
}

‎src/state/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import{interpret,Interpreter}from'xstate'
2-
import*asCRfrom'../typings'
2+
import*asCRfrom'typings'
33
importmachinefrom'./machine'
4+
import*asvscodefrom'vscode'
45

56
// machine interpreter
67
// https://xstate.js.org/docs/guides/interpretation.html
@@ -17,9 +18,11 @@ class StateMachine {
1718
this.service=interpret(machine,this.machineOptions)
1819
// logging
1920
.onTransition(state=>{
21+
console.log('onTransition',state.changed)
2022
if(state.changed){
2123
console.log('next state')
2224
console.log(state.value)
25+
vscode.commands.executeCommand('coderoad.send_state',state.value)
2326
}
2427
})
2528
}
@@ -30,6 +33,11 @@ class StateMachine {
3033
deactivate(){
3134
this.service.stop()
3235
}
36+
send(action:string|CR.Action){
37+
console.log('machine.send')
38+
console.log(action)
39+
this.service.send(action)
40+
}
3341
onReceive(action:CR.Action){
3442
console.log('RECEIVED ACTION')
3543
console.log(action)

‎src/state/machine.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@ export const machine = Machine<
1616
initial:'SelectTutorial',
1717
states:{
1818
SelectTutorial:{
19+
onEntry:['createWebview'],
1920
initial:'Initial',
2021
states:{
2122
Initial:{
22-
onEntry:['createWebview'],
23+
after:{
24+
1000:'Startup'
25+
}
26+
},
27+
Startup:{
28+
onEntry:['newOrContinue'],
2329
on:{
2430
CONTINUE:'ContinueTutorial',
2531
NEW:'NewTutorial',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp