scratch3.0 scratch-gui中集成自定义用户系统1(第四章)

2024-03-15 16:38

本文主要是介绍scratch3.0 scratch-gui中集成自定义用户系统1(第四章),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

scratch3.0系列章节列表

scratch3.0二次开发scratch3.0基本介绍(第一章)

scratch3.0二次开发运行scratch-gui项目并了解工程结构(第二章)

scratch3.0二次自定义品牌logo(第三章)

scratch3.0 scratch-gui中集成自定义用户系统1(第四章)

scratch3.0 scratch-gui中集成自定义用户系统2(第五章)

scratch3.0 scratch-gui中集成自定义用户系统3(第六章)

scratch3.0 scratch-gui中集成自定义用户系统4(第七章)

scratch3.0 scratch-gui中集成自定义用户系统5(第八章)

scratch3.0 scratch-gui中集成自定义用户系统6(第九章)

scratch3.0 scratch-gui中集成作品系统1(第九章)

scratch3.0 scratch-gui中集成作品系统2(第十章)

scratch3.0 scratch-gui中集成作品系统3(第十一章)

scratch3.0 scratch-gui加载自定义初始化角色(第十二章)

scratch3.0 scratch-gui打开自己平台云端作品(第十三章)

写在前面

该系列文章是为具有开发能力的朋友写作的,目的是帮助他们在刮擦3.0的基础上开发一套完整的集刮擦3.0编程工具,用户社区和作品云端存储及分享,品牌集成于一体的刮擦编程平台。如果您不是开发者,但想要拥有自己的教育平台和品牌,也欢迎学习交流和洽谈合作。

所以如果您是想学习scratch少儿编程课程,那请忽略该系列的文章。

 

前言

前面我们将scratch-gui工程成功建造运行起来,并且成功植入了我们的品牌徽标,这让我们对整个项目有了初步的认识。

现在我们已经有了scratch编程工具,但是我们还剩下两个主要的后台,用户社区后台和GUI的存储后台。目前Scratch3.0团队还没有发现社区替换和GUI的存储部分是否有开源计划,考虑到Scratch2.0的重新初始化开源,3.0社区初始化开源的可能也不大。

 

scratch-www项目提供了用户社区的功能,但是需要通过接口去分析它的后台的数据存储的结构,我觉得比较麻烦,不如我们自己来开发一个,集成到我们的编程工具scratch-gui中。

所以接下来我们的工作是自己来提供相关的两个前提平台,并与GUI集成到一起。

 

约会用户登录状态

我们先一步一步来,先做一个比较简单的用户系统,再一步一步迭代。

 

这一章,我们先来改造一下前面的scratch-gui,约会用户登录状态的检测。

在进入项目时,检测用户是否登录,如果用户未登录,则在右上角显示登录按钮,否则显示用户头像和姓名等基本信息。

 

先在reduser目录中创建user-state.js文件,用作记录用户的信息。

添加如下内容:

import keyMirror from 'keymirror';const UserState = keyMirror({    NOT_LOGINED: null,    LOGINED: null});const UserStates = Object.keys(UserState)const initialState = {    error: null,    userData: null,    loginState: UserState.NOT_LOGINED};const getIsLogined = loginState => (    loginState === UserState.LOGINED);const reducer = function (state, action) {    if (typeof state === 'undefined') state = initialState;}export {    reducer as default,    initialState as userStateInitialState,    UserState,    UserStates,    getIsLogined};

reducers/gui.js中,作为项目的用户相关的初始化信息。

在reducer/gui.js中日期用户状态:

​​​

import userStateReducer, {userStateInitialState} from './user-state';```加入到initialState中:```const guiInitialState = {    alerts: alertsInitialState,    assetDrag: assetDragInitialState,    blockDrag: blockDragInitialState,    cards: cardsInitialState,    colorPicker: colorPickerInitialState,    connectionModal: connectionModalInitialState,    customProcedures: customProceduresInitialState,    editorTab: editorTabInitialState,    mode: modeInitialState,    hoveredTarget: hoveredTargetInitialState,    stageSize: stageSizeInitialState,    menus: menuInitialState,    micIndicator: micIndicatorInitialState,    modals: modalsInitialState,    monitors: monitorsInitialState,    monitorLayout: monitorLayoutInitialState,    projectChanged: projectChangedInitialState,    projectState: projectStateInitialState,    projectTitle: projectTitleInitialState,    fontsLoaded: fontsLoadedInitialState,    restoreDeletion: restoreDeletionInitialState,    targets: targetsInitialState,    timeout: timeoutInitialState,    toolbox: toolboxInitialState,    vm: vmInitialState,    vmStatus: vmStatusInitialState,    userState: userStateInitialState};```将reducer加入到guiReducer中:```const guiReducer = combineReducers({    alerts: alertsReducer,    assetDrag: assetDragReducer,    blockDrag: blockDragReducer,    cards: cardsReducer,    colorPicker: colorPickerReducer,    connectionModal: connectionModalReducer,    customProcedures: customProceduresReducer,    editorTab: editorTabReducer,    mode: modeReducer,    hoveredTarget: hoveredTargetReducer,    stageSize: stageSizeReducer,    menus: menuReducer,    micIndicator: micIndicatorReducer,    modals: modalReducer,    monitors: monitorReducer,    monitorLayout: monitorLayoutReducer,    projectChanged: projectChangedReducer,    projectState: projectStateReducer,    projectTitle: projectTitleReducer,    fontsLoaded: fontsLoadedReducer,    restoreDeletion: restoreDeletionReducer,    targets: targetReducer,    timeout: timeoutReducer,    toolbox: toolboxReducer,    vm: vmReducer,    vmStatus: vmStatusReducer,    userState: userStateReducer});

下面去container / gui.jsx中为里面定义的GUI Component添加loginState这个道具,使用标识用户是否登录:

GUI.propTypes = {    assetHost: PropTypes.string,    children: PropTypes.node,    cloudHost: PropTypes.string,    error: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),    fetchingProject: PropTypes.bool,    intl: intlShape,    isError: PropTypes.bool,    isLoading: PropTypes.bool,    isScratchDesktop: PropTypes.bool,    isShowingProject: PropTypes.bool,    loadingStateVisible: PropTypes.bool,    onProjectLoaded: PropTypes.func,    onSeeCommunity: PropTypes.func,    onStorageInit: PropTypes.func,    onUpdateProjectId: PropTypes.func,    onUpdateProjectTitle: PropTypes.func,    onUpdateReduxProjectTitle: PropTypes.func,    onVmInit: PropTypes.func,    projectHost: PropTypes.string,    projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),    projectTitle: PropTypes.string,    telemetryModalVisible: PropTypes.bool,    vm: PropTypes.instanceOf(VM).isRequired,    loginState: PropTypes.bool};

这个`loginState`道具的状态值来自于user-state.js中getIsLogined中检测当前的loginState(指状态中的)是否等于UserState.LOGINED:

const mapStateToProps = state => {    const loadingState = state.scratchGui.projectState.loadingState;    const loginState = state.scratchGui.userState.loginState;    return {        activeTabIndex: state.scratchGui.editorTab.activeTabIndex,        alertsVisible: state.scratchGui.alerts.visible,        backdropLibraryVisible: state.scratchGui.modals.backdropLibrary,        blocksTabVisible: state.scratchGui.editorTab.activeTabIndex === BLOCKS_TAB_INDEX,        cardsVisible: state.scratchGui.cards.visible,        connectionModalVisible: state.scratchGui.modals.connectionModal,        costumeLibraryVisible: state.scratchGui.modals.costumeLibrary,        costumesTabVisible: state.scratchGui.editorTab.activeTabIndex === COSTUMES_TAB_INDEX,        error: state.scratchGui.projectState.error,        isError: getIsError(loadingState),        isFullScreen: state.scratchGui.mode.isFullScreen,        isPlayerOnly: state.scratchGui.mode.isPlayerOnly,        isRtl: state.locales.isRtl,        isShowingProject: getIsShowingProject(loadingState),        loadingStateVisible: state.scratchGui.modals.loadingProject,        projectId: state.scratchGui.projectState.projectId,        soundsTabVisible: state.scratchGui.editorTab.activeTabIndex === SOUNDS_TAB_INDEX,        targetIsStage: (            state.scratchGui.targets.stage &&            state.scratchGui.targets.stage.id === state.scratchGui.targets.editingTarget        ),        telemetryModalVisible: state.scratchGui.modals.telemetryModal,        tipsLibraryVisible: state.scratchGui.modals.tipsLibrary,        vm: state.scratchGui.vm,        loginState: getIsLogined(loginState)    };};

现在container / gui.jsx中定义的Component GUI具有登录状态属性了,我们要把它传到menu-bar中,因为我们要在menu-bar中去控制右上角的显示状态。

 

在这个GUI组件中使用了components / gui / gui.jsx定义的GUIComponent这个组件,GUIComponent定义了整个项目的基本样式结构中,可以找到对MenuBar的使用。

 

首先,在GUIComponent的定义中日期之前定义的`loginState`:

const GUIComponent = props => {    const {        accountNavOpen,        activeTabIndex,        alertsVisible,        authorId,        authorThumbnailUrl,        authorUsername,        basePath,        backdropLibraryVisible,        backpackHost,        backpackVisible,        blocksTabVisible,        cardsVisible,        canCreateNew,        canEditTitle,        canRemix,        canSave,        canCreateCopy,        canShare,        canUseCloud,        children,        connectionModalVisible,        costumeLibraryVisible,        costumesTabVisible,        enableCommunity,        intl,        isCreating,        isFullScreen,        isPlayerOnly,        isRtl,        isShared,        loading,        renderLogin,        onClickAccountNav,        onCloseAccountNav,        onLogOut,        onOpenRegistration,        onToggleLoginOpen,        onUpdateProjectTitle,        onActivateCostumesTab,        onActivateSoundsTab,        onActivateTab,        onClickLogo,        onExtensionButtonClick,        onProjectTelemetryEvent,        onRequestCloseBackdropLibrary,        onRequestCloseCostumeLibrary,        onRequestCloseTelemetryModal,        onSeeCommunity,        onShare,        onTelemetryModalCancel,        onTelemetryModalOptIn,        onTelemetryModalOptOut,        showComingSoon,        soundsTabVisible,        stageSizeMode,        targetIsStage,        telemetryModalVisible,        tipsLibraryVisible,        vm,        loginState,        ...componentProps    } = omit(props, 'dispatch');    ...

再在使用MenuBar的地方也为MenuBar定义`loginState`属性,它的值就是GUIComponent传进来的`loginState`的值:

<MenuBar                    accountNavOpen={accountNavOpen}                    authorId={authorId}                    authorThumbnailUrl={authorThumbnailUrl}                    authorUsername={authorUsername}                    canCreateCopy={canCreateCopy}                    canCreateNew={canCreateNew}                    canEditTitle={canEditTitle}                    canRemix={canRemix}                    canSave={canSave}                    canShare={canShare}                    className={styles.menuBarPosition}                    enableCommunity={enableCommunity}                    isShared={isShared}                    renderLogin={renderLogin}                    showComingSoon={showComingSoon}                    onClickAccountNav={onClickAccountNav}                    onClickLogo={onClickLogo}                    onCloseAccountNav={onCloseAccountNav}                    onLogOut={onLogOut}                    onOpenRegistration={onOpenRegistration}                    onProjectTelemetryEvent={onProjectTelemetryEvent}                    onSeeCommunity={onSeeCommunity}                    onShare={onShare}                    onToggleLoginOpen={onToggleLoginOpen}                    onUpdateProjectTitle={onUpdateProjectTitle}                    loginState={loginState}                />

最后修改components / menu-bar.jsx中的MenuBar组件的显示,将右上角替换成:

<React.Fragment>                            {this.props.loginState ? (                                <React.Fragment>                                    <MenuBarItemTooltip id="mystuff">                                        <div                                            className={classNames(                                                styles.menuBarItem,                                                styles.hoverable,                                                styles.mystuffButton                                            )}                                        >                                            <img                                                className={styles.mystuffIcon}                                                src={mystuffIcon}                                            />                                        </div>                                    </MenuBarItemTooltip>                                    <MenuBarItemTooltip                                        id="account-nav"                                        place={this.props.isRtl ? 'right' : 'left'}                                    >                                        <div                                            className={classNames(                                                styles.menuBarItem,                                                styles.hoverable,                                                styles.accountNavMenu                                            )}                                        >                                            <img                                                className={styles.profileIcon}                                                src={profileIcon}                                            />                                            <span>                                                {'scratch-cat'}                                            </span>                                            <img                                                className={styles.dropdownCaretIcon}                                                src={dropdownCaret}                                            />                                        </div>                                    </MenuBarItemTooltip>                                </React.Fragment>                            ) : <button >Login</button>}                        </React.Fragment>

如果用户已登录,就显示头像和姓名的样式(具体的用户信息需要跟后台打通,我们后面再实现):

 

否则显示登录按钮:

我们可以通过修改reducers / user-state.js中的loginState的初始值来查看效果:

loginState: UserState.NOT_LOGINED

loginState: UserState.LOGINED

这个值我们会在后面根据用户登录的token去获取。

 

为了与项目整体风格一致,我们修改这个登录按钮的样式,在菜单栏目录中添加login-button.css和login-button.jsx文件,内容分别如下:

​​

@import "../../css/colors.css";.login-button {    background: $data-primary;}
import classNames from 'classnames';import {FormattedMessage} from 'react-intl';import PropTypes from 'prop-types';import React from 'react';import Button from '../button/button.jsx';import styles from './login-button.css';const LoginButton = ({    className,    onClick}) => (    <Button        className={classNames(            className,            styles.loginButton        )}        onClick={onClick}    >        <FormattedMessage            defaultMessage="Login"            description="Label for login"            id="gui.menuBar.login"        />    </Button>);LoginButton.propTypes = {    className: PropTypes.string,    onClick: PropTypes.func};LoginButton.defaultProps = {    onClick: () => {}};export default LoginButton;

然后在menu-bar.jsx中如下使用:

<LoginButton className={styles.menuBarButton} />

 这样看起来就好看多了:

好了,这里接收完成后,我们接下来就可以实现一个后台系统,然后对接后台系统登录和获取用户信息了。

 

上一章节链接:https://blog.csdn.net/tank_ft/article/details/104039006
下一章节链接:https://blog.csdn.net/tank_ft/article/details/104197077

这篇关于scratch3.0 scratch-gui中集成自定义用户系统1(第四章)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/812602

相关文章

springboot集成Lucene的详细指南

《springboot集成Lucene的详细指南》这篇文章主要为大家详细介绍了springboot集成Lucene的详细指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起... 目录添加依赖创建配置类创建实体类创建索引服务类创建搜索服务类创建控制器类使用示例以下是 Spring

Windows系统宽带限制如何解除?

《Windows系统宽带限制如何解除?》有不少用户反映电脑网速慢得情况,可能是宽带速度被限制的原因,只需解除限制即可,具体该如何操作呢?本文就跟大家一起来看看Windows系统解除网络限制的操作方法吧... 有不少用户反映电脑网速慢得情况,可能是宽带速度被限制的原因,只需解除限制即可,具体该如何操作呢?本文

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

电脑找不到mfc90u.dll文件怎么办? 系统报错mfc90u.dll丢失修复的5种方案

《电脑找不到mfc90u.dll文件怎么办?系统报错mfc90u.dll丢失修复的5种方案》在我们日常使用电脑的过程中,可能会遇到一些软件或系统错误,其中之一就是mfc90u.dll丢失,那么,mf... 在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包

电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案

《电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案》最近有不少兄弟反映,电脑突然弹出“mfc100u.dll已加载,但找不到入口点”的错误提示,导致一些程序无法正... 在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“找不到指定的模块”或“缺少某个DL

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient