mirror of
https://github.com/open-scratch/easy-scratch3.git
synced 2024-11-25 16:36:03 +08:00
云变量接口
This commit is contained in:
parent
8deb5b52f2
commit
80532795cd
13
README-EN.md
13
README-EN.md
@ -70,6 +70,16 @@ window.scratchConfig = {
|
||||
enable: true, // enable backpack
|
||||
api: "/api/teaching/scratch/backpack", //backpack API
|
||||
},
|
||||
cloudData:{
|
||||
enable: true, //enable cloud data
|
||||
id: "create", //default cloud data ID
|
||||
api: "127.0.0.1:1234/api/websocket/scratch/cloudData" //cloud data API
|
||||
},
|
||||
projectInfo: {//project info
|
||||
projectName: "",
|
||||
authorUsername: "admin",
|
||||
authorAvatar: './static/avatar.png',
|
||||
},
|
||||
logo: {
|
||||
show: true, //is visible
|
||||
url: "./static/logo.png", //logo url, support base64 images
|
||||
@ -349,6 +359,9 @@ window.scratch.pushSoundLibrary(
|
||||
)
|
||||
```
|
||||
|
||||
#### set cloud data ID
|
||||
`window.scratch.setCloudId(id)`
|
||||
|
||||
# Appendix
|
||||
|
||||
## block catagory code
|
||||
|
13
README.md
13
README.md
@ -78,6 +78,16 @@ https://www.213.name/archives/1739
|
||||
enable: true, // 是否启用背包
|
||||
api: "/api/teaching/scratch/backpack", //背包API接口
|
||||
},
|
||||
cloudData:{
|
||||
enable: true, //是否开启云变量功能
|
||||
id: "create", //默认云变量ID,可使用window.scratch.setCloudId更换ID
|
||||
api: "127.0.0.1:1234/api/websocket/scratch/cloudData" //云变量API地址
|
||||
},
|
||||
projectInfo: {//作品信息
|
||||
projectName: "",
|
||||
authorUsername: "admin",
|
||||
authorAvatar: './static/avatar.png',
|
||||
},
|
||||
logo: {
|
||||
show: true, //是否显示
|
||||
url: "./static/logo.png", //logo地址,支持base64图片
|
||||
@ -367,6 +377,9 @@ window.scratch.pushSoundsLibrary(
|
||||
)
|
||||
```
|
||||
|
||||
#### 设置云变量ID
|
||||
`window.scratch.setCloudId(id)`
|
||||
|
||||
# 附录
|
||||
|
||||
## Scratch项目结构
|
||||
|
@ -74,7 +74,6 @@ const GUIComponent = props => {
|
||||
canSave,
|
||||
canCreateCopy,
|
||||
canShare,
|
||||
canUseCloud,
|
||||
children,
|
||||
connectionModalVisible,
|
||||
costumeLibraryVisible,
|
||||
@ -300,7 +299,6 @@ const GUIComponent = props => {
|
||||
<TabPanel className={tabClassNames.tabPanel}>
|
||||
<Box className={styles.blocksWrapper}>
|
||||
<Blocks
|
||||
canUseCloud={canUseCloud}
|
||||
grow={1}
|
||||
isVisible={blocksTabVisible}
|
||||
options={{
|
||||
@ -381,7 +379,6 @@ GUIComponent.propTypes = {
|
||||
canRemix: PropTypes.bool,
|
||||
canSave: PropTypes.bool,
|
||||
canShare: PropTypes.bool,
|
||||
canUseCloud: PropTypes.bool,
|
||||
cardsVisible: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
costumeLibraryVisible: PropTypes.bool,
|
||||
@ -437,7 +434,6 @@ GUIComponent.defaultProps = {
|
||||
canSave: false,
|
||||
canCreateCopy: false,
|
||||
canShare: false,
|
||||
canUseCloud: false,
|
||||
enableCommunity: false,
|
||||
isCreating: false,
|
||||
isShared: false,
|
||||
|
@ -822,8 +822,8 @@ const mapStateToProps = (state, ownProps) => {
|
||||
loginMenuOpen: loginMenuOpen(state),
|
||||
projectTitle: state.scratchGui.projectTitle,
|
||||
sessionExists: state.session && typeof state.session.session !== 'undefined',
|
||||
username: window.scratchConfig.menuBar.userAvatar.username || '',
|
||||
avatar: window.scratchConfig.menuBar.userAvatar.avatar || null,
|
||||
username: window.scratchConfig.session.username || '',
|
||||
avatar: window.scratchConfig.session.avatar || null,
|
||||
onAvatarClick: window.scratchConfig.menuBar.userAvatar.handleClick,
|
||||
userOwnsProject: ownProps.authorUsername && user &&
|
||||
(ownProps.authorUsername === user.username),
|
||||
|
@ -38,6 +38,7 @@ const PromptComponent = props => (
|
||||
className={styles.modalContent}
|
||||
contentLabel={props.title}
|
||||
onRequestClose={props.onCancel}
|
||||
id={"cloudData"}
|
||||
>
|
||||
<Box className={styles.body}>
|
||||
<Box className={styles.label}>
|
||||
|
@ -465,7 +465,7 @@ class Blocks extends React.Component {
|
||||
optVarType !== this.ScratchBlocks.BROADCAST_MESSAGE_VARIABLE_TYPE &&
|
||||
p.prompt.title !== this.ScratchBlocks.Msg.RENAME_VARIABLE_MODAL_TITLE &&
|
||||
p.prompt.title !== this.ScratchBlocks.Msg.RENAME_LIST_MODAL_TITLE;
|
||||
p.prompt.showCloudOption = (optVarType === this.ScratchBlocks.SCALAR_VARIABLE_TYPE) && this.props.canUseCloud;
|
||||
p.prompt.showCloudOption = (optVarType === this.ScratchBlocks.SCALAR_VARIABLE_TYPE) && window.scratchConfig.cloudData.enable;
|
||||
this.setState(p);
|
||||
}
|
||||
handleConnectionModalStart (extensionId) {
|
||||
@ -512,7 +512,6 @@ class Blocks extends React.Component {
|
||||
/* eslint-disable no-unused-vars */
|
||||
const {
|
||||
anyModalVisible,
|
||||
canUseCloud,
|
||||
customProceduresVisible,
|
||||
extensionLibraryVisible,
|
||||
options,
|
||||
@ -575,7 +574,6 @@ class Blocks extends React.Component {
|
||||
|
||||
Blocks.propTypes = {
|
||||
anyModalVisible: PropTypes.bool,
|
||||
canUseCloud: PropTypes.bool,
|
||||
customProceduresVisible: PropTypes.bool,
|
||||
extensionLibraryVisible: PropTypes.bool,
|
||||
isRtl: PropTypes.bool,
|
||||
|
@ -164,6 +164,7 @@ class GUI extends React.Component {
|
||||
/* eslint-disable no-unused-vars */
|
||||
assetHost,
|
||||
cloudHost,
|
||||
cloudId,
|
||||
error,
|
||||
isError,
|
||||
isScratchDesktop,
|
||||
@ -196,6 +197,7 @@ GUI.propTypes = {
|
||||
assetHost: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
cloudHost: PropTypes.string,
|
||||
cloudId: PropTypes.string,
|
||||
error: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
||||
fetchingProject: PropTypes.bool,
|
||||
intl: intlShape,
|
||||
|
@ -179,19 +179,20 @@ const alerts = [
|
||||
description="Info about cloud variable limitations"
|
||||
id="gui.alerts.cloudInfo"
|
||||
values={{
|
||||
learnMoreLink: (
|
||||
<a
|
||||
href="https://scratch.mit.edu/info/faq/#clouddata"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Learn more."
|
||||
description="Link text to cloud var faq"
|
||||
id="gui.alerts.cloudInfoLearnMore"
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
learnMoreLink: ""
|
||||
// (
|
||||
// <a
|
||||
// href="https://scratch.mit.edu/info/faq/#clouddata"
|
||||
// rel="noopener noreferrer"
|
||||
// target="_blank"
|
||||
// >
|
||||
// <FormattedMessage
|
||||
// defaultMessage="Learn more."
|
||||
// description="Link text to cloud var faq"
|
||||
// id="gui.alerts.cloudInfoLearnMore"
|
||||
// />
|
||||
// </a>
|
||||
// )
|
||||
}}
|
||||
/>
|
||||
),
|
||||
|
@ -28,6 +28,55 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
'handleCloudDataUpdate'
|
||||
]);
|
||||
|
||||
this.enable = window.scratchConfig && window.scratchConfig.cloudData && window.scratchConfig.cloudData.enable || false
|
||||
this.token = window.scratchConfig && window.scratchConfig.session && window.scratchConfig.session.token,
|
||||
this.username = window.scratchConfig && window.scratchConfig.session && window.scratchConfig.session.username || '';
|
||||
this.authorUsername = window.scratchConfig && window.scratchConfig.projectInfo && window.scratchConfig.projectInfo.authorUsername,
|
||||
this.cloudId = window.scratchConfig && window.scratchConfig.cloudData && window.scratchConfig.cloudData.id
|
||||
this.cloudHost = window.scratchConfig && window.scratchConfig.cloudData && window.scratchConfig.cloudData.api
|
||||
|
||||
|
||||
//动态设置是否开启云变量
|
||||
let that = this
|
||||
document.addEventListener("setEnableCouldData",function(e){
|
||||
that.enable = e.detail.enable;
|
||||
window.scratchConfig.cloudData.enable = e.detail.enable;
|
||||
that.handleCloudDataUpdate(that.enable)
|
||||
})
|
||||
|
||||
window.scratch.setEnableCouldData = function(enable){
|
||||
var event = new CustomEvent('setEnableCouldData', {"detail": {enable: enable}});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
//动态设置cloudId
|
||||
document.addEventListener("setCloudId",function(e){
|
||||
if(that.cloudId != e.detail.id){
|
||||
window.scratchConfig.cloudData.id = e.detail.id;
|
||||
that.cloudId = e.detail.id;
|
||||
that.handleCloudDataUpdate(that.enable)
|
||||
}
|
||||
})
|
||||
|
||||
window.scratch.setCloudId = function(id){
|
||||
var event = new CustomEvent('setCloudId', {"detail": {id: id}});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
//设置authorUsername
|
||||
document.addEventListener("setAuthorUsername",function(e){
|
||||
if(that.authorUsername != e.detail.authorUsername){
|
||||
window.scratchConfig.projectInfo.authorUsername = e.detail.authorUsername;
|
||||
that.authorUsername = e.detail.authorUsername;
|
||||
that.handleCloudDataUpdate(that.enable)
|
||||
}
|
||||
})
|
||||
|
||||
window.scratch.setAuthorUsername = function(authorUsername){
|
||||
var event = new CustomEvent('setAuthorUsername', {"detail": {authorUsername: authorUsername}});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
this.props.vm.on('HAS_CLOUD_DATA_UPDATE', this.handleCloudDataUpdate);
|
||||
}
|
||||
componentDidMount () {
|
||||
@ -52,14 +101,25 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
this.disconnectFromCloud();
|
||||
}
|
||||
canUseCloud (props) {
|
||||
return !!(props.cloudHost && props.username && props.vm && props.projectId && props.hasCloudPermission);
|
||||
// return !!(props.cloudHost && props.username && props.vm && props.projectId && props.hasCloudPermission);
|
||||
// console.log(props.vm);
|
||||
// console.log(props.projectId);
|
||||
// console.log(props.hasCloudPermission);
|
||||
return this.enable;
|
||||
}
|
||||
shouldConnect (props) {
|
||||
return !this.isConnected() && this.canUseCloud(props) &&
|
||||
props.isShowingWithId && props.vm.runtime.hasCloudData() &&
|
||||
props.canModifyCloudData;
|
||||
shouldConnect (props) {
|
||||
console.log("should connnet");
|
||||
console.log(this.enable);
|
||||
console.log(props.vm.runtime.hasCloudData());
|
||||
// return !this.isConnected() && this.canUseCloud(props) &&
|
||||
// props.isShowingWithId && props.vm.runtime.hasCloudData() &&
|
||||
// props.canModifyCloudData;
|
||||
//如果开启了云变量,且项目包含云变量
|
||||
return this.enable && props.vm.runtime.hasCloudData();
|
||||
}
|
||||
shouldDisconnect (props, prevProps) {
|
||||
//如果关闭了云变量,且项目不包含云变量
|
||||
return !this.canUseCloud(props)||!props.vm.runtime.hasCloudData();
|
||||
return this.isConnected() &&
|
||||
( // Can no longer use cloud or cloud provider info is now stale
|
||||
!this.canUseCloud(props) ||
|
||||
@ -75,10 +135,11 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
}
|
||||
connectToCloud () {
|
||||
this.cloudProvider = new CloudProvider(
|
||||
this.props.cloudHost,
|
||||
this.cloudHost,
|
||||
this.props.vm,
|
||||
this.props.username,
|
||||
this.props.projectId);
|
||||
this.authorUsername,
|
||||
this.token,
|
||||
this.cloudId);
|
||||
this.props.vm.setCloudProvider(this.cloudProvider);
|
||||
}
|
||||
disconnectFromCloud () {
|
||||
@ -100,9 +161,8 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
const {
|
||||
/* eslint-disable no-unused-vars */
|
||||
canModifyCloudData,
|
||||
cloudHost,
|
||||
projectId,
|
||||
username,
|
||||
// username,
|
||||
hasCloudPermission,
|
||||
isShowingWithId,
|
||||
onShowCloudInfo,
|
||||
@ -112,7 +172,6 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
} = this.props;
|
||||
return (
|
||||
<WrappedComponent
|
||||
canUseCloud={this.canUseCloud(this.props)}
|
||||
vm={vm}
|
||||
{...componentProps}
|
||||
/>
|
||||
@ -122,20 +181,16 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
|
||||
CloudManager.propTypes = {
|
||||
canModifyCloudData: PropTypes.bool.isRequired,
|
||||
cloudHost: PropTypes.string,
|
||||
hasCloudPermission: PropTypes.bool,
|
||||
isShowingWithId: PropTypes.bool.isRequired,
|
||||
onShowCloudInfo: PropTypes.func,
|
||||
projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
username: PropTypes.string,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
|
||||
CloudManager.defaultProps = {
|
||||
cloudHost: null,
|
||||
hasCloudPermission: false,
|
||||
onShowCloudInfo: () => {},
|
||||
username: null
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
@ -144,7 +199,7 @@ const cloudManagerHOC = function (WrappedComponent) {
|
||||
isShowingWithId: getIsShowingWithId(loadingState),
|
||||
projectId: state.scratchGui.projectState.projectId,
|
||||
// if you're editing someone else's project, you can't modify cloud data
|
||||
canModifyCloudData: (!state.scratchGui.mode.hasEverEnteredEditor || ownProps.canSave)
|
||||
canModifyCloudData: (!state.scratchGui.mode.hasEverEnteredEditor || ownProps.canSave),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -13,9 +13,10 @@ class CloudProvider {
|
||||
* @param {string} projectId The id associated with the project containing
|
||||
* cloud data.
|
||||
*/
|
||||
constructor (cloudHost, vm, username, projectId) {
|
||||
constructor (cloudHost, vm, username, token, projectId) {
|
||||
this.vm = vm;
|
||||
this.username = username;
|
||||
this.token = token;
|
||||
this.projectId = projectId;
|
||||
this.cloudHost = cloudHost;
|
||||
|
||||
@ -113,6 +114,10 @@ class CloudProvider {
|
||||
value: message.value
|
||||
};
|
||||
break;
|
||||
}
|
||||
//初始化云变量
|
||||
case 'init': {
|
||||
|
||||
}
|
||||
}
|
||||
return varData;
|
||||
@ -130,6 +135,7 @@ class CloudProvider {
|
||||
msg.method = methodName;
|
||||
msg.user = this.username;
|
||||
msg.project_id = this.projectId;
|
||||
msg.token = this.token
|
||||
|
||||
// Optional string params can use simple falsey undefined check
|
||||
if (dataName) msg.name = dataName;
|
||||
@ -221,6 +227,7 @@ class CloudProvider {
|
||||
this.connection = null;
|
||||
this.vm = null;
|
||||
this.username = null;
|
||||
this.token = null;
|
||||
this.projectId = null;
|
||||
if (this._connectionTimeout) {
|
||||
clearTimeout(this._connectionTimeout);
|
||||
|
@ -25,6 +25,16 @@
|
||||
enable: true, // 是否启用背包
|
||||
api: "/api/teaching/scratch/backpack", //背包API接口
|
||||
},
|
||||
cloudData:{
|
||||
enable: true, //是否开启云变量功能
|
||||
id: "create", //默认云变量ID,可使用window.scratch.setCloudId更换ID
|
||||
api: "127.0.0.1:1234/api/websocket/scratch/cloudData" //云变量API地址
|
||||
},
|
||||
projectInfo: {//作品信息
|
||||
projectName: "",
|
||||
authorUsername: "admin",
|
||||
authorAvatar: './static/avatar.png',
|
||||
},
|
||||
logo: {
|
||||
show: true, //是否显示
|
||||
url: window.location.protocol+"//"+window.location.host + "/static/logo.png", //logo地址,支持base64图片
|
||||
@ -194,6 +204,21 @@
|
||||
},
|
||||
}
|
||||
|
||||
//api
|
||||
/**
|
||||
* window.scratch.loadPorject(url, callback)
|
||||
* window.scratch.getProjectFile(callback(file))
|
||||
* window.scratch.getProjectCover(callback(file))
|
||||
* window.scratch.getProjectName()
|
||||
* window.scratch.setProjectName(projectName)
|
||||
* window.scratch.setPlayerOnly(isPlayerOnly)
|
||||
* window.scratch.setFullScreen(isFullScreen)
|
||||
*
|
||||
* window.scratch.setEnableCouldData(isEnable) //设置是否开启云变量(会开启或关闭当前连接)
|
||||
* window.scratch.setCloudId(id) //设置云变量ID(会触发一次重连)
|
||||
* window.scratch.setAuthorUsername(authorUsername) //设置作者用户名
|
||||
* window.vm.runtime.hasCloudData() //是否包含云变量
|
||||
*/
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
@ -23,6 +23,10 @@ const handleTelemetryModalOptOut = () => {
|
||||
log('User opted out of telemetry');
|
||||
};
|
||||
|
||||
const onVmInit = (vm) =>{
|
||||
console.log("scratch vm init");
|
||||
console.log(vm);
|
||||
}
|
||||
/*
|
||||
* Render the GUI playground. This is a separate function because importing anything
|
||||
* that instantiates the VM causes unsupported browsers to crash
|
||||
@ -46,6 +50,8 @@ export default appTarget => {
|
||||
const backpackShow = window.scratchConfig.session && window.scratchConfig.session.token
|
||||
&& window.scratchConfig && window.scratchConfig.backpack && window.scratchConfig.backpack.enable
|
||||
|| false
|
||||
const cloudHost = window.scratchConfig && window.scratchConfig.cloudData && window.scratchConfig.cloudData.api
|
||||
|
||||
|
||||
const scratchDesktopMatches = window.location.href.match(/[?&]isScratchDesktop=([^&]+)/);
|
||||
let simulateScratchDesktop;
|
||||
@ -82,7 +88,11 @@ export default appTarget => {
|
||||
backpackVisible={backpackShow}
|
||||
// showComingSoon
|
||||
backpackApi={backpackApi}
|
||||
// canUseCloud={canUseCloud}
|
||||
hasCloudPermission={true}
|
||||
|
||||
canSave={false}
|
||||
onVmInit={onVmInit}
|
||||
onClickLogo={onClickLogo}
|
||||
/>,
|
||||
appTarget);
|
||||
|
Loading…
Reference in New Issue
Block a user