Scratch二次开发4:登录功能的实现

写在前面:

为公共事业做贡献,做了个开源版本:scratch.lite

开源版本带MySQL后台服务器,功能:注册、登录、保存作品、分享、修改作品名称、保存作品缩略图。

有兴趣的朋友可以去下载参考:lite: 一个轻量级的Scratch编程分享平台:注册登录、作品创作、作品管理、素材管理、用户管理,作品点赞、收藏、分享。

Scratch二次开发的纯技术交流QQ群:115224892/914159821

原始scratch-GUI版本中,并无登录功能,但为scratch-www版本留了接口,由于使用的是react框架,初学者可能会被绕晕。

下面就简单说说如何实现这个功能。

一、登录相关的核心源代码

1、session.js

登录状态文件,需要新加到/src/reducers目录下,内容如下:

const SET_SESSION = 'session/SET_SESSION';
//登录状态
const initialState = {
    userid: 0,
    username: '',
    nickname: '',
    avatar: ''
};

const reducer = function (state, action) {
    if (typeof state === 'undefined') state = initialState;

    switch (action.type) {
    case SET_SESSION:
        return Object.assign({}, state, action.session);
    }
    return state;
};
const setSession = session => ({type: SET_SESSION,session: session});

export {
    reducer as default,
    initialState as initializedSession,
    setSession
};

2、session.js

与服务器通信部分,放在/src/lib目录下,文件名本人与上面的状态文件保持了一致。

(本人把作品保存部分的通信接口也写到了这个文件中,后续会专门写一篇关于保存作品的部分,那里会用到。)

function miniFetch(resolve, reject, uri, params){
    var opts = {
        headers:{
            'Accept':'application/json,text/plain,*/*',/* 格式限制:json、文本、其他格式 */
            'Content-Type':'application/x-www-form-urlencoded'/* 请求内容类型 */
        },
        method:'post'
    }
    if (params){
        if (params.headers) {opts['headers'] =  Object.assign(opts['headers'], params.headers)}
        if (params.method) {opts["method"] = params.method}
        if (params.body)   {opts["body"] = params.body}
    }

    fetch(uri, opts)
    .then(response=>{
        var body = response.json();
        if(response.status == 200){
            return resolve(body);
        }
        return reject(body)
    })
    .catch(err=>reject(err))
};
//登录一:首页打开Scratch时,自动获取一次用户登录信息
module.exports.requestSession = (resolve, reject) => (
    miniFetch(resolve, reject, '/user/getSession')
);
//登录二:提交账号、密码进行登录
module.exports.requestLogin = (resolve, reject, data) => (
    miniFetch(resolve, reject, '/user/login', {body:data})
);
//退出:提交账号,退出登录状态
module.exports.requestLogout = (resolve, reject, data) => (
    miniFetch(resolve, reject, '/user/logout', {body:data})
);

//获取项目源代码
module.exports.requestProject = (resolve, reject, projectId) => (
    miniFetch(resolve, reject, `/scratch/project/${projectId}`)
);
//保存标题
module.exports.requestSaveProjectTitle = (resolve, reject, projectId, projectTitle) => {
    miniFetch(resolve, reject, '/scratch/saveProjcetTitle', {body:`id=${projectId}&title=${projectTitle}`})
};
//保存缩略图
module.exports.requestSaveProjectThumbnail = (resolve, reject, projectId, thumbnailBlob) => {
    miniFetch(resolve, reject, `/scratch/thumbnail/${projectId}`, {body:thumbnailBlob, headers:{'Content-Type': 'image/png'}})
};
//保存分享
module.exports.requestShareProject = (resolve, reject, projectId) => {
    miniFetch(resolve, reject, `/scratch/shareProject/${projectId}`)
};

二、登录流程

可以在两个地方检查并设置登录信息:

1、第一次打开编辑器时主动检测;

2、用户手动点击登录时触发式被动检测。

第一次主动自动检测,本人选择放在了启动部分:/scr/playground/index.jsx文件中

//在此判断浏览器是否支持
//实例化虚拟机会导致不受支持的浏览器出错,先判断浏览器是否支持Scratch
if (supportedBrowser()) {
    //获取session
    const {requestSession} = require('../lib/session');
    new Promise((resolve, reject) => {
        requestSession(resolve, reject);
    }).then(session => {
        if (typeof session === 'undefined'){ return runScratch({}); }

        return runScratch(session);
    }, err => {
        return runScratch({});
    });

} else {
    alert("抱歉,浏览器不支持。我们建议您使用Chrome内核的浏览器!");
}



function runScratch(session) {
    if (process.env.NODE_ENV === 'production' && typeof window === 'object') {
        window.onbeforeunload = () => true;//在即将离开当前页面(刷新或关闭)时执行 JavaScript
    }

    GUI.setAppElement(appTarget);
    const WrappedGui = compose(AppStateHOC,HashParserHOC)(GUI);
    /**
        _session=:用户的登录信息,在app-state-hoc.jsx中使用即可,不需要继续后传
     */
    ReactDOM.render(<WrappedGui _session={session}  />, appTarget);        
};

被动登录检测部分,在用户填写用户名与密码并点击登录后,触发。本人放在了menu-bar.jsx文件中:

    handleRenderLogin () {//登录操作
        return (
            <Login
                onLogIn={(formData, restoreStateInLoginComponent) => {
                    new Promise((resolve, reject) => {
                        requestLogin(resolve, reject,formData);
                    }).then(
                        body => {
                            if (body.status=="OK"){
                                this.props.onSetSession(body);
                                this.props.onRequestCloseAccount()//关闭登录后弹出账号菜单

                            } else {
                                alert(body.status);//提示用户登录不成功的原因
                                restoreStateInLoginComponent()
                            }
                        }, 
                        err => {
                            restoreStateInLoginComponent()
                        }
                    );
                }}
            />
        );
    }
    handleLogout () { //退出账号登录状态
        new Promise((resolve, reject) => {
            requestLogout(resolve, reject,`id=${this.props.userid}`);
        }).then(
            body => {
                this.props.onSetSession(initializedSession);
                //this.props.onRequestCloseAccount()//关闭登录菜单
            }, 
            err => {}
        );        
    }

三、登录界面部分

本人参考了scratch www 版本,做了个简单的小登录窗口,只贴个登录前及登录后的图吧,源代码就不放了。

          

如果本文章对您有帮助,请不吝点个赞再走!!!Bailee 了个Bye!!!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值