<commit_before>/**
 * Created by raychen on 16/9/14.
 */

//config and test
import {SUCCESS, FAIL, getUser, setUser} from './servers/config'
//services
import {saveUser, login, register} from './servers/service/LoginService';
import {getFlowListData, getCountData, getLangListData, getCoverData} from './servers/service/HomeService'
import {addLang, getAllLanguage, deleteLanguage} from './servers/service/LanguageService'
import {evaluateRecommend, getUserFollowings, getUserFollowers, getUserFollowingsAndFollowersNum, addFeedback, getUserStarRepo, getBestSubRepo, isLanguist} from './servers/service/UserService'
import {addAReopSet, addARepoToSet, getRepoSet, getRepoSetList, getRelatedRecommend, getRepoInfos, addMore, addInfoToList, getRepoLanguage} from './servers/service/RepoService'
import {record_log, getLog} from './servers/service/LogService'
import {updateWhenLogin} from './servers/logic/UpdateWhenLogin'
//others
import {starRepo, followUser,unfollowUser, unstarRepo} from './servers/api/github_user'
import {searchRepo} from './servers/api/github_search'

function addRepoAPI(server) {
  //star repo
  server.post('/api/repo/star', (req, res)=> {
    starRepo(req.body.user, req.body.repo, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' star repo: ' + req.body.repo + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' star repo: ' + req.body.repo + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //unstar repo
  server.post('/api/repo/unstar', (req, res)=> {
    unstarRepo(req.body.user, req.body.repo, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' unstar repo: ' + req.body.repo + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' unstar repo: ' + req.body.repo + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //add a repo to a repo set
  server.post('/api/repo/addToSet', (req, res) => {
    addARepoToSet(req.body.login, req.body.fullname, req.body.setname, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add: ' + req.body.fullname + ' to the set: ' + req.body.setname + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add: ' + req.body.fullname + ' to the set: ' + req.body.setname + ' FAIL!', 'error');
        res.send({res: resa});
      }
    })
  });
  //add a repo set
  server.post('/api/repo/addSet', (req, res) => {
    addAReopSet(req.body.login, req.body.setname, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add set: ' + req.body.setname + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add set: ' + req.body.setname + ' SUCCESS!', 'error');
        res.send({res: resa});
      }
    });
  });
  //search repo
  server.get('/api/search/repo', (req, res) => {
    searchRepo(req.query.keyword, req.query.language, req.query.page, (resa) => {
      record_log(getUser(), getUser() + ' search repo: ' + req.query.q + ' and return: ' + resa.length + ' RECORDS', 'query');
      res.send(resa);
    })
  });
  //get set list
  server.get('/api/repo/setList', (req, res) => {
    getRepoSetList(req.query.user, (resa) => {
      record_log(getUser(), getUser() + ' get set list and return: ' + resa.length + ' RECORDS', 'query');
      res.send(resa);
    })
  });
  //get set
  server.get('/api/repo/set', (req, res) => {
    getRepoSet(req.query.user, req.query.setName, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get set: ' + req.query.setName + ' repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get recommend repo
  server.get('/api/repo/related', (req, res) => {
    getRelatedRecommend(req.query.fullName, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' related repo and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get repo infos
  server.get('/api/repo/info', (req, res) => {
    getRepoInfos(req.query.fullName, (resa) => {
      record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' info', 'query');
      res.send(resa);
    })
  });
  //get repo languages/tags
  server.get('/api/repo/languages', (req, res) => {
    getRepoLanguage(req.query.fullName, (resa) => {
      addInfoToList(getUser(), [resa], true, () => {
        //record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' languages and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
}

function addUserAPI(server) {
  //follow user
  server.post('/api/user/follow', (req, res)=> {
    followUser(req.body.user, req.body.follow, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' follow user: ' + req.body.follow + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' follow user: ' + req.body.follow + ' SUCCESS!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //unfollow user
  server.post('/api/user/unfollow', (req, res)=> {
    unfollowUser(req.body.user, req.body.follow, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' unfollow user: ' + req.body.follow + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' unfollow user: ' + req.body.follow + ' SUCCESS!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //get current user
  server.get('/api/current_user', (req, res) => {
    res.send(req.session.username);
  });
  //get temp user
  server.get('/api/temp_user', (req, res) => {
    res.send(req.session.tempname);
  });
  //get followings
  server.get('/api/user/following', (req, res) => {
    getUserFollowings(req.query.user, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get followings and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get followers
  server.get('/api/user/follower', (req, res) => {
    getUserFollowers(req.query.user, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get followers and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get followersNum and followingsNum (eg.{followings:1, followers:1})
  server.get('/api/user/folInfo', (req, res) => {
    getUserFollowingsAndFollowersNum(req.query.user, (resa) => {
      record_log(getUser(), getUser() + ' get followings and followers info', 'query');
      res.send(resa);
    })
  });
  //get anyone star repo
  server.get('/api/user/starRepo', (req, res)=> {
    getUserStarRepo(req.query.login, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get star repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    });
  });
  //get user most stared subscript repos
  server.get('/api/user/subRepo', (req, res)=> {
    getBestSubRepo(req.query.login, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get subscribe repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    });
  });
  //judge a person if he is languist
  server.get('/api/user/isLanguist', (req, res)=> {
    isLanguist(req.query.login, (resa) => {
      res.send({res: resa});
    });
  });
}

function addLoginAPI(server) {
  //login success
  server.get('/api/login/success', (req, res)=> {
    saveUser(req.query.code, (ress) => {
      if (ress != null) {
        req.session.tempname = ress;
        setUser(ress);
        record_log(getUser(), ress + ' sign up with github SUCCESS!', 'login');
        res.redirect('/register');
      }
      else {
        record_log(getUser(), ress + ' sign up with github FAIL!', 'error');
        res.redirect('/login');
      }
    });
  });
  //login
  server.post('/api/login', (req, res) => {
    login(req.body.username, req.body.password, (res2) => {
      if (res2 == SUCCESS) {
        setUser(req.body.username);
        req.session.username = req.body.username;
        record_log(getUser(), getUser() + ' login SUCCESS!', 'login');
        //console.log('session');
        //console.log(req.session.cookie.maxAge / 1000);
        res.send({res: SUCCESS});
      } else {
        record_log(getUser(), getUser() + ' login FAIL!', 'error');
        res.send({res: res2});
      }
    })
  });
  //register
  server.post('/api/register', (req, res) => {
    register(req.body.username, req.body.password, (res2) => {
      if (res2 == SUCCESS) {
        req.session.username = req.body.username;
        record_log(getUser(), getUser() + ' register SUCCESS!', 'login');
        res.send({res: SUCCESS});
      } else {
        res.send({res: res2});
        record_log(getUser(), getUser() + ' register FAIL!', 'error');
      }
    })
  });
  //logout
  server.post('/api/logout', (req, res) => {
    record_log(getUser(), getUser() + ' logout!', 'login');
    req.session.username = null;
    req.session.tempname = null;
    setUser(null);
    res.redirect('/login');
  });
}

function addOtherAPI(server) {
  //get recommend data
  server.get('/api/home/flowList', (req, res) => {
    getFlowListData(req.query.user, ret => {
      addInfoToList(req.query.user, ret, true, () => {
        record_log(getUser(), getUser() + ' get flowlist data and return: ' + ret.length + ' RECORDS', 'query');
        res.send(ret);
      });
    });
  });
  //home-count
  server.get('/api/home/count', (req, res) => {
    getCountData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home count info', 'query');
      res.send(call);
    });
  });
  //home-language list
  server.get('/api/home/langList', (req, res) => {
    getLangListData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home languages and return: ' + call.length + ' RECORDS', 'query');
      res.send(call);
    });
  });
  //home-cover
  server.get('/api/home/cover', (req, res)=> {
    getCoverData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home cover info', 'query');
      res.send(call);
    });
  });

  //evaluate the recommend
  server.post('/api/rec/evaluate', (req, res) => {
    evaluateRecommend(req.body.login, req.body.name, req.body.type, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' dislike: ' + req.body.name + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' dislike: ' + req.body.name + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    })
  });
  //add more
  server.get('/api/recommend/more', (req, res) => {
    addMore(req.query.login, req.query.times, (resa) => {
      record_log(getUser(), getUser() + ' get more: ' + req.query.times + ' times recommend data and return: ' + resa.length + ' RECORDS', 'query');
      res.send(resa);
    })
  });
  //add feedback
  server.post('/api/feedback/add', (req, res)=> {
    addFeedback(req.body.login, req.body.feedback, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add feedback SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add feedback FAIL!', 'error');
        res.send({res: resa});
      }
    });
  });
}

function addLanguageAPI(server) {
  //choose/modify language
  server.post('/api/lang/choose', (req, res) => {
    addLang(req.body.login, req.body.lang, req.body.level, ret => {
      if (ret == SUCCESS) {
        record_log(getUser(), getUser() + ' choose language: ' + req.body.lang + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' choose language: ' + req.body.lang + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //get all language
  server.get('/api/language/all', (req, res) => {
    getAllLanguage((langs) => {
      res.send(langs);
    })
  });
  //delete language
  server.post('/api/lang/delete', (req, res) => {
    deleteLanguage(req.body.login, req.body.lang, ret => {
      if (ret == SUCCESS) {
        record_log(getUser(), getUser() + ' delete language: ' + req.body.lang + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' delete language: ' + req.body.lang + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
}

export {addLanguageAPI, addLoginAPI, addOtherAPI, addUserAPI, addRepoAPI}
<commit_msg>fix bug<commit_after>/**
 * Created by raychen on 16/9/14.
 */

//config and test
import {SUCCESS, FAIL, getUser, setUser} from './servers/config'
//services
import {saveUser, login, register} from './servers/service/LoginService';
import {getFlowListData, getCountData, getLangListData, getCoverData} from './servers/service/HomeService'
import {addLang, getAllLanguage, deleteLanguage} from './servers/service/LanguageService'
import {evaluateRecommend, getUserFollowings, getUserFollowers, getUserFollowingsAndFollowersNum, addFeedback, getUserStarRepo, getBestSubRepo, isLanguist} from './servers/service/UserService'
import {addAReopSet, addARepoToSet, getRepoSet, getRepoSetList, getRelatedRecommend, getRepoInfos, addMore, addInfoToList, getRepoLanguage} from './servers/service/RepoService'
import {record_log, getLog} from './servers/service/LogService'
import {updateWhenLogin} from './servers/logic/UpdateWhenLogin'
//others
import {starRepo, followUser,unfollowUser, unstarRepo} from './servers/api/github_user'
import {searchRepo} from './servers/api/github_search'

function addRepoAPI(server) {
  //star repo
  server.post('/api/repo/star', (req, res)=> {
    starRepo(req.body.user, req.body.repo, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' star repo: ' + req.body.repo + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' star repo: ' + req.body.repo + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //unstar repo
  server.post('/api/repo/unstar', (req, res)=> {
    unstarRepo(req.body.user, req.body.repo, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' unstar repo: ' + req.body.repo + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' unstar repo: ' + req.body.repo + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //add a repo to a repo set
  server.post('/api/repo/addToSet', (req, res) => {
    addARepoToSet(req.body.login, req.body.fullname, req.body.setname, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add: ' + req.body.fullname + ' to the set: ' + req.body.setname + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add: ' + req.body.fullname + ' to the set: ' + req.body.setname + ' FAIL!', 'error');
        res.send({res: resa});
      }
    })
  });
  //add a repo set
  server.post('/api/repo/addSet', (req, res) => {
    addAReopSet(req.body.login, req.body.setname, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add set: ' + req.body.setname + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add set: ' + req.body.setname + ' SUCCESS!', 'error');
        res.send({res: resa});
      }
    });
  });
  //search repo
  server.get('/api/search/repo', (req, res) => {
    searchRepo(req.query.keyword, req.query.language, req.query.page, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' search repo: ' + req.query.q + ' and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get set list
  server.get('/api/repo/setList', (req, res) => {
    getRepoSetList(req.query.user, (resa) => {
      record_log(getUser(), getUser() + ' get set list and return: ' + resa.length + ' RECORDS', 'query');
      res.send(resa);
    })
  });
  //get set
  server.get('/api/repo/set', (req, res) => {
    getRepoSet(req.query.user, req.query.setName, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get set: ' + req.query.setName + ' repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get recommend repo
  server.get('/api/repo/related', (req, res) => {
    getRelatedRecommend(req.query.fullName, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' related repo and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get repo infos
  server.get('/api/repo/info', (req, res) => {
    getRepoInfos(req.query.fullName, (resa) => {
      record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' info', 'query');
      res.send(resa);
    })
  });
  //get repo languages/tags
  server.get('/api/repo/languages', (req, res) => {
    getRepoLanguage(req.query.fullName, (resa) => {
      addInfoToList(getUser(), [resa], true, () => {
        //record_log(getUser(), getUser() + ' get repo: ' + req.query.fullName + ' languages and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
}

function addUserAPI(server) {
  //follow user
  server.post('/api/user/follow', (req, res)=> {
    followUser(req.body.user, req.body.follow, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' follow user: ' + req.body.follow + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' follow user: ' + req.body.follow + ' SUCCESS!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //unfollow user
  server.post('/api/user/unfollow', (req, res)=> {
    unfollowUser(req.body.user, req.body.follow, resa => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' unfollow user: ' + req.body.follow + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' unfollow user: ' + req.body.follow + ' SUCCESS!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //get current user
  server.get('/api/current_user', (req, res) => {
    res.send(req.session.username);
  });
  //get temp user
  server.get('/api/temp_user', (req, res) => {
    res.send(req.session.tempname);
  });
  //get followings
  server.get('/api/user/following', (req, res) => {
    getUserFollowings(req.query.user, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get followings and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get followers
  server.get('/api/user/follower', (req, res) => {
    getUserFollowers(req.query.user, (resa) => {
      addInfoToList(req.query.user, resa, true, () => {
        record_log(getUser(), getUser() + ' get followers and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    })
  });
  //get followersNum and followingsNum (eg.{followings:1, followers:1})
  server.get('/api/user/folInfo', (req, res) => {
    getUserFollowingsAndFollowersNum(req.query.user, (resa) => {
      record_log(getUser(), getUser() + ' get followings and followers info', 'query');
      res.send(resa);
    })
  });
  //get anyone star repo
  server.get('/api/user/starRepo', (req, res)=> {
    getUserStarRepo(req.query.login, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get star repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    });
  });
  //get user most stared subscript repos
  server.get('/api/user/subRepo', (req, res)=> {
    getBestSubRepo(req.query.login, (resa) => {
      addInfoToList(getUser(), resa, true, () => {
        record_log(getUser(), getUser() + ' get subscribe repos and return: ' + resa.length + ' RECORDS', 'query');
        res.send(resa);
      });
    });
  });
  //judge a person if he is languist
  server.get('/api/user/isLanguist', (req, res)=> {
    isLanguist(req.query.login, (resa) => {
      res.send({res: resa});
    });
  });
}

function addLoginAPI(server) {
  //login success
  server.get('/api/login/success', (req, res)=> {
    saveUser(req.query.code, (ress) => {
      if (ress != null) {
        req.session.tempname = ress;
        setUser(ress);
        record_log(getUser(), ress + ' sign up with github SUCCESS!', 'login');
        res.redirect('/register');
      }
      else {
        record_log(getUser(), ress + ' sign up with github FAIL!', 'error');
        res.redirect('/login');
      }
    });
  });
  //login
  server.post('/api/login', (req, res) => {
    login(req.body.username, req.body.password, (res2) => {
      if (res2 == SUCCESS) {
        setUser(req.body.username);
        req.session.username = req.body.username;
        record_log(getUser(), getUser() + ' login SUCCESS!', 'login');
        //console.log('session');
        //console.log(req.session.cookie.maxAge / 1000);
        res.send({res: SUCCESS});
      } else {
        record_log(getUser(), getUser() + ' login FAIL!', 'error');
        res.send({res: res2});
      }
    })
  });
  //register
  server.post('/api/register', (req, res) => {
    register(req.body.username, req.body.password, (res2) => {
      if (res2 == SUCCESS) {
        req.session.username = req.body.username;
        record_log(getUser(), getUser() + ' register SUCCESS!', 'login');
        res.send({res: SUCCESS});
      } else {
        res.send({res: res2});
        record_log(getUser(), getUser() + ' register FAIL!', 'error');
      }
    })
  });
  //logout
  server.post('/api/logout', (req, res) => {
    record_log(getUser(), getUser() + ' logout!', 'login');
    req.session.username = null;
    req.session.tempname = null;
    setUser(null);
    res.redirect('/login');
  });
}

function addOtherAPI(server) {
  //get recommend data
  server.get('/api/home/flowList', (req, res) => {
    getFlowListData(req.query.user, ret => {
      addInfoToList(req.query.user, ret, true, () => {
        record_log(getUser(), getUser() + ' get flowlist data and return: ' + ret.length + ' RECORDS', 'query');
        res.send(ret);
      });
    });
  });
  //home-count
  server.get('/api/home/count', (req, res) => {
    getCountData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home count info', 'query');
      res.send(call);
    });
  });
  //home-language list
  server.get('/api/home/langList', (req, res) => {
    getLangListData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home languages and return: ' + call.length + ' RECORDS', 'query');
      res.send(call);
    });
  });
  //home-cover
  server.get('/api/home/cover', (req, res)=> {
    getCoverData(req.query.user, call => {
      record_log(getUser(), getUser() + ' get home cover info', 'query');
      res.send(call);
    });
  });

  //evaluate the recommend
  server.post('/api/rec/evaluate', (req, res) => {
    evaluateRecommend(req.body.login, req.body.name, req.body.type, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' dislike: ' + req.body.name + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' dislike: ' + req.body.name + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    })
  });
  //add more
  server.get('/api/recommend/more', (req, res) => {
    addMore(req.query.login, req.query.times, (resa) => {
      record_log(getUser(), getUser() + ' get more: ' + req.query.times + ' times recommend data and return: ' + resa.length + ' RECORDS', 'query');
      res.send(resa);
    })
  });
  //add feedback
  server.post('/api/feedback/add', (req, res)=> {
    addFeedback(req.body.login, req.body.feedback, (resa) => {
      if (resa == SUCCESS) {
        record_log(getUser(), getUser() + ' add feedback SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' add feedback FAIL!', 'error');
        res.send({res: resa});
      }
    });
  });
}

function addLanguageAPI(server) {
  //choose/modify language
  server.post('/api/lang/choose', (req, res) => {
    addLang(req.body.login, req.body.lang, req.body.level, ret => {
      if (ret == SUCCESS) {
        record_log(getUser(), getUser() + ' choose language: ' + req.body.lang + ' SUCCESS!', 'add');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' choose language: ' + req.body.lang + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
  //get all language
  server.get('/api/language/all', (req, res) => {
    getAllLanguage((langs) => {
      res.send(langs);
    })
  });
  //delete language
  server.post('/api/lang/delete', (req, res) => {
    deleteLanguage(req.body.login, req.body.lang, ret => {
      if (ret == SUCCESS) {
        record_log(getUser(), getUser() + ' delete language: ' + req.body.lang + ' SUCCESS!', 'del');
        res.send({res: SUCCESS});
      }
      else {
        record_log(getUser(), getUser() + ' delete language: ' + req.body.lang + ' FAIL!', 'error');
        res.send({res: FAIL});
      }
    });
  });
}

export {addLanguageAPI, addLoginAPI, addOtherAPI, addUserAPI, addRepoAPI}
<|endoftext|>


<commit_before>import { skybox } from "pex-shaders";
import createQuad from "primitive-quad";
import { patchVS, patchFS } from "../utils.js";
import { mat4 } from "pex-math";
const identityMatrix = mat4.create();

class Skybox {
  constructor(opts) {
    this.type = "Skybox";
    this.enabled = true;
    this.rgbm = false;
    this.backgroundBlur = 0;

    console.log("skybox-system", opts);

    const ctx = (this._ctx = opts.ctx);

    this.texture = null;
    this.diffuseTexture = null;
    this.dirty = true;

    this.set(opts);

    const skyboxPositions = [
      [-1, -1],
      [1, -1],
      [1, 1],
      [-1, 1],
    ];
    const skyboxFaces = [
      [0, 1, 2],
      [0, 2, 3],
    ];

    this._drawCommand = {
      name: "Skybox.draw",
      pipeline: ctx.pipeline({
        vert: ctx.capabilities.isWebGL2
          ? patchVS(skybox.skybox.vert)
          : /* glsl */ `
${ctx.capabilities.maxColorAttachments > 1 ? "#define USE_DRAW_BUFFERS" : ""}
    ${skybox.skybox.vert}`,
        frag: ctx.capabilities.isWebGL2
          ? patchFS(skybox.skybox.frag)
          : /* glsl */ `
${ctx.capabilities.maxColorAttachments > 1 ? "#define USE_DRAW_BUFFERS" : ""}
${skybox.skybox.frag}`,
        depthTest: true,
        depthWrite: false,
      }),
      attributes: {
        aPosition: ctx.vertexBuffer(skyboxPositions),
      },
      indices: ctx.indexBuffer(skyboxFaces),
      uniforms: {
        uUseTonemapping: false,
        uExposure: 1,
      },
    };

    const quad = createQuad();

    this._skyTexture = ctx.texture2D({
      width: 512,
      height: 256,
      // pixelFormat: this.rgbm ? ctx.PixelFormat.RGBA8 : ctx.PixelFormat.RGBA16F,
      pixelFormat: this.rgbm ? ctx.PixelFormat.RGBA8 : ctx.PixelFormat.RGBA,
      encoding: this.rgbm ? ctx.Encoding.RGBM : ctx.Encoding.Linear,
      min: ctx.Filter.Linear,
      mag: ctx.Filter.Linear,
    });

    this._updateSkyTexture = {
      name: "Skybox.updateSkyTexture",
      pass: ctx.pass({
        name: "Skybox.updateSkyTexture",
        color: [this._skyTexture],
        clearColor: [0, 0, 0, 0],
      }),
      pipeline: ctx.pipeline({
        vert: skybox.skyEnvMap.vert,
        frag: skybox.skyEnvMap.frag,
      }),
      uniforms: {
        uSunPosition: [0, 0, 0],
      },
      attributes: {
        aPosition: ctx.vertexBuffer(quad.positions),
        aTexCoord0: ctx.vertexBuffer(quad.uvs),
      },
      indices: ctx.indexBuffer(quad.cells),
    };
  }

  set(opts) {
    Object.assign(this, opts);

    if (opts.sunPosition) {
      this.dirty = true;
    }
  }

  updateSkyTexture() {
    const ctx = this._ctx;
    this.dirty = false;
    ctx.submit(this._updateSkyTexture, {
      uniforms: {
        uSunPosition: this.sunPosition,
        uRGBM: this.rgbm,
      },
    });
  }

  draw(camera, opts) {
    const { entity, projectionMatrix, viewMatrix, exposure } = camera;
    const { backgroundMode, outputEncoding } = opts;
    const ctx = this._ctx;
    if (!this.texture && this.dirty) {
      this.updateSkyTexture();
    }

    let texture = this.texture || this._skyTexture;
    let backgroundBlur = 0;
    if (backgroundMode) {
      if (this.backgroundTexture) {
        texture = this.backgroundTexture;
      }

      if (this.backgroundBlur > 0) {
        backgroundBlur = this.backgroundBlur;
        //TODO: skybox-system and reflection-probe-system peer dependency
        // if (!this._reflectionProbe) {
        // this._reflectionProbe =
        // this.entity.renderer.getComponents("ReflectionProbe")[0];
        // }
        if (this._reflectionProbe) {
          texture = this._reflectionProbe._reflectionMap;
        }
      }
    }

    //TODO: useTonemapping hardcoded to false
    // const postProcessingCmp = entity
    // ? entity.getComponent("PostProcessing")
    // : null;
    // const useTonemapping = !(postProcessingCmp && postProcessingCmp.enabled);
    const useTonemapping = false;

    // TODO: can we somehow avoid creating an object every frame here?
    ctx.submit(this._drawCommand, {
      viewport: camera.viewport,
      scissor: camera.viewport,
      uniforms: {
        uProjectionMatrix: projectionMatrix,
        uViewMatrix: viewMatrix,
        // uModelMatrix: this.entity.transform.modelMatrix,
        //TODO: iplement entity matrix
        uModelMatrix: identityMatrix,
        uEnvMap: texture,
        uEnvMapEncoding: texture.encoding,
        uOutputEncoding: outputEncoding,
        uBackgroundBlur: backgroundBlur,
        uUseTonemapping: backgroundMode ? useTonemapping : false,
        uExposure: backgroundMode ? exposure : 1,
      },
    });
  }
}

export default function createSkyboxSystem(opts) {
  const skyboxSystem = {
    cache: {},
    debug: false,
  };

  skyboxSystem.update = (entities) => {
    const skyboxEntities = entities.filter((e) => e.skybox);
    for (let skyboxEntity of skyboxEntities) {
      if (!skyboxSystem.cache[skyboxEntity.id]) {
        const skybox = new Skybox({
          ...skyboxEntity.skybox,
          ctx: opts.ctx,
        });
        skyboxSystem.cache[skyboxEntity.id] = skybox;
        skyboxEntity._skybox = skybox; //TODO: why do we need it

        skybox.updateSkyTexture();
      }
    }
  };

  return skyboxSystem;
}
<commit_msg>feat(systems/skybox-system): add default values<commit_after>import { skybox } from "pex-shaders";
import createQuad from "primitive-quad";
import { patchVS, patchFS } from "../utils.js";
import { mat4 } from "pex-math";
const identityMatrix = mat4.create();

class Skybox {
  constructor(opts) {
    this.type = "Skybox";
    this.enabled = true;
    this.rgbm = false;
    this.backgroundBlur = 0;

    console.log("skybox-system", opts);

    const ctx = (this._ctx = opts.ctx);

    this.texture = null;
    this.diffuseTexture = null;
    this.dirty = true;

    this.set(opts);

    const skyboxPositions = [
      [-1, -1],
      [1, -1],
      [1, 1],
      [-1, 1],
    ];
    const skyboxFaces = [
      [0, 1, 2],
      [0, 2, 3],
    ];

    this._drawCommand = {
      name: "Skybox.draw",
      pipeline: ctx.pipeline({
        vert: ctx.capabilities.isWebGL2
          ? patchVS(skybox.skybox.vert)
          : /* glsl */ `
${ctx.capabilities.maxColorAttachments > 1 ? "#define USE_DRAW_BUFFERS" : ""}
    ${skybox.skybox.vert}`,
        frag: ctx.capabilities.isWebGL2
          ? patchFS(skybox.skybox.frag)
          : /* glsl */ `
${ctx.capabilities.maxColorAttachments > 1 ? "#define USE_DRAW_BUFFERS" : ""}
${skybox.skybox.frag}`,
        depthTest: true,
        depthWrite: false,
      }),
      attributes: {
        aPosition: ctx.vertexBuffer(skyboxPositions),
      },
      indices: ctx.indexBuffer(skyboxFaces),
      uniforms: {
        uUseTonemapping: false,
        uExposure: 1,
      },
    };

    const quad = createQuad();

    this._skyTexture = ctx.texture2D({
      width: 512,
      height: 256,
      // pixelFormat: this.rgbm ? ctx.PixelFormat.RGBA8 : ctx.PixelFormat.RGBA16F,
      pixelFormat: this.rgbm ? ctx.PixelFormat.RGBA8 : ctx.PixelFormat.RGBA,
      encoding: this.rgbm ? ctx.Encoding.RGBM : ctx.Encoding.Linear,
      min: ctx.Filter.Linear,
      mag: ctx.Filter.Linear,
    });

    this._updateSkyTexture = {
      name: "Skybox.updateSkyTexture",
      pass: ctx.pass({
        name: "Skybox.updateSkyTexture",
        color: [this._skyTexture],
        clearColor: [0, 0, 0, 0],
      }),
      pipeline: ctx.pipeline({
        vert: skybox.skyEnvMap.vert,
        frag: skybox.skyEnvMap.frag,
      }),
      uniforms: {
        uSunPosition: [0, 0, 0],
      },
      attributes: {
        aPosition: ctx.vertexBuffer(quad.positions),
        aTexCoord0: ctx.vertexBuffer(quad.uvs),
      },
      indices: ctx.indexBuffer(quad.cells),
    };
  }

  set(opts) {
    Object.assign(this, opts);

    if (opts.sunPosition) {
      this.dirty = true;
    }
  }

  updateSkyTexture() {
    const ctx = this._ctx;
    this.dirty = false;
    ctx.submit(this._updateSkyTexture, {
      uniforms: {
        uSunPosition: this.sunPosition || [0, 0, 0],
        uRGBM: this.rgbm,
      },
    });
  }

  draw(camera, opts) {
    const { entity, projectionMatrix, viewMatrix, exposure } = camera;
    const { backgroundMode, outputEncoding } = opts;
    const ctx = this._ctx;
    if (!this.texture && this.dirty) {
      this.updateSkyTexture();
    }

    let texture = this.texture || this._skyTexture;
    let backgroundBlur = 0;
    if (backgroundMode) {
      if (this.backgroundTexture) {
        texture = this.backgroundTexture;
      }

      if (this.backgroundBlur > 0) {
        backgroundBlur = this.backgroundBlur;
        //TODO: skybox-system and reflection-probe-system peer dependency
        // if (!this._reflectionProbe) {
        // this._reflectionProbe =
        // this.entity.renderer.getComponents("ReflectionProbe")[0];
        // }
        if (this._reflectionProbe) {
          texture = this._reflectionProbe._reflectionMap;
        }
      }
    }

    //TODO: useTonemapping hardcoded to false
    // const postProcessingCmp = entity
    // ? entity.getComponent("PostProcessing")
    // : null;
    // const useTonemapping = !(postProcessingCmp && postProcessingCmp.enabled);
    const useTonemapping = false;

    // TODO: can we somehow avoid creating an object every frame here?
    ctx.submit(this._drawCommand, {
      viewport: camera.viewport,
      scissor: camera.viewport,
      uniforms: {
        uProjectionMatrix: projectionMatrix,
        uViewMatrix: viewMatrix,
        // uModelMatrix: this.entity.transform.modelMatrix,
        //TODO: iplement entity matrix
        uModelMatrix: identityMatrix,
        uEnvMap: texture,
        uEnvMapEncoding: texture.encoding,
        uOutputEncoding: outputEncoding,
        uBackgroundBlur: backgroundBlur,
        uUseTonemapping: backgroundMode ? useTonemapping : false,
        uExposure: backgroundMode ? exposure || 1 : 1, //TODO: hardcoded default from camera.exposure
      },
    });
  }
}

export default function createSkyboxSystem(opts) {
  const skyboxSystem = {
    cache: {},
    debug: false,
  };

  skyboxSystem.update = (entities) => {
    const skyboxEntities = entities.filter((e) => e.skybox);
    for (let skyboxEntity of skyboxEntities) {
      if (!skyboxSystem.cache[skyboxEntity.id]) {
        const skybox = new Skybox({
          ...skyboxEntity.skybox,
          ctx: opts.ctx,
        });
        skyboxSystem.cache[skyboxEntity.id] = skybox;
        skyboxEntity._skybox = skybox; //TODO: why do we need it

        skybox.updateSkyTexture();
      }
    }
  };

  return skyboxSystem;
}
<|endoftext|>


<commit_before>var KeyboardShortcut = (function(my) {
    //maps keycode to character, id of popover for given function and function
    var shortcuts = {
        67: {
            character: "C",
            id: "toggleChatPopover",
            function: BottomToolbar.toggleChat
        },
        70: {
            character: "F",
            id: "filmstripPopover",
            function: BottomToolbar.toggleFilmStrip
        },
        77: {
            character: "M",
            id: "mutePopover",
            function: toggleAudio
        },
        84: {
            character: "T",
            function: function() {
                if(!isAudioMuted()) {
                    toggleAudio();
                }
            }
        },
        86: {
            character: "V",
            id: "toggleVideoPopover",
            function: toggleVideo
        }
    };

    window.onkeyup = function(e) {
        if(!($(":focus").is("input[type=text]") || $(":focus").is("textarea"))) {
            var keycode = e.which;
            if (typeof shortcuts[keycode] === "object") {
                shortcuts[keycode].function();
            } else if (keycode >= "0".charCodeAt(0) && keycode <= "9".charCodeAt(0)) {
                var remoteVideos = $(".videocontainer:not(#mixedstream)"),
                    videoWanted = keycode - "0".charCodeAt(0) + 1;
                if (remoteVideos.length > videoWanted) {
                    remoteVideos[videoWanted].click();
                }
            }
        }
    };

    window.onkeydown = function(e) {
        if($("#chatspace").css("display") === "none") {
            if(e.which === "T".charCodeAt(0)) {
                if(isAudioMuted()) {
                    toggleAudio();
                }
            }
        }
    };

    /**
     *
     * @param id indicates the popover associated with the shortcut
     * @returns {string} the keyboard shortcut used for the id given
     */
    my.getShortcut = function(id) {
        for(var keycode in shortcuts) {
            if(shortcuts.hasOwnProperty(keycode)) {
                if (shortcuts[keycode].id === id) {
                    return " (" + shortcuts[keycode].character + ")";
                }
            }
        }
        return "";
    };
    return my;
}(KeyboardShortcut || {}));
<commit_msg>Fixes push to talk when chat is opened.<commit_after>var KeyboardShortcut = (function(my) {
    //maps keycode to character, id of popover for given function and function
    var shortcuts = {
        67: {
            character: "C",
            id: "toggleChatPopover",
            function: BottomToolbar.toggleChat
        },
        70: {
            character: "F",
            id: "filmstripPopover",
            function: BottomToolbar.toggleFilmStrip
        },
        77: {
            character: "M",
            id: "mutePopover",
            function: toggleAudio
        },
        84: {
            character: "T",
            function: function() {
                if(!isAudioMuted()) {
                    toggleAudio();
                }
            }
        },
        86: {
            character: "V",
            id: "toggleVideoPopover",
            function: toggleVideo
        }
    };

    window.onkeyup = function(e) {
        if(!($(":focus").is("input[type=text]") || $(":focus").is("textarea"))) {
            var keycode = e.which;
            if (typeof shortcuts[keycode] === "object") {
                shortcuts[keycode].function();
            } else if (keycode >= "0".charCodeAt(0) && keycode <= "9".charCodeAt(0)) {
                var remoteVideos = $(".videocontainer:not(#mixedstream)"),
                    videoWanted = keycode - "0".charCodeAt(0) + 1;
                if (remoteVideos.length > videoWanted) {
                    remoteVideos[videoWanted].click();
                }
            }
        }
    };

    window.onkeydown = function(e) {
        if(!($(":focus").is("input[type=text]") || $(":focus").is("textarea"))) {
            if(e.which === "T".charCodeAt(0)) {
                if(isAudioMuted()) {
                    toggleAudio();
                }
            }
        }
    };

    /**
     *
     * @param id indicates the popover associated with the shortcut
     * @returns {string} the keyboard shortcut used for the id given
     */
    my.getShortcut = function(id) {
        for(var keycode in shortcuts) {
            if(shortcuts.hasOwnProperty(keycode)) {
                if (shortcuts[keycode].id === id) {
                    return " (" + shortcuts[keycode].character + ")";
                }
            }
        }
        return "";
    };
    return my;
}(KeyboardShortcut || {}));
<|endoftext|>


<commit_before>// Routes for public website

'use strict';

var bind = function (view) { return function (data, env) {
	view.scope = env;
	return view.load();
}; };

console.log("routes")
module.exports = function (view) {
	var main = view.documentElement.diff('./_main');

	return {
		'/': bind(main.diff('./index')),
		'public-inner':  bind(main.diff('./public-inner')),

		// 404 page
		404: bind(main.diff('./404')),
        'guide': bind(main.diff('./guide'))
	};
};
<commit_msg>Removed all console.log calls from view folder<commit_after>// Routes for public website

'use strict';

var bind = function (view) { return function (data, env) {
	view.scope = env;
	return view.load();
}; };

module.exports = function (view) {
	var main = view.documentElement.diff('./_main');

	return {
		'/': bind(main.diff('./index')),
		'public-inner':  bind(main.diff('./public-inner')),

		// 404 page
		404: bind(main.diff('./404')),
		'guide': bind(main.diff('./guide'))
	};
};
<|endoftext|>


<commit_before>'use strict';

if(!window.sb3theme) window.sb3theme = new (function() {
  var self = this;

  this.css = document.createElement("style");
  document.head.appendChild(this.css);
  this.style = function(css) {
    this.css.innerHTML += css;
  }
  this.style(`.blocklyDropDownArrow {
        background: inherit !important;
        border-color: inherit !important;
      }`)

  var onChanges = [];
  this.onChange = function(func) {
    onChanges.push(func);
  }
  var addFilters = [];
  this.addFilter = function(filter) {
    addFilters.push(filter);
    if(this.svg) {
      runAddFilters();
    }
  }
  var runAddFilters = function() {
    var defs = self.svg.getElementsByTagName('defs')[0];
    var ns = Blockly.SVG_NS;
    while(addFilters.length) {
      let filter = addFilters.pop();
      var doc = new DOMParser().parseFromString(`<svg xmlns="` + ns + `">` + filter + `</svg>`, 'image/svg+xml');
      defs.appendChild( defs.ownerDocument.importNode(doc.documentElement.firstElementChild, true) );
    }
  }

  var styleBlock = function(queueitem) {
    var block = queueitem[0];
    var db = queueitem[1];
    block.svgPath_.classList.add("block-background");

    var classes = ["block"];
    var category = self.colors[block.colour_];
    classes.push(category);
    self.colors[getComputedStyle(block.svgPath_).fill] = category;

    //do things wth the inputs
    var substacks = 0;
    var inputBools = block.svgGroup_.querySelectorAll(":scope > path:not(.block-background)");
    for(let i = 0; i < inputBools.length; i++) {
      inputBools[i].classList.add("input", "input-background", "input-boolean");
    }
    for(let i = 0; i < block.inputList.length; i++) {
      let j = block.inputList[i];
      if(j.name.match(/SUBSTACK/)) {
        substacks++;
        if(j.connection && j.connection.targetConnection) { //if there's a block in the substack, push it to the queue
          queue.push([j.connection.targetConnection.sourceBlock_, db])
        }
      } else if(j.connection && j.connection.check_ == "Boolean") {
        //nothing, bools should already be taken care of
      } else if(j.connection) {
        let inputBlock = j.connection.targetConnection.sourceBlock_;
        if(inputBlock.isShadow_) {
          let inputGroup = inputBlock.svgGroup_;
          inputBlock.svgPath_.classList.add("input-background");
          inputGroup.classList.add("input");
          if(inputBlock.type.match(/number/)) {
            inputGroup.classList.add("input-number");
          } else if(inputBlock.type.match(/text/)) {
            inputGroup.classList.add("input-string");
          } else if(inputBlock.type.match(/menu|dropdown/)) {
            inputGroup.classList.add("input-dropdown");
          }
        } else {
          //if there's a non-shadow-block in the input, push it to the queue
          queue.push([inputBlock, db])
        }
      }
    }

    //icon class
    if(block.renderingMetrics_ && block.renderingMetrics_.imageField) {
      block.renderingMetrics_.imageField.imageElement_.classList.add("icon");
    }

    if(block.nextConnection && block.nextConnection.targetConnection) { //if there's a block conected to me, push it to the queue
      queue.push([block.nextConnection.targetConnection.sourceBlock_, db])
    }

    //figure out shape based on connectors and things
    if(!self.horizontal && !block.previousConnection && !block.startHat_) {
      classes.push("reporter");
      if(block.edgeShape_ == 1) {
        classes.push("boolean");
      } else if(block.edgeShape_ == 3) {
        classes.push("number");
      } else {
        classes.push("string");
      }
    } else {
      if(substacks) {
        classes.push("c-block");
        if(substacks > 1) {
          classes.push("else");
        }
      }
      if((self.horizontal) ? !block.previousConnection : block.startHat_) {
        classes.push("hat"); // because c-block/hats are very possible by just tweaking block definitions
      } else if(!substacks) {
        classes.push("stack"); //stack if it's not a c-block
      }
      if(!block.nextConnection) {
        classes.push("end");
      }
    }
    block.svgGroup_.classList.add.apply(block.svgGroup_.classList, classes);
    console.log([block, classes.join()]);

    for(let i in onChanges) {
      onChanges[i](block.type, block.svgGroup_, classes, block);
    }
  }

  var queue = [];
  var blocklyEvent = function(event, db) {
    if(event instanceof Blockly.Events.Create) {
      queue = [[db[event.blockId], db]];
      while(queue.length) {
        styleBlock(queue.pop());
      }
    }
  }

  var initSVG = function() {
    self.svg = document.querySelector('svg.blocklySvg');
    self.horizontal = !!Blockly.BlockSvg.IMAGE_FIELD_WIDTH;
    if(self.horizontal) {
      self.svg.classList.add("horizontal");
    } else {
      self.svg.classList.add("vertical");
    }

    self.colors = {}; // buil an object with the official color names for easy category detection
    for(let i in Blockly.Colours) {
      if(Blockly.Colours.hasOwnProperty(i) && typeof Blockly.Colours[i] == "object") {
        self.colors[Blockly.Colours[i]["primary"]] = i;
      }
    }

    //hijack replacement-rings
    var oldHighlightForReplacement = Blockly.BlockSvg.prototype.highlightForReplacement;
    Blockly.BlockSvg.prototype.highlightForReplacement = function(add) {
      if(add) {
        this.svgGroup_.classList.add("replaceable");
      } else {
        this.svgGroup_.classList.remove("replaceable");
      }
      oldHighlightForReplacement.apply(this, arguments);
    }

    //hijack dropown menus
    var oldDropdownShowEditor = Blockly.FieldDropdown.prototype.showEditor_;
    Blockly.FieldDropdown.prototype.showEditor_ = function() {
      oldDropdownShowEditor.apply(this, arguments);
      var menu = document.querySelector(".blocklyDropDownDiv");
      menu.classList.add("dropdown-menu", self.colors[menu.style.backgroundColor]);
    }

    //hijack icon menus
    var oldIconMenuShowEditor = Blockly.FieldIconMenu.prototype.showEditor_;
    Blockly.FieldIconMenu.prototype.showEditor_ = function() {
      oldIconMenuShowEditor.apply(this, arguments);
      console.log("a thing happened")
      var menu = document.querySelector(".blocklyDropDownDiv");
      menu.classList.add("dropdown-menu", self.colors[menu.style.backgroundColor]);
    }

    //hijack insertion-markers
    var oldSetInsertionMarker = Blockly.BlockSvg.prototype.setInsertionMarker;
    Blockly.BlockSvg.prototype.setInsertionMarker = function() {
      this.svgGroup_.classList.add("insertion-marker");
      oldSetInsertionMarker.apply(this, arguments);
    }

    var flyoutWorkspace = (workspace.flyout_) ? workspace.flyout_.workspace_ :
      workspace.toolbox_.flyout_.workspace_;

    flyoutWorkspace.addChangeListener(function(e) {
      blocklyEvent(e, flyoutWorkspace.blockDB_)
    });
    Blockly.mainWorkspace.addChangeListener(function(e) {
      blocklyEvent(e, Blockly.mainWorkspace.blockDB_)
    });

    runAddFilters();
  }

  // hang out until the SVG exists, then run the init function
  if(document.querySelector('svg.blocklySvg')) {
    initSVG();
  } else {
    var initObserver = new MutationObserver(function(mutations) {
      if(document.querySelector('svg.blocklySvg')) {
        initObserver.disconnect();
        initSVG();
      }
    });
    initObserver.observe(document.getElementsByTagName('html')[0], {childList: true, subtree: true}); // <body> doesn't always exist at runtime
  }
});
<commit_msg>add auto-coloring menus (#43)<commit_after>'use strict';

if(!window.sb3theme) window.sb3theme = new (function() {
  var self = this;

  this.options = {menuColors: true};

  this.css = document.createElement("style");
  document.head.appendChild(this.css);
  this.style = function(css) {
    this.css.innerHTML += css;
  }
  this.style(`.blocklyDropDownArrow {
        background: inherit !important;
        border-color: inherit !important;
      }`)

  var onChanges = [];
  this.onChange = function(func) {
    onChanges.push(func);
  }
  var addFilters = [];
  this.addFilter = function(filter) {
    addFilters.push(filter);
    if(this.svg) {
      runAddFilters();
    }
  }
  var runAddFilters = function() {
    var defs = self.svg.getElementsByTagName('defs')[0];
    var ns = Blockly.SVG_NS;
    while(addFilters.length) {
      let filter = addFilters.pop();
      var doc = new DOMParser().parseFromString(`<svg xmlns="` + ns + `">` + filter + `</svg>`, 'image/svg+xml');
      defs.appendChild( defs.ownerDocument.importNode(doc.documentElement.firstElementChild, true) );
    }
  }

  var styleBlock = function(queueitem) {
    var block = queueitem[0];
    var db = queueitem[1];
    block.svgPath_.classList.add("block-background");

    var classes = ["block"];
    var category = self.colors[block.colour_];
    classes.push(category);

    //do things wth the inputs
    var substacks = 0;
    var inputBools = block.svgGroup_.querySelectorAll(":scope > path:not(.block-background)");
    for(let i = 0; i < inputBools.length; i++) {
      inputBools[i].classList.add("input", "input-background", "input-boolean");
    }
    for(let i = 0; i < block.inputList.length; i++) {
      let j = block.inputList[i];
      if(j.name.match(/SUBSTACK/)) {
        substacks++;
        if(j.connection && j.connection.targetConnection) { //if there's a block in the substack, push it to the queue
          queue.push([j.connection.targetConnection.sourceBlock_, db])
        }
      } else if(j.connection && j.connection.check_ == "Boolean") {
        //nothing, bools should already be taken care of
      } else if(j.connection) {
        let inputBlock = j.connection.targetConnection.sourceBlock_;
        if(inputBlock.isShadow_) {
          let inputGroup = inputBlock.svgGroup_;
          inputBlock.svgPath_.classList.add("input-background");
          inputGroup.classList.add("input");
          if(inputBlock.type.match(/number/)) {
            inputGroup.classList.add("input-number");
          } else if(inputBlock.type.match(/text/)) {
            inputGroup.classList.add("input-string");
          } else if(inputBlock.type.match(/menu|dropdown/)) {
            inputGroup.classList.add("input-dropdown");
          }
        } else {
          //if there's a non-shadow-block in the input, push it to the queue
          queue.push([inputBlock, db])
        }
      }
    }

    //icon class
    if(block.renderingMetrics_ && block.renderingMetrics_.imageField) {
      block.renderingMetrics_.imageField.imageElement_.classList.add("icon");
    }

    if(block.nextConnection && block.nextConnection.targetConnection) { //if there's a block conected to me, push it to the queue
      queue.push([block.nextConnection.targetConnection.sourceBlock_, db])
    }

    //figure out shape based on connectors and things
    if(!self.horizontal && !block.previousConnection && !block.startHat_) {
      classes.push("reporter");
      if(block.edgeShape_ == 1) {
        classes.push("boolean");
      } else if(block.edgeShape_ == 3) {
        classes.push("number");
      } else {
        classes.push("string");
      }
    } else {
      if(substacks) {
        classes.push("c-block");
        if(substacks > 1) {
          classes.push("else");
        }
      }
      if((self.horizontal) ? !block.previousConnection : block.startHat_) {
        classes.push("hat"); // because c-block/hats are very possible by just tweaking block definitions
      } else if(!substacks) {
        classes.push("stack"); //stack if it's not a c-block
      }
      if(!block.nextConnection) {
        classes.push("end");
      }
    }
    block.svgGroup_.classList.add.apply(block.svgGroup_.classList, classes);
    console.log([block, classes.join()]);

    for(let i in onChanges) {
      onChanges[i](block.type, block.svgGroup_, classes, block);
    }
  }

  var queue = [];
  var blocklyEvent = function(event, db) {
    if(event instanceof Blockly.Events.Create) {
      queue = [[db[event.blockId], db]];
      while(queue.length) {
        styleBlock(queue.pop());
      }
    }
  }

  var initSVG = function() {
    self.svg = document.querySelector('svg.blocklySvg');
    self.horizontal = !!Blockly.BlockSvg.IMAGE_FIELD_WIDTH;
    if(self.horizontal) {
      self.svg.classList.add("horizontal");
    } else {
      self.svg.classList.add("vertical");
    }

    self.colors = {}; // build an object with the official color names for easy category detection
    for(let i in Blockly.Colours) {
      if(Blockly.Colours.hasOwnProperty(i) && typeof Blockly.Colours[i] == "object") {
        self.colors[Blockly.Colours[i]["primary"]] = i;
      }
    }

    //hijack replacement-rings
    var oldHighlightForReplacement = Blockly.BlockSvg.prototype.highlightForReplacement;
    Blockly.BlockSvg.prototype.highlightForReplacement = function(add) {
      if(add) {
        this.svgGroup_.classList.add("replaceable");
      } else {
        this.svgGroup_.classList.remove("replaceable");
      }
      oldHighlightForReplacement.apply(this, arguments);
    }

    //hijack dropown menus
    var oldDropdownShowEditor = Blockly.FieldDropdown.prototype.showEditor_;
    Blockly.FieldDropdown.prototype.showEditor_ = function() {
      oldDropdownShowEditor.apply(this, arguments);
      var menu = document.querySelector(".blocklyDropDownDiv");
      menu.classList.add("dropdown-menu", self.colors[this.sourceBlock_.parentBlock_.colour_]);
      if(self.options.menuColors) {
        menu.style.backgroundColor = getComputedStyle(this.sourceBlock_.parentBlock_.svgPath_).fill;
        menu.style.borderColor = getComputedStyle(this.sourceBlock_.parentBlock_.svgPath_).stroke;
      }
    }

    //hijack icon menus
    var oldIconMenuShowEditor = Blockly.FieldIconMenu.prototype.showEditor_;
    Blockly.FieldIconMenu.prototype.showEditor_ = function() {
      oldIconMenuShowEditor.apply(this, arguments);
      console.log("a thing happened")
      var menu = document.querySelector(".blocklyDropDownDiv");
      menu.classList.add("dropdown-menu", self.colors[menu.style.backgroundColor]);
    }

    //hijack insertion-markers
    var oldSetInsertionMarker = Blockly.BlockSvg.prototype.setInsertionMarker;
    Blockly.BlockSvg.prototype.setInsertionMarker = function() {
      this.svgGroup_.classList.add("insertion-marker");
      oldSetInsertionMarker.apply(this, arguments);
    }

    var flyoutWorkspace = (workspace.flyout_) ? workspace.flyout_.workspace_ :
      workspace.toolbox_.flyout_.workspace_;

    flyoutWorkspace.addChangeListener(function(e) {
      blocklyEvent(e, flyoutWorkspace.blockDB_)
    });
    Blockly.mainWorkspace.addChangeListener(function(e) {
      blocklyEvent(e, Blockly.mainWorkspace.blockDB_)
    });

    runAddFilters();
  }

  // hang out until the SVG exists, then run the init function
  if(document.querySelector('svg.blocklySvg')) {
    initSVG();
  } else {
    var initObserver = new MutationObserver(function(mutations) {
      if(document.querySelector('svg.blocklySvg')) {
        initObserver.disconnect();
        initSVG();
      }
    });
    initObserver.observe(document.getElementsByTagName('html')[0], {childList: true, subtree: true}); // <body> doesn't always exist at runtime
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/ui-icon';
const { Component, computed, observer, run } = Ember;

export default Component.extend({
  layout: layout,
  tagName: 'i',
  classNames: ['ui-icon'],
  classNameBindings: ['fontFamily','_fw', '_icon', '_classSize', 'spin:fa-spin', 'pulse:fa-pulse', 'border:fa-border', 'muted', 'cursor'],
  attributeBindings: ['_style:style'],
  fontFamily: 'fa',
  fw: true,
  _fw: Ember.on('init', computed('fw', function() {
    let fw = this.get('fw');
    let fontFamily = this.get('fontFamily');
    return fw ? `${fontFamily}-fw` : null;
  })),
  icon: null,
  _icon: computed('icon', function() {
    let family = this.get('fontFamily');
    let icon = this.get('icon');
    return icon ? `${family}-${icon}` : null;
  }),
  color: null,
  border: false,
  circular: false,
  _circular: observer('circular', function() {
    let circular = this.get('circular');
    if(circular) {
      run.next( ()=> {
        let height = this.$().height();
        this.set('_styleWidth', height + 'px');
        this.set('_styleBorderRadius', '50%');
        this.set('_styleTextAlign', 'center');
      });
    }
  }),
  size: null, // set by container
  _classSize: null,
  _styleFontSize: null,
  _styleBorderRadius: null,
  _styleWidth: null,
  _sizeObserver: observer('size', function() {
    let size = String(this.get('size'));
    if(size.substr(-2) === 'pt' || size.substr(-2) === 'em' || size.substr(-1) === '%') {
      this.set('_styleFontSize',size);
    } else if (size && size === 'lg') {
      this.set('_classSize', 'fa-lg');
    } else if (size && size.substr(-1) === 'x') {
      // fontsize multiplier
      let factor = size.substr(0,size.length - 1);
      if (factor > 10) {
        console.log('ui-icon has styling options up to 10x, not as high as %s. If you need bigger sizing use an explicit pixel size(px) or state a percentage number rather than a multiplier', factor);
      }
      if(factor) {
        this.set('_classSize', `scale-${factor}x`);
      }
    } // end scale factor
  }),
  value: null, // values are passed by an action
  _value: computed('value', 'elementId', function() {
    let { value, elementId } = this.getProperties('value','elementId');
    return value !== null ? value : elementId;
  }),
  click: function(evt) {
    let value = this.get('_value');
    this.sendAction('action', value); // general action
  },

  tooltip: false,
  tooltipPlacement: 'top',
  tooltipDelay: 500,
  tooltipHtml: true,
  tooltipTrigger: 'hover',
  tooltipTemplate: '

',
  _tooltipInit: Ember.on('didInsertElement', function() {
    let tooltip = this.get('tooltip');
    if(tooltip) {
      let {
        tooltipPlacement: placement,
        tooltipDelay: delay,
        tooltipHtml: html,
        tooltipTrigger: trigger,
        tooltipTemplate: template} = this.getProperties('tooltipPlacement', 'tooltipDelay','tooltipHtml','tooltipTrigger','tooltipTemplate');
      Ember.run.next( () => {
        try {
          this.$().tooltip({
            title: tooltip,
            delay: delay,
            html: html,
            trigger: trigger,
            placement: placement,
            template: template
          });
        } catch (e) {
          console.log('There was a problem setting up the tooltip on [' + this.get('elementId') + '], ensure Bootstrap\'s JS is included in the vendor JS.\n%o',e);
        }
      });
    }
  }),

  _style: Ember.computed('_styleWidth', '_styleFontSize', 'color', function() {
    const propMap = [
      {key: '_styleWidth', value: 'width'},
      {key: 'color', value: 'color'},
      {key: 'background', value: 'background-color'},
      {key: '_styleBorderRadius', value: 'border-radius'},
      {key: '_styleTextAlign', value: 'text-align'},
      {key: '_styleFontSize', value: 'font-size'}
    ];

    let style = '';

    propMap.forEach( (item) => {
      let styleProperty = this.get(item.key);
      if(styleProperty) {
        style = style + `;${item.value}:${styleProperty}`;
      }
    });

    return Ember.String.htmlSafe(style);
  }),

  _init: Ember.on('didInsertElement', function() {
    this._sizeObserver();
    this._circular();
  })

});

<commit_msg>remove unused variable<commit_after>import Ember from 'ember';
import layout from '../templates/components/ui-icon';
const { Component, computed, observer, run } = Ember;

export default Component.extend({
  layout: layout,
  tagName: 'i',
  classNames: ['ui-icon'],
  classNameBindings: ['fontFamily','_fw', '_icon', '_classSize', 'spin:fa-spin', 'pulse:fa-pulse', 'border:fa-border', 'muted', 'cursor'],
  attributeBindings: ['_style:style'],
  fontFamily: 'fa',
  fw: true,
  _fw: Ember.on('init', computed('fw', function() {
    let fw = this.get('fw');
    let fontFamily = this.get('fontFamily');
    return fw ? `${fontFamily}-fw` : null;
  })),
  icon: null,
  _icon: computed('icon', function() {
    let family = this.get('fontFamily');
    let icon = this.get('icon');
    return icon ? `${family}-${icon}` : null;
  }),
  color: null,
  border: false,
  circular: false,
  _circular: observer('circular', function() {
    let circular = this.get('circular');
    if(circular) {
      run.next( ()=> {
        let height = this.$().height();
        this.set('_styleWidth', height + 'px');
        this.set('_styleBorderRadius', '50%');
        this.set('_styleTextAlign', 'center');
      });
    }
  }),
  size: null, // set by container
  _classSize: null,
  _styleFontSize: null,
  _styleBorderRadius: null,
  _styleWidth: null,
  _sizeObserver: observer('size', function() {
    let size = String(this.get('size'));
    if(size.substr(-2) === 'pt' || size.substr(-2) === 'em' || size.substr(-1) === '%') {
      this.set('_styleFontSize',size);
    } else if (size && size === 'lg') {
      this.set('_classSize', 'fa-lg');
    } else if (size && size.substr(-1) === 'x') {
      // fontsize multiplier
      let factor = size.substr(0,size.length - 1);
      if (factor > 10) {
        console.log('ui-icon has styling options up to 10x, not as high as %s. If you need bigger sizing use an explicit pixel size(px) or state a percentage number rather than a multiplier', factor);
      }
      if(factor) {
        this.set('_classSize', `scale-${factor}x`);
      }
    } // end scale factor
  }),
  value: null, // values are passed by an action
  _value: computed('value', 'elementId', function() {
    let { value, elementId } = this.getProperties('value','elementId');
    return value !== null ? value : elementId;
  }),
  click: function() {
    let value = this.get('_value');
    this.sendAction('action', value); // general action
  },

  tooltip: false,
  tooltipPlacement: 'top',
  tooltipDelay: 500,
  tooltipHtml: true,
  tooltipTrigger: 'hover',
  tooltipTemplate: '

',
  _tooltipInit: Ember.on('didInsertElement', function() {
    let tooltip = this.get('tooltip');
    if(tooltip) {
      let {
        tooltipPlacement: placement,
        tooltipDelay: delay,
        tooltipHtml: html,
        tooltipTrigger: trigger,
        tooltipTemplate: template} = this.getProperties('tooltipPlacement', 'tooltipDelay','tooltipHtml','tooltipTrigger','tooltipTemplate');
      Ember.run.next( () => {
        try {
          this.$().tooltip({
            title: tooltip,
            delay: delay,
            html: html,
            trigger: trigger,
            placement: placement,
            template: template
          });
        } catch (e) {
          console.log('There was a problem setting up the tooltip on [' + this.get('elementId') + '], ensure Bootstrap\'s JS is included in the vendor JS.\n%o',e);
        }
      });
    }
  }),

  _style: Ember.computed('_styleWidth', '_styleFontSize', 'color', function() {
    const propMap = [
      {key: '_styleWidth', value: 'width'},
      {key: 'color', value: 'color'},
      {key: 'background', value: 'background-color'},
      {key: '_styleBorderRadius', value: 'border-radius'},
      {key: '_styleTextAlign', value: 'text-align'},
      {key: '_styleFontSize', value: 'font-size'}
    ];

    let style = '';

    propMap.forEach( (item) => {
      let styleProperty = this.get(item.key);
      if(styleProperty) {
        style = style + `;${item.value}:${styleProperty}`;
      }
    });

    return Ember.String.htmlSafe(style);
  }),

  _init: Ember.on('didInsertElement', function() {
    this._sizeObserver();
    this._circular();
  })

});

<|endoftext|>


<commit_before>'use strict';

goog.provide('Blockly.Blocks.actuator');
goog.require('Blockly.Blocks');

Blockly.Blocks.actuator.HUE = 100

//Servo
Blockly.Blocks.servo_move = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_SERVO)
            .appendField(Blockly.MIXLY_PIN + " #")
            .setCheck(Number);
        this.appendValueInput("DEGREE", Number)
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_DEGREE_0_180);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_SERVO_MOVE);
    }
};

//LED
Blockly.Blocks['number'] = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(new Blockly.FieldDropdown([
                ["1", "1"],
                ["2", "2"]
            ]), 'op')
        this.setOutput(true);
    }
};

Blockly.Blocks['ledswitch'] = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(new Blockly.FieldDropdown([
                [Blockly.MIXLY_ESP32_ON, "1"],
                [Blockly.MIXLY_ESP32_OFF, "0"],
                [Blockly.MIXLY_ESP32_TOGGLE, "-1"]
            ]), "flag");
        this.setOutput(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_INOUT_HIGHLOW);
    }
};

Blockly.Blocks.actuator_led_bright = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_SETTING);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendValueInput('bright')
    .appendField(Blockly.MIXLY_PULSEIN_STAT)
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_SETONOFF);
  }
};

Blockly.Blocks.actuator_get_led_bright = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_MICROBIT_PY_STORAGE_GET);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_PULSEIN_STAT)
    this.setOutput(true);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_GETONOFF);
  }
};

Blockly.Blocks.actuator_led_brightness = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_SETTING);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendValueInput('bright')
    .appendField(Blockly.MIXLY_MICROBIT_JS_MONITOR_BRIGHTNESS)
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_SETBRIGHT);
  }
};

//music
Blockly.Blocks.esp32_music_pitch = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_MBOT_TONE)
            .appendField(Blockly.MIXLY_PIN + " #")
            .setCheck(Number);
        this.appendValueInput('pitch')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_FREQUENCY);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_BLOCKGROUP_TONE);
    }
};

Blockly.Blocks.esp32_music_pitch_with_time = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_MBOT_TONE)
            .appendField(Blockly.MIXLY_PIN + " #")
            .setCheck(Number);
        this.appendValueInput('pitch')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_FREQUENCY);
        this.appendValueInput('time')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_DURATION);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_BLOCKGROUP_TONE2);
    }
};

Blockly.Blocks.esp32_music_stop = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_NOTONE_PIN)
            .setCheck(Number);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
    }
};

Blockly.Blocks.esp32_music_set_tempo = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('TICKS')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_MICROBIT_JS_SET_TEMPO)
            .appendField(Blockly.MICROBIT_ACTUATOR_ticks);
        this.appendValueInput('BPM')
            .setCheck(Number)
            .appendField(Blockly.MICROBIT_ACTUATOR_bpm);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_SET_TEMPO);
    }
}

Blockly.Blocks.esp32_music_get_tempo = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_MICROBIT_Get_current_tempo)
        this.setOutput(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_GET_TEMPO);
    }
}

Blockly.Blocks.esp32_music_reset = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_MICROBIT_Reset_music)
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_RESET);
    }
}

Blockly.Blocks.esp32_music_play_list = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('LIST')
            .appendField(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS)
        this.appendValueInput('PIN')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_PIN + " #");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS);

    }
}

Blockly.Blocks.esp32_mixgo_music_play_list_show = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('LIST')
            .appendField(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS)
        this.appendValueInput('PIN')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_PIN + " #");
        // this.appendValueInput('DISPLAY')
        //     .appendField(Blockly.MIXLY_ESP32_MIXGO_MUSIC_SHOW_IN);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_ESP32_MIXGO_MUSIC_PLAY_TONE);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_PLAYSHOW)
    }
}
//RGB
Blockly.Blocks.actuator_neopixel_init = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
        this.appendValueInput('SUB')
            .appendField(Blockly.MIXLY_SETUP)
            .setCheck("var");
        this.appendValueInput("PIN", Number)
           .setCheck(Number)
           .setAlign(Blockly.ALIGN_RIGHT)
           .appendField(Blockly.MIXLY_PIN+" #");
        this.appendValueInput("LEDCOUNT")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_COUNT);
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip(Blockly.MIXLY_RGB_PIN_COUNT);
    }
};

Blockly.Blocks.actuator_neopixel_rgb = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
        this.appendValueInput('SUB')
            .setCheck("var");
            // .appendField(Blockly.MIXLY_SETUP)
        this.appendValueInput("_LED_")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_NUM);
        this.appendValueInput("RVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_R);
        this.appendValueInput("GVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_G);
        this.appendValueInput("BVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_B);
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
        this.setTooltip(Blockly.MIXLY_RGB_NUM_R_G_B);
    }
};

Blockly.Blocks.actuator_neopixel_write = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
         // this.appendValueInput("PIN", Number)
         //    .setCheck(Number)
         //    .setAlign(Blockly.ALIGN_RIGHT)
         //    .appendField(Blockly.MIXLY_PIN);
        this.appendValueInput('SUB')
            .setCheck("var");
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_ESP32_RGB_WRITE)
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_WRI);
    }
};

Blockly.Blocks.led_light=Blockly.Blocks.actuator_led_bright;
Blockly.Blocks.get_led_bright=Blockly.Blocks.actuator_get_led_bright;
Blockly.Blocks.led_brightness=Blockly.Blocks.actuator_led_brightness;
<commit_msg>Delete duplicate '#'<commit_after>'use strict';

goog.provide('Blockly.Blocks.actuator');
goog.require('Blockly.Blocks');

Blockly.Blocks.actuator.HUE = 100

//Servo
Blockly.Blocks.servo_move = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_SERVO)
            .appendField(Blockly.MIXLY_PIN )
            .setCheck(Number);
        this.appendValueInput("DEGREE", Number)
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_DEGREE_0_180);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_SERVO_MOVE);
    }
};

//LED
Blockly.Blocks['number'] = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(new Blockly.FieldDropdown([
                ["1", "1"],
                ["2", "2"]
            ]), 'op')
        this.setOutput(true);
    }
};

Blockly.Blocks['ledswitch'] = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(new Blockly.FieldDropdown([
                [Blockly.MIXLY_ESP32_ON, "1"],
                [Blockly.MIXLY_ESP32_OFF, "0"],
                [Blockly.MIXLY_ESP32_TOGGLE, "-1"]
            ]), "flag");
        this.setOutput(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_INOUT_HIGHLOW);
    }
};

Blockly.Blocks.actuator_led_bright = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_SETTING);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendValueInput('bright')
    .appendField(Blockly.MIXLY_PULSEIN_STAT)
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_SETONOFF);
  }
};

Blockly.Blocks.actuator_get_led_bright = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_MICROBIT_PY_STORAGE_GET);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_PULSEIN_STAT)
    this.setOutput(true);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_GETONOFF);
  }
};

Blockly.Blocks.actuator_led_brightness = {
  init: function() {
    this.setColour(Blockly.Blocks.actuator.HUE);
    this.appendDummyInput()
    .appendField(Blockly.MIXLY_SETTING);
    this.appendValueInput('led')
    .appendField(Blockly.MIXLY_BUILDIN_LED)
    this.appendValueInput('bright')
    .appendField(Blockly.MIXLY_MICROBIT_JS_MONITOR_BRIGHTNESS)
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setInputsInline(true);
    this.setTooltip(Blockly.MIXLY_ESP32_LED_SETBRIGHT);
  }
};

//music
Blockly.Blocks.esp32_music_pitch = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_MBOT_TONE)
            .appendField(Blockly.MIXLY_PIN )
            .setCheck(Number);
        this.appendValueInput('pitch')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_FREQUENCY);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_BLOCKGROUP_TONE);
    }
};

Blockly.Blocks.esp32_music_pitch_with_time = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_MBOT_TONE)
            .appendField(Blockly.MIXLY_PIN )
            .setCheck(Number);
        this.appendValueInput('pitch')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_FREQUENCY);
        this.appendValueInput('time')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_DURATION);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip(Blockly.MIXLY_TOOLTIP_BLOCKGROUP_TONE2);
    }
};

Blockly.Blocks.esp32_music_stop = {
    init: function() {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput("PIN", Number)
            .appendField(Blockly.MIXLY_NOTONE_PIN)
            .setCheck(Number);
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
    }
};

Blockly.Blocks.esp32_music_set_tempo = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('TICKS')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_MICROBIT_JS_SET_TEMPO)
            .appendField(Blockly.MICROBIT_ACTUATOR_ticks);
        this.appendValueInput('BPM')
            .setCheck(Number)
            .appendField(Blockly.MICROBIT_ACTUATOR_bpm);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_SET_TEMPO);
    }
}

Blockly.Blocks.esp32_music_get_tempo = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_MICROBIT_Get_current_tempo)
        this.setOutput(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_GET_TEMPO);
    }
}

Blockly.Blocks.esp32_music_reset = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_MICROBIT_Reset_music)
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_RESET);
    }
}

Blockly.Blocks.esp32_music_play_list = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('LIST')
            .appendField(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS)
        this.appendValueInput('PIN')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_PIN );
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS);

    }
}

Blockly.Blocks.esp32_mixgo_music_play_list_show = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendValueInput('LIST')
            .appendField(Blockly.MIXLY_ESP32_MUSIC_PLAY_LISTS)
        this.appendValueInput('PIN')
            .setCheck(Number)
            .appendField(Blockly.MIXLY_PIN );
        // this.appendValueInput('DISPLAY')
        //     .appendField(Blockly.MIXLY_ESP32_MIXGO_MUSIC_SHOW_IN);
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_ESP32_MIXGO_MUSIC_PLAY_TONE);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(true);
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_PLAYSHOW)
    }
}
//RGB
Blockly.Blocks.actuator_neopixel_init = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
        this.appendValueInput('SUB')
            .appendField(Blockly.MIXLY_SETUP)
            .setCheck("var");
        this.appendValueInput("PIN", Number)
           .setCheck(Number)
           .setAlign(Blockly.ALIGN_RIGHT)
           .appendField(Blockly.MIXLY_PIN);
        this.appendValueInput("LEDCOUNT")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_COUNT);
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip(Blockly.MIXLY_RGB_PIN_COUNT);
    }
};

Blockly.Blocks.actuator_neopixel_rgb = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
        this.appendValueInput('SUB')
            .setCheck("var");
            // .appendField(Blockly.MIXLY_SETUP)
        this.appendValueInput("_LED_")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_NUM);
        this.appendValueInput("RVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_R);
        this.appendValueInput("GVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_G);
        this.appendValueInput("BVALUE")
            .setCheck(Number)
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(Blockly.MIXLY_RGB_B);
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
        this.setTooltip(Blockly.MIXLY_RGB_NUM_R_G_B);
    }
};

Blockly.Blocks.actuator_neopixel_write = {
    init: function () {
        this.setColour(Blockly.Blocks.actuator.HUE);
        this.appendDummyInput("")
            .appendField(Blockly.MIXLY_RGB)
         // this.appendValueInput("PIN", Number)
         //    .setCheck(Number)
         //    .setAlign(Blockly.ALIGN_RIGHT)
         //    .appendField(Blockly.MIXLY_PIN);
        this.appendValueInput('SUB')
            .setCheck("var");
        this.appendDummyInput()
            .appendField(Blockly.MIXLY_ESP32_RGB_WRITE)
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
        this.setTooltip(Blockly.MIXLY_ESP32_MUSIC_WRI);
    }
};

Blockly.Blocks.led_light=Blockly.Blocks.actuator_led_bright;
Blockly.Blocks.get_led_bright=Blockly.Blocks.actuator_get_led_bright;
Blockly.Blocks.led_brightness=Blockly.Blocks.actuator_led_brightness;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { Panel } from 'react-bootstrap';
import FontAwesome from 'react-fontawesome';

require('./RecentLists.css');

function RecentLists(props) {

  return (
    <Panel className='recent-lists'>
      Others want to
      {
        props.lists.map(list => (
          <div
            className='list-link'
            key={list.cuid}>
            <FontAwesome
              name='angle-right'
              className='bullet-icon' />
            <Link to={`/lists/${list.cuid}`} >
              {list.name}
            </Link>
          </div>
        ))
      }
    </Panel>
  )
}

RecentLists.propTypes = {
  lists: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    cuid: PropTypes.string.isRequired,
  })).isRequired,
};

export default RecentLists;
<commit_msg>unique on recent lists<commit_after>import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { Panel } from 'react-bootstrap';
import FontAwesome from 'react-fontawesome';
import * as _ from 'lodash';

require('./RecentLists.css');

function RecentLists(props) {

  return (
    <Panel className='recent-lists'>
      Others want to
      {
        _.uniqBy(props.lists, 'name')
          .map(list => (
            <div
              className='list-link'
              key={list.cuid}>
              <FontAwesome
                name='angle-right'
                className='bullet-icon' />
              <Link to={`/lists/${list.cuid}`} >
                {list.name}
              </Link>
            </div>
          ))
      }
    </Panel>
  )
}

RecentLists.propTypes = {
  lists: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    cuid: PropTypes.string.isRequired,
  })).isRequired,
};

export default RecentLists;
<|endoftext|>


<commit_before>exports.version=1398133981
<commit_msg>update the client/hub version, since the next update -- new sync -- will require users to do a browser refresh<commit_after>exports.version=1399347019
<|endoftext|>