初始化提交
This commit is contained in:
1292
mixly-sw/mixly-modules/common/board-manager.js
Normal file
1292
mixly-sw/mixly-modules/common/board-manager.js
Normal file
File diff suppressed because it is too large
Load Diff
66
mixly-sw/mixly-modules/common/config.js
Normal file
66
mixly-sw/mixly-modules/common/config.js
Normal file
@@ -0,0 +1,66 @@
|
||||
(() => {
|
||||
|
||||
goog.require('Mixly.Url');
|
||||
goog.require('Mixly.LocalStorage');
|
||||
goog.provide('Mixly.Config');
|
||||
|
||||
const {
|
||||
Url,
|
||||
LocalStorage,
|
||||
Config
|
||||
} = Mixly;
|
||||
|
||||
Config.USER = {
|
||||
theme: 'light',
|
||||
language: 'zh-hans',
|
||||
winSize: 1,
|
||||
blockRenderer: 'geras',
|
||||
compileCAndH: 'true',
|
||||
boardIgnore: []
|
||||
};
|
||||
|
||||
/**
|
||||
* @function 读取软件、板卡的配置信息
|
||||
* @return {void}
|
||||
**/
|
||||
Config.init = () => {
|
||||
Config.SOFTWARE = goog.getJSON('./sw-config.json', {});
|
||||
console.log('Config.SOFTWARE:', Config.SOFTWARE);
|
||||
Config.BOARDS_INFO = goog.getJSON('./boards.json', {});
|
||||
console.log('Config.BOARDS_INFO:', Config.BOARDS_INFO);
|
||||
const boardPageConfig = Url.getConfig();
|
||||
Config.BOARD_PAGE = boardPageConfig ?? {};
|
||||
console.log('Config.BOARD_PAGE:', Config.BOARD_PAGE);
|
||||
document.title = Config.SOFTWARE.version ?? 'Mixly 2.0';
|
||||
|
||||
Config.USER = {
|
||||
...Config.USER,
|
||||
...LocalStorage.get(LocalStorage.PATH['USER']) ?? {}
|
||||
};
|
||||
|
||||
if (Config.USER.themeAuto) {
|
||||
const themeMedia = window.matchMedia("(prefers-color-scheme: light)");
|
||||
Config.USER.theme = themeMedia.matches ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
if (Config.USER.languageAuto) {
|
||||
switch (navigator.language) {
|
||||
case 'zh-CN':
|
||||
Config.USER.language = 'zh-hans';
|
||||
break;
|
||||
case 'zh-HK':
|
||||
case 'zh-SG':
|
||||
case 'zh-TW':
|
||||
Config.USER.language = 'zh-hant';
|
||||
break;
|
||||
default:
|
||||
Config.USER.language = 'en';
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Config.USER', Config.USER);
|
||||
}
|
||||
|
||||
Config.init();
|
||||
|
||||
})();
|
||||
78
mixly-sw/mixly-modules/common/env.js
Normal file
78
mixly-sw/mixly-modules/common/env.js
Normal file
@@ -0,0 +1,78 @@
|
||||
(() => {
|
||||
|
||||
goog.require('path');
|
||||
goog.require('Mixly');
|
||||
goog.require('Mixly.Config');
|
||||
goog.provide('Mixly.Env');
|
||||
|
||||
const fs_extra = Mixly.require('fs-extra');
|
||||
const fs_plus = Mixly.require('fs-plus');
|
||||
const electron_remote = Mixly.require('@electron/remote');
|
||||
|
||||
const { Env, Config } = Mixly;
|
||||
|
||||
const { SOFTWARE } = Config;
|
||||
|
||||
/**
|
||||
* 获取当前mixly2.0的路径
|
||||
* @type {String}
|
||||
*/
|
||||
Env.clientPath = null;
|
||||
|
||||
/**
|
||||
* 检测当前系统
|
||||
* @type {String} win32、darwin、linux
|
||||
*/
|
||||
Env.currentPlatform = goog.platform();
|
||||
|
||||
/**
|
||||
* 获取板卡index或主页面index的路径
|
||||
* @type {String}
|
||||
*/
|
||||
Env.indexDirPath = path.join((new URL($('html')[0].baseURI)).href, '../').replace(/file:\/+/g, '');
|
||||
Env.indexDirPath = decodeURIComponent(Env.indexDirPath);
|
||||
if (Env.currentPlatform !== 'win32') {
|
||||
Env.indexDirPath = '/' + Env.indexDirPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否启用node服务器
|
||||
* @type {Boolean}
|
||||
*/
|
||||
Env.hasSocketServer = SOFTWARE?.webSocket?.enabled ? true : false;
|
||||
|
||||
/**
|
||||
* 检测是否启用node编译服务器
|
||||
* @type {Boolean}
|
||||
*/
|
||||
Env.hasCompiler = SOFTWARE?.webCompiler?.enabled ? true : false;
|
||||
|
||||
Env.thirdPartyBoardPath = path.join(Env.indexDirPath, 'boards/extend');
|
||||
|
||||
if (goog.isElectron) {
|
||||
const { app } = electron_remote;
|
||||
const { currentPlatform } = Env;
|
||||
if (currentPlatform === "darwin") {
|
||||
Env.clientPath = path.join(app.getPath("exe"), '../../../../');
|
||||
} else {
|
||||
Env.clientPath = path.join(app.getPath("exe"), '../');
|
||||
}
|
||||
if (Env.currentPlatform === "darwin" || Env.currentPlatform === "linux") {
|
||||
Env.python3Path = '/usr/bin/python3';
|
||||
} else {
|
||||
Env.python3Path = path.join(Env.clientPath, 'mixpyBuild/win_python3/python3.exe');
|
||||
}
|
||||
|
||||
Env.arduinoCliPath = path.join(Env.clientPath, 'arduino-cli/');
|
||||
const cliFilePath = path.join(Env.arduinoCliPath, 'arduino-cli' + (currentPlatform === 'win32'? '.exe':''));
|
||||
if (!fs_plus.isFileSync(cliFilePath)) {
|
||||
const defaultPath = SOFTWARE?.defaultPath[currentPlatform] ?? null;
|
||||
if (defaultPath?.arduinoCli) {
|
||||
Env.arduinoCliPath = path.join(Env.clientPath, defaultPath.arduinoCli, '../');
|
||||
} else {
|
||||
Env.arduinoCliPath = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})()
|
||||
141
mixly-sw/mixly-modules/common/events.js
Normal file
141
mixly-sw/mixly-modules/common/events.js
Normal file
@@ -0,0 +1,141 @@
|
||||
goog.loadJs('electron', () => {
|
||||
|
||||
goog.require('Mixly.BoardManager');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.Url');
|
||||
goog.provide('Mixly.Events');
|
||||
|
||||
const {
|
||||
BoardManager,
|
||||
Env,
|
||||
Config,
|
||||
Url,
|
||||
Events
|
||||
} = Mixly;
|
||||
|
||||
const fs = Mixly.require('fs');
|
||||
const electron = Mixly.require('electron');
|
||||
const electron_remote = Mixly.require('@electron/remote');
|
||||
const { ipcRenderer } = electron;
|
||||
const { USER } = Config;
|
||||
|
||||
ipcRenderer.on('ping', (event, message) => {
|
||||
console.log(message);
|
||||
var messageObj = null;
|
||||
try {
|
||||
messageObj = JSON.parse(message);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
if (messageObj?.type == "update") {
|
||||
if (USER.autoUpdate !== 'no') {
|
||||
const contentData = `<div style="padding: 50px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;text-align: center;">有可用更新,是否立即下载<br /><b style="font-size: 10px;color: #fff;">版本:${messageObj?.oldVersion} → ${messageObj?.newVersion}</b><br /><b style="color: #f70a2b;">注意:</b><br /><p style="color: #f70a2b;">更新时会关闭所有Mixly窗口!</p></div>`;
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: false,
|
||||
closeBtn: false,
|
||||
area: '300px',
|
||||
shade: 0.8,
|
||||
id: 'LAY_layuipro',
|
||||
btn: ['稍后提醒', '立即更新'],
|
||||
btnAlign: 'c',
|
||||
moveType: 1,
|
||||
content: contentData,
|
||||
resize: false,
|
||||
success: function (layero) {
|
||||
},
|
||||
btn2: function () {
|
||||
ipcRenderer.send('ping', "update");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ipcRenderer.on('open-file', (event, message) => {
|
||||
function getBoardFromXml(xml) {
|
||||
if (xml.indexOf("board=\"") === -1) {
|
||||
var idxa = xml.indexOf("board=\\\"") + 7;
|
||||
var idxb = xml.indexOf("\"", idxa + 1);
|
||||
if (idxa !== -1 && idxb !== -1 && idxb > idxa)
|
||||
return xml.substring(idxa + 1, idxb - 1);
|
||||
} else {
|
||||
var idxa = xml.indexOf("board=\"") + 6;
|
||||
var idxb = xml.indexOf("\"", idxa + 1);
|
||||
if (idxa !== -1 && idxb !== -1 && idxb > idxa)
|
||||
return xml.substring(idxa + 1, idxb);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
let mixStr = fs.readFileSync(message, "utf8");
|
||||
let boardType = getBoardFromXml(mixStr);
|
||||
if (boardType && boardType.indexOf('@') !== -1) {
|
||||
boardType = boardType.substring(0, boardType.indexOf('@'));
|
||||
} else if (boardType && boardType.indexOf('/') !== -1) {
|
||||
boardType = boardType.substring(0, boardType.indexOf('/'));
|
||||
}
|
||||
if (boardType) {
|
||||
BoardManager.loadBoards();
|
||||
const { boardsList } = BoardManager;
|
||||
for (let i = 0; i < boardsList.length; i++) {
|
||||
if (boardsList[i].boardType === boardType) {
|
||||
boardsList[i].filePath = message;
|
||||
const {
|
||||
boardType,
|
||||
boardIndex,
|
||||
boardImg,
|
||||
thirdPartyBoard,
|
||||
filePath
|
||||
} = boardsList[i];
|
||||
let boardJson = JSON.parse(JSON.stringify({
|
||||
boardType,
|
||||
boardIndex,
|
||||
boardImg,
|
||||
thirdPartyBoard,
|
||||
filePath
|
||||
}));
|
||||
let params = "id=error";
|
||||
try {
|
||||
params = Url.jsonToUrl(boardJson);
|
||||
window.location.href = "./boards/index.html?" + params;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(function () {
|
||||
alert("未找到" + boardType + "板卡!");
|
||||
}, 500);
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
alert("未在文件内找到板卡名!");
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
ipcRenderer.on('command', (event, command) => {
|
||||
let commandObj = null;
|
||||
try {
|
||||
commandObj = JSON.parse(command);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
const defaultCommand = {
|
||||
obj: '',
|
||||
func: '',
|
||||
args: []
|
||||
};
|
||||
commandObj = {
|
||||
...defaultCommand,
|
||||
...commandObj
|
||||
}
|
||||
if (commandObj.obj === 'Mixly.Electron.Loader' && commandObj.func === 'reload') {
|
||||
const currentWindow = electron_remote.getCurrentWindow();
|
||||
currentWindow.reload();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
91
mixly-sw/mixly-modules/common/loader.js
Normal file
91
mixly-sw/mixly-modules/common/loader.js
Normal file
@@ -0,0 +1,91 @@
|
||||
(() => {
|
||||
|
||||
goog.require('layui');
|
||||
goog.require('Mixly.Url');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.BoardManager');
|
||||
goog.require('Mixly.XML');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.XML');
|
||||
goog.require('Mixly.Setting');
|
||||
goog.require('Mixly.Events');
|
||||
goog.require('Mixly.Electron.PythonShell');
|
||||
goog.require('Mixly.WebSocket.Socket');
|
||||
goog.provide('Mixly.Loader');
|
||||
|
||||
const {
|
||||
Url,
|
||||
Env,
|
||||
Config,
|
||||
BoardManager,
|
||||
XML,
|
||||
Setting,
|
||||
Electron,
|
||||
Loader
|
||||
} = Mixly;
|
||||
|
||||
const { carousel } = layui;
|
||||
|
||||
const { BOARD_PAGE } = Config;
|
||||
|
||||
const { PythonShell } = Electron;
|
||||
|
||||
Loader.init = () => {
|
||||
$('body').append(XML.TEMPLATE_STR['INTERFACE']);
|
||||
if (goog.isElectron) {
|
||||
PythonShell.init();
|
||||
}
|
||||
if (Env.hasSocketServer) {
|
||||
const { Socket } = Mixly.WebSocket;
|
||||
Socket.init();
|
||||
}
|
||||
BoardManager.loadBoards();
|
||||
BoardManager.updateBoardsCard();
|
||||
Setting.init();
|
||||
window.addEventListener('resize', BoardManager.updateBoardsCard, false);
|
||||
carousel.on('change(board-switch-filter)', function (obj) {
|
||||
const boardType = obj.item.find('.mixly-board').find('h2').html() ?? 'Add';
|
||||
history.replaceState({}, "", Url.changeURLArg(window.location.href, "boardType", boardType));
|
||||
BOARD_PAGE.boardType = boardType;
|
||||
});
|
||||
|
||||
$("#loading").fadeOut("normal", () => {
|
||||
$('#loading').remove();
|
||||
});
|
||||
|
||||
if (goog.isElectron) {
|
||||
(function(window, document) {
|
||||
var url = 'http://mixly.org/assets/app20.html';
|
||||
function detect() {
|
||||
var iframes = document.getElementsByTagName('iframe');
|
||||
for (var i = 0; i < iframes.length; i++) {
|
||||
if (iframes[0].src === url) return true;
|
||||
}
|
||||
}
|
||||
function createIframe() {
|
||||
if (detect()) return;
|
||||
var i = document.createElement("iframe");
|
||||
i.src = url;
|
||||
i.width = '0';
|
||||
i.height = '0';
|
||||
i.style.display = 'none';
|
||||
document.body.appendChild(i);
|
||||
}
|
||||
createIframe();
|
||||
})(window, document);
|
||||
} else {
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?c06a333a8909f6abd97020e6e0929d60";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
Loader.init();
|
||||
});
|
||||
|
||||
})();
|
||||
31
mixly-sw/mixly-modules/common/msg.js
Normal file
31
mixly-sw/mixly-modules/common/msg.js
Normal file
@@ -0,0 +1,31 @@
|
||||
(() => {
|
||||
|
||||
goog.require('Mixly.MJSON');
|
||||
goog.require('Mixly.Config');
|
||||
goog.provide('Mixly.Msg');
|
||||
|
||||
const { Msg, MJSON, Config } = Mixly;
|
||||
|
||||
const { USER } = Config;
|
||||
|
||||
Msg.LANG_PATH = {
|
||||
"zh-hans": "./mixly-sw/msg/zh-hans.json",
|
||||
"zh-hant": "./mixly-sw/msg/zh-hant.json",
|
||||
"en": "./mixly-sw/msg/en.json"
|
||||
}
|
||||
|
||||
Msg.LANG = {
|
||||
"zh-hans": MJSON.get(Msg.LANG_PATH["zh-hans"]),
|
||||
"zh-hant": MJSON.get(Msg.LANG_PATH["zh-hant"]),
|
||||
"en": MJSON.get(Msg.LANG_PATH["en"])
|
||||
}
|
||||
|
||||
Msg.nowLang = USER.language ?? 'zh-hans';
|
||||
|
||||
Msg.getLang = (str) => {
|
||||
return Msg.LANG[Msg.nowLang][str];
|
||||
}
|
||||
|
||||
console.log('Msg.LANG', Msg.LANG);
|
||||
|
||||
})();
|
||||
317
mixly-sw/mixly-modules/common/setting.js
Normal file
317
mixly-sw/mixly-modules/common/setting.js
Normal file
@@ -0,0 +1,317 @@
|
||||
(() => {
|
||||
|
||||
goog.require('ace');
|
||||
goog.require('ace.ExtLanguageTools');
|
||||
goog.require('layui');
|
||||
goog.require('layui.loading');
|
||||
goog.require('store');
|
||||
goog.require('$.select2');
|
||||
goog.require('Mixly.XML');
|
||||
goog.require('Mixly.LayerExt');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.BoardManager');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.MJSON');
|
||||
goog.require('Mixly.Storage');
|
||||
goog.require('Mixly.WebSocket.Socket');
|
||||
goog.provide('Mixly.Setting');
|
||||
|
||||
const {
|
||||
XML,
|
||||
LayerExt,
|
||||
Msg,
|
||||
BoardManager,
|
||||
Config,
|
||||
Env,
|
||||
MJSON,
|
||||
Storage,
|
||||
Setting
|
||||
} = Mixly;
|
||||
|
||||
const { LANG } = Msg;
|
||||
const { element, form, loading, layer } = layui;
|
||||
const { USER, SOFTWARE } = Config;
|
||||
|
||||
Setting.ID = 'setting-menu';
|
||||
Setting.CONFIG = {}
|
||||
Setting.nowIndex = 0;
|
||||
Setting.config = {};
|
||||
|
||||
Setting.init = () => {
|
||||
element.tab({
|
||||
headerElem: '#setting-menu-options>li',
|
||||
bodyElem: '#setting-menu-body>.menu-body'
|
||||
});
|
||||
element.render('nav', 'setting-menu-filter');
|
||||
Setting.addOnchangeOptionListener();
|
||||
|
||||
form.on('switch(setting-theme-filter)', function(data) {
|
||||
const { checked } = data.elem;
|
||||
USER.theme = checked ? 'dark' : 'light';
|
||||
$('body').removeClass('dark light')
|
||||
.addClass(USER.theme);
|
||||
$('html').attr('data-bs-theme', USER.theme);
|
||||
Storage.user('/', USER);
|
||||
});
|
||||
|
||||
form.on('submit(open-setting-dialog-filter)', function(data) {
|
||||
Setting.onclick();
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(board-reset-filter)', function(data) {
|
||||
BoardManager.resetBoard((error) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
}
|
||||
BoardManager.screenWidthLevel = -1;
|
||||
BoardManager.screenHeightLevel = -1;
|
||||
BoardManager.loadBoards();
|
||||
BoardManager.updateBoardsCard();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Setting.menuInit = () => {
|
||||
$('#setting-menu-options').children('.layui-this').removeClass('layui-this');
|
||||
$('#setting-menu-options').children('li').first().addClass('layui-this');
|
||||
$('#setting-menu-body').children('.layui-show').removeClass('layui-show');
|
||||
$('#setting-menu-body').children('div').first().addClass('layui-show');
|
||||
form.render(null, 'setting-form-filter');
|
||||
form.val('setting-form-filter', USER);
|
||||
}
|
||||
|
||||
Setting.onclick = () => {
|
||||
Setting.menuInit();
|
||||
let obj = $(".setting-menu-item").select2({
|
||||
width: '100%',
|
||||
minimumResultsForSearch: 10
|
||||
});
|
||||
Setting.configMenuSetValue(obj, USER);
|
||||
element.render('collapse', 'menu-user-collapse-filter');
|
||||
Setting.nowIndex = 0;
|
||||
LayerExt.open({
|
||||
title: [Msg.getLang('SETTING'), '36px'],
|
||||
id: 'setting-menu-layer',
|
||||
content: $('#' + Setting.ID),
|
||||
shade: LayerExt.SHADE_ALL,
|
||||
area: ['50%', '50%'],
|
||||
min: ['400px', '200px'],
|
||||
success: () => {
|
||||
}
|
||||
});
|
||||
$('#setting-menu-user button').off().click((event) => {
|
||||
const type = $(event.currentTarget).attr('value');
|
||||
switch (type) {
|
||||
case 'apply':
|
||||
let oldTheme = USER.themeAuto? 'auto' : USER.theme;
|
||||
let oldLanglage = USER.languageAuto? 'auto' : USER.language;
|
||||
let updateTheme = false, updateLanguage = false;
|
||||
let value = Setting.configMenuGetValue(obj);
|
||||
for (let i in value) {
|
||||
USER[i] = value[i];
|
||||
}
|
||||
updateTheme = oldTheme !== USER.theme;
|
||||
updateLanguage = oldLanglage !== USER.language;
|
||||
if (updateTheme) {
|
||||
if (USER.theme === 'auto') {
|
||||
const themeMedia = window.matchMedia("(prefers-color-scheme: light)");
|
||||
USER.theme = themeMedia.matches ? 'light' : 'dark';
|
||||
USER.themeAuto = true;
|
||||
} else {
|
||||
USER.themeAuto = false;
|
||||
}
|
||||
$('body').removeClass('dark light')
|
||||
.addClass(USER.theme);
|
||||
$('html').attr('data-bs-theme', USER.theme);
|
||||
}
|
||||
if (updateLanguage) {
|
||||
if (USER.language === 'auto') {
|
||||
switch (navigator.language) {
|
||||
case 'zh-CN':
|
||||
USER.language = 'zh-hans';
|
||||
break;
|
||||
case 'zh-HK':
|
||||
case 'zh-SG':
|
||||
case 'zh-TW':
|
||||
USER.language = 'zh-hant';
|
||||
break;
|
||||
default:
|
||||
USER.language = 'en';
|
||||
}
|
||||
USER.languageAuto = true;
|
||||
} else {
|
||||
USER.languageAuto = false;
|
||||
}
|
||||
Msg.nowLang = USER.language ?? 'zh-hans';
|
||||
}
|
||||
if (updateTheme || updateLanguage) {
|
||||
BoardManager.screenWidthLevel = -1;
|
||||
BoardManager.screenHeightLevel = -1;
|
||||
BoardManager.updateBoardsCard();
|
||||
}
|
||||
Storage.user('/', USER);
|
||||
layer.closeAll(() => {
|
||||
XML.renderAllTemplete();
|
||||
layer.msg(Msg.getLang('CONFIG_UPDATE_SUCC'), { time: 1000 });
|
||||
});
|
||||
break;
|
||||
case 'reset':
|
||||
Setting.configMenuReset(obj);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Setting.addOnchangeOptionListener = () => {
|
||||
element.on('tab(setting-menu-filter)', function(data) {
|
||||
const { index } = data;
|
||||
if (index === 1) {
|
||||
if (data.index !== Setting.nowIndex) {
|
||||
goog.isElectron && BoardManager.onclickImportBoards();
|
||||
} else {
|
||||
layui.table.resize('cloud-boards-table');
|
||||
}
|
||||
} else if (index === 2) {
|
||||
if (data.index !== Setting.nowIndex) {
|
||||
$('#setting-menu-update').loading({
|
||||
background: USER.theme === 'dark' ? '#807b7b' : '#fff',
|
||||
opacity: 1,
|
||||
animateTime: 0,
|
||||
imgSrc: 1
|
||||
});
|
||||
const { Socket } = Mixly.WebSocket;
|
||||
Socket.updating = true;
|
||||
Socket.sendCommand({
|
||||
obj: 'Socket',
|
||||
func: 'getConfigByUrl',
|
||||
args: [ SOFTWARE.configUrl ]
|
||||
});
|
||||
}
|
||||
}
|
||||
Setting.nowIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
Setting.configMenuReset = (obj) => {
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
let $item = $(obj[i]);
|
||||
let newValue = $item.children('option').first().val();
|
||||
$item.val(newValue).trigger("change");
|
||||
}
|
||||
}
|
||||
|
||||
Setting.configMenuSetValue = (obj, value) => {
|
||||
let newValue = { ...value };
|
||||
if (value.themeAuto) {
|
||||
newValue.theme = 'auto';
|
||||
}
|
||||
if (value.languageAuto) {
|
||||
newValue.language = 'auto';
|
||||
}
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
let $item = $(obj[i]);
|
||||
let type = $item.attr('value');
|
||||
if (!newValue[type]) {
|
||||
continue;
|
||||
}
|
||||
$item.val(newValue[type]).trigger("change");
|
||||
}
|
||||
}
|
||||
|
||||
Setting.configMenuGetValue = (obj) => {
|
||||
let config = {};
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
let $item = $(obj[i]);
|
||||
config[$item.attr('value')] = $item.val();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
Setting.refreshUpdateMenuStatus = (config) => {
|
||||
console.log(config);
|
||||
const {
|
||||
serverVersion
|
||||
} = config;
|
||||
let $serverDiv = $('#setting-menu-update-server');
|
||||
let $btnDiv = $('#setting-menu-update > div:nth-child(2)');
|
||||
$serverDiv.find('span').css('display', 'none');
|
||||
let needUpdateServer = false;
|
||||
if (serverVersion && serverVersion !== SOFTWARE.serverVersion) {
|
||||
$serverDiv.find('span[value="obsolete"]').css('display', 'inline-block');
|
||||
needUpdateServer = true;
|
||||
$serverDiv.find('text').text(`${SOFTWARE.serverVersion} → ${serverVersion}`);
|
||||
} else {
|
||||
$serverDiv.find('span[value="latest"]').css('display', 'inline-block');
|
||||
$serverDiv.find('text').text(SOFTWARE.serverVersion);
|
||||
}
|
||||
if (needUpdateServer) {
|
||||
$btnDiv.css('display', 'flex');
|
||||
$btnDiv.children('button').off().click((event) => {
|
||||
LayerExt.open({
|
||||
title: Msg.getLang('PROGRESS'),
|
||||
id: 'setting-menu-update-layer',
|
||||
shade: LayerExt.SHADE_ALL,
|
||||
area: ['40%', '60%'],
|
||||
max: ['800px', '300px'],
|
||||
min: ['500px', '100px'],
|
||||
success: (layero, index) => {
|
||||
$('#setting-menu-update-layer').css('overflow', 'hidden');
|
||||
layero.find('.layui-layer-setwin').css('display', 'none');
|
||||
Setting.ace = Setting.createAceEditor('setting-menu-update-layer');
|
||||
Setting.ace.resize();
|
||||
const { Socket } = Mixly.WebSocket;
|
||||
Socket.sendCommand({
|
||||
obj: 'Socket',
|
||||
func: 'updateSW',
|
||||
args: []
|
||||
});
|
||||
},
|
||||
resizing: (layero) => {
|
||||
Setting.ace.resize();
|
||||
},
|
||||
end: () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$btnDiv.css('display', 'none');
|
||||
}
|
||||
setTimeout(() => {
|
||||
$('#setting-menu-update').loading('destroy');
|
||||
}, 500);
|
||||
}
|
||||
|
||||
Setting.showUpdateMessage = (data) => {
|
||||
Setting.ace.updateSelectionMarkers();
|
||||
const { selection, session } = Setting.ace;
|
||||
const initCursor = selection.getCursor();
|
||||
Setting.ace.gotoLine(session.getLength());
|
||||
selection.moveCursorLineEnd();
|
||||
Setting.ace.insert(data);
|
||||
Setting.ace.gotoLine(session.getLength());
|
||||
selection.moveCursorLineEnd();
|
||||
}
|
||||
|
||||
Setting.createAceEditor = (container, language = 'txt', tabSize = 4) => {
|
||||
let codeEditor = ace.edit(container);
|
||||
if (USER.theme === 'dark') {
|
||||
codeEditor.setTheme('ace/theme/dracula');
|
||||
} else {
|
||||
codeEditor.setTheme('ace/theme/xcode');
|
||||
}
|
||||
codeEditor.getSession().setMode(`ace/mode/${language}`);
|
||||
codeEditor.getSession().setTabSize(tabSize);
|
||||
codeEditor.setFontSize(15);
|
||||
codeEditor.setShowPrintMargin(false);
|
||||
codeEditor.setReadOnly(true);
|
||||
codeEditor.setScrollSpeed(0.8);
|
||||
codeEditor.setShowPrintMargin(false);
|
||||
codeEditor.renderer.setShowGutter(false);
|
||||
codeEditor.setValue('', -1);
|
||||
return codeEditor;
|
||||
}
|
||||
|
||||
})();
|
||||
241
mixly-sw/mixly-modules/common/xml.js
Normal file
241
mixly-sw/mixly-modules/common/xml.js
Normal file
@@ -0,0 +1,241 @@
|
||||
(() => {
|
||||
|
||||
goog.require('layui');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.provide('Mixly.XML');
|
||||
|
||||
const { Env, Config, Msg, XML } = Mixly;
|
||||
const { SOFTWARE, USER } = Config;
|
||||
const { laytpl } = layui;
|
||||
|
||||
XML.TEMPLATE_DIR_PATH = './mixly-sw/templete';
|
||||
|
||||
let env = 'electron';
|
||||
if (Env.hasSocketServer) {
|
||||
env = 'web-socket';
|
||||
} else if (Env.hasCompiler) {
|
||||
env = 'web-compiler';
|
||||
}
|
||||
if (env === 'electron' && !goog.isElectron) {
|
||||
env = 'web';
|
||||
}
|
||||
|
||||
XML.TEMPLATE_CONFIG = [
|
||||
{
|
||||
type: 'SETTING_DIV',
|
||||
path: '/setting-div.html',
|
||||
config: {
|
||||
env,
|
||||
personalise: () => {
|
||||
return Msg.getLang('PERSONAL');
|
||||
},
|
||||
theme: () => {
|
||||
return Msg.getLang('THEME');
|
||||
},
|
||||
light: () => {
|
||||
return Msg.getLang('LIGHT');
|
||||
},
|
||||
dark: () => {
|
||||
return Msg.getLang('DARK');
|
||||
},
|
||||
language: () => {
|
||||
return Msg.getLang('LANGUAGE');
|
||||
},
|
||||
autoUpdate: () => {
|
||||
return Msg.getLang('AUTO_CHECK_UPDATE');
|
||||
},
|
||||
blockRenderer: () => {
|
||||
return Msg.getLang('BLOCKS_RENDER');
|
||||
},
|
||||
apply: () => {
|
||||
return Msg.getLang('APPLY');
|
||||
},
|
||||
reset: () => {
|
||||
return Msg.getLang('RESET');
|
||||
},
|
||||
compileCAndH: () => {
|
||||
return Msg.getLang('COMPILE_WITH_OTHERS');
|
||||
},
|
||||
autoOpenPort: () => {
|
||||
return Msg.getLang('AUTO_OPEN_SERIAL_PORT');
|
||||
},
|
||||
autoWithSys: () => {
|
||||
return Msg.getLang('FOLLOW_SYS');
|
||||
},
|
||||
yes: () => {
|
||||
return Msg.getLang('ENABLE');
|
||||
},
|
||||
no: () => {
|
||||
return Msg.getLang('DISABLE');
|
||||
},
|
||||
manageBoard: () => {
|
||||
return Msg.getLang('MANAGE_BOARD');
|
||||
},
|
||||
resetBoard: () => {
|
||||
return Msg.getLang('RESET_BOARD');
|
||||
},
|
||||
importBoard: () => {
|
||||
return Msg.getLang('IMPORT_BOARD');
|
||||
},
|
||||
softwareSettings: () => {
|
||||
return Msg.getLang('SOFTWARE');
|
||||
},
|
||||
boardSettings: () => {
|
||||
return Msg.getLang('BOARD');
|
||||
},
|
||||
checkForUpdates: () => {
|
||||
return Msg.getLang('UPDATE');
|
||||
},
|
||||
server: () => {
|
||||
return Msg.getLang('SERVER');
|
||||
},
|
||||
client: () => {
|
||||
return Msg.getLang('CLIENT');
|
||||
},
|
||||
version: () => {
|
||||
return Msg.getLang('VERSION');
|
||||
},
|
||||
latest: () => {
|
||||
return Msg.getLang('LATEST');
|
||||
},
|
||||
obsolete: () => {
|
||||
return Msg.getLang('TO_BE_UPDATED');
|
||||
},
|
||||
update: () => {
|
||||
return Msg.getLang('UPDATE');
|
||||
},
|
||||
experimental: () => {
|
||||
return Msg.getLang('EXPERIMENTAL');
|
||||
},
|
||||
blocklyContentHighlight: () => {
|
||||
return Msg.getLang('WORKSPACE_HIGHLIGHT');
|
||||
},
|
||||
blocklyShowGrid: () => {
|
||||
return Msg.getLang('WORKSPACE_GRID');
|
||||
},
|
||||
blocklyShowMinimap: () => {
|
||||
return Msg.getLang('WORKSPACE_MINIMAP');
|
||||
},
|
||||
blocklyMultiselect: () => {
|
||||
return Msg.getLang('WORKSPACE_MULTISELECT');
|
||||
}
|
||||
},
|
||||
appendToBody: true,
|
||||
generateDom: false,
|
||||
render: true
|
||||
}, {
|
||||
type: 'PROGRESS_BAR_DIV',
|
||||
path: '/progress-bar-div.html',
|
||||
config: {},
|
||||
appendToBody: false,
|
||||
generateDom: false,
|
||||
render: false
|
||||
}, {
|
||||
type: 'LOADER_DIV',
|
||||
path: '/loader-div.html',
|
||||
config: {
|
||||
btnName: () => {
|
||||
return Msg.getLang('CANCEL');
|
||||
}
|
||||
},
|
||||
appendToBody: true,
|
||||
generateDom: false,
|
||||
render: true
|
||||
}, {
|
||||
type: 'INTERFACE',
|
||||
path: '/interface.html',
|
||||
config: {},
|
||||
appendToBody: false,
|
||||
generateDom: false,
|
||||
render: false
|
||||
}
|
||||
];
|
||||
|
||||
XML.TEMPLATE_ENV = {
|
||||
SETTING_DIV: true,
|
||||
PROGRESS_BAR_DIV: true,
|
||||
LOADER_DIV: true,
|
||||
INTERFACE: true
|
||||
};
|
||||
|
||||
XML.TEMPLATE_STR = {};
|
||||
|
||||
XML.TEMPLATE_STR_RENDER = {};
|
||||
|
||||
XML.TEMPLATE_DOM = {};
|
||||
|
||||
XML.render = (xmlStr, config = {}) => {
|
||||
const newConfig = {};
|
||||
for (let i in config) {
|
||||
if (typeof config[i] === 'function')
|
||||
newConfig[i] = config[i]();
|
||||
else
|
||||
newConfig[i] = config[i];
|
||||
}
|
||||
return laytpl(xmlStr).render(newConfig);
|
||||
}
|
||||
|
||||
XML.renderAllTemplete = () => {
|
||||
for (let i of XML.TEMPLATE_CONFIG) {
|
||||
const {
|
||||
type,
|
||||
config,
|
||||
appendToBody,
|
||||
render
|
||||
} = i;
|
||||
if (render && XML.TEMPLATE_ENV[type]) {
|
||||
const xmlStr = XML.TEMPLATE_STR[type];
|
||||
XML.TEMPLATE_STR_RENDER[type] = XML.render(xmlStr);
|
||||
if (appendToBody) {
|
||||
$('*[mxml-id="' + type + '"]').remove();
|
||||
XML.TEMPLATE_DOM[type] = XML.getDom(xmlStr, config);
|
||||
XML.TEMPLATE_DOM[type].attr('mxml-id', type);
|
||||
$('body').append(XML.TEMPLATE_DOM[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XML.getDom = (xmlStr, config = {}) => {
|
||||
return $(XML.render(xmlStr, config));
|
||||
}
|
||||
|
||||
for (let i of XML.TEMPLATE_CONFIG) {
|
||||
const {
|
||||
type,
|
||||
path,
|
||||
config,
|
||||
appendToBody,
|
||||
generateDom
|
||||
} = i;
|
||||
if (XML.TEMPLATE_ENV[type]) {
|
||||
const xmlStr = goog.get(XML.TEMPLATE_DIR_PATH + path);
|
||||
if (xmlStr) {
|
||||
XML.TEMPLATE_STR[type] = xmlStr;
|
||||
if (generateDom) {
|
||||
XML.TEMPLATE_STR_RENDER[type] = XML.render(xmlStr, config);
|
||||
XML.TEMPLATE_DOM[type] = XML.getDom(xmlStr, config);
|
||||
}
|
||||
if (appendToBody) {
|
||||
if (!XML.TEMPLATE_DOM[type]) {
|
||||
XML.TEMPLATE_DOM[type] = XML.getDom(xmlStr, config);
|
||||
}
|
||||
XML.TEMPLATE_DOM[type].attr('mxml-id', type);
|
||||
$('body').append(XML.TEMPLATE_DOM[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
for (let i of XML.TEMPLATE_CONFIG) {
|
||||
const { type, appendToBody } = i;
|
||||
if (XML.TEMPLATE_ENV[type] && XML.TEMPLATE_DOM[type] && appendToBody) {
|
||||
$('body').append(XML.TEMPLATE_DOM[type]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
143
mixly-sw/mixly-modules/deps.json
Normal file
143
mixly-sw/mixly-modules/deps.json
Normal file
@@ -0,0 +1,143 @@
|
||||
[
|
||||
{
|
||||
"path": "/common/board-manager.js",
|
||||
"require": [
|
||||
"path",
|
||||
"layui",
|
||||
"Mixly.Env",
|
||||
"Mixly.Msg",
|
||||
"Mixly.XML",
|
||||
"Mixly.LayerExt",
|
||||
"Mixly.Config",
|
||||
"Mixly.MArray",
|
||||
"Mixly.Url",
|
||||
"Mixly.Storage",
|
||||
"Mixly.Electron.CloudDownload",
|
||||
"Mixly.Electron.PythonShell"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.BoardManager"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/config.js",
|
||||
"require": [
|
||||
"Mixly.Url",
|
||||
"Mixly.LocalStorage"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Config"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/env.js",
|
||||
"require": [
|
||||
"path",
|
||||
"Mixly",
|
||||
"Mixly.Config"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Env"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/events.js",
|
||||
"require": [
|
||||
"Mixly.BoardManager",
|
||||
"Mixly.Env",
|
||||
"Mixly.Config",
|
||||
"Mixly.Url"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Events"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/loader.js",
|
||||
"require": [
|
||||
"layui",
|
||||
"Mixly.Url",
|
||||
"Mixly.Env",
|
||||
"Mixly.Config",
|
||||
"Mixly.BoardManager",
|
||||
"Mixly.XML",
|
||||
"Mixly.Msg",
|
||||
"Mixly.Setting",
|
||||
"Mixly.Events",
|
||||
"Mixly.Electron.PythonShell",
|
||||
"Mixly.WebSocket.Socket"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Loader"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/msg.js",
|
||||
"require": [
|
||||
"Mixly.MJSON",
|
||||
"Mixly.Config"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Msg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/setting.js",
|
||||
"require": [
|
||||
"ace",
|
||||
"ace.ExtLanguageTools",
|
||||
"layui",
|
||||
"layui.loading",
|
||||
"store",
|
||||
"$.select2",
|
||||
"Mixly.XML",
|
||||
"Mixly.LayerExt",
|
||||
"Mixly.Msg",
|
||||
"Mixly.BoardManager",
|
||||
"Mixly.Config",
|
||||
"Mixly.Env",
|
||||
"Mixly.MJSON",
|
||||
"Mixly.Storage",
|
||||
"Mixly.WebSocket.Socket"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Setting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/common/xml.js",
|
||||
"require": [
|
||||
"layui",
|
||||
"Mixly.Env",
|
||||
"Mixly.Config",
|
||||
"Mixly.Msg"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.XML"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/electron/python-shell.js",
|
||||
"require": [
|
||||
"Mixly.Env",
|
||||
"Mixly.Electron"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.Electron.PythonShell"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/web-socket/socket.js",
|
||||
"require": [
|
||||
"Mixly.Env",
|
||||
"Mixly.Config",
|
||||
"Mixly.MJSON",
|
||||
"Mixly.WebSocket",
|
||||
"Mixly.LayerExt",
|
||||
"Mixly.Command"
|
||||
],
|
||||
"provide": [
|
||||
"Mixly.WebSocket.Socket"
|
||||
]
|
||||
}
|
||||
]
|
||||
39
mixly-sw/mixly-modules/electron/python-shell.js
Normal file
39
mixly-sw/mixly-modules/electron/python-shell.js
Normal file
@@ -0,0 +1,39 @@
|
||||
(() => {
|
||||
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Electron');
|
||||
goog.provide('Mixly.Electron.PythonShell');
|
||||
|
||||
const {
|
||||
Env,
|
||||
Electron
|
||||
} = Mixly;
|
||||
|
||||
const fs_extra = Mixly.require('fs-extra');
|
||||
const fs_plus = Mixly.require('fs-plus');
|
||||
const python_shell = Mixly.require('python-shell');
|
||||
|
||||
const { PythonShell } = Electron;
|
||||
|
||||
PythonShell.init = () => {
|
||||
if (Env.currentPlatform !== 'win32' && fs_plus.isFileSync('/usr/local/bin/python3')) {
|
||||
Env.python3Path = '/usr/local/bin/python3';
|
||||
}
|
||||
PythonShell.OPTIONS = {
|
||||
pythonPath: Env.python3Path,
|
||||
pythonOptions: ['-u'],
|
||||
encoding: "binary",
|
||||
mode: 'utf-8'
|
||||
};
|
||||
}
|
||||
|
||||
PythonShell.run = (indexPath, pyFilePath) => {
|
||||
indexPath = decodeURIComponent(indexPath);
|
||||
pyFilePath = decodeURIComponent(pyFilePath);
|
||||
const shell = new python_shell.PythonShell(pyFilePath, {
|
||||
...PythonShell.OPTIONS,
|
||||
args: [ Env.clientPath, indexPath ]
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
244
mixly-sw/mixly-modules/web-socket/socket.js
Normal file
244
mixly-sw/mixly-modules/web-socket/socket.js
Normal file
@@ -0,0 +1,244 @@
|
||||
(() => {
|
||||
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.MJSON');
|
||||
goog.require('Mixly.WebSocket');
|
||||
goog.require('Mixly.LayerExt');
|
||||
goog.require('Mixly.Command');
|
||||
goog.provide('Mixly.WebSocket.Socket');
|
||||
|
||||
const {
|
||||
Env,
|
||||
Config,
|
||||
MJSON,
|
||||
LayerExt,
|
||||
Command
|
||||
} = Mixly;
|
||||
|
||||
const { SOFTWARE } = Config;
|
||||
|
||||
const { Socket } = Mixly.WebSocket;
|
||||
|
||||
Socket.obj = null;
|
||||
Socket.url = 'ws://127.0.0.1/socket';
|
||||
Socket.jsonArr = [];
|
||||
Socket.connected = false;
|
||||
Socket.initFunc = null;
|
||||
Socket.debug = SOFTWARE.debug;
|
||||
let { hostname, protocol, port } = window.location;
|
||||
if (protocol === 'http:') {
|
||||
Socket.protocol = 'ws:';
|
||||
} else {
|
||||
Socket.protocol = 'wss:';
|
||||
}
|
||||
if (port) {
|
||||
port = ':' + port;
|
||||
}
|
||||
Socket.url = Socket.protocol + '//' + hostname + port + '/socket';
|
||||
Socket.IPAddress = hostname;
|
||||
Socket.disconnectTimes = 0;
|
||||
Socket.updating = false;
|
||||
|
||||
|
||||
let lockReconnect = false; // 避免重复连接
|
||||
let timeoutFlag = true;
|
||||
let timeoutSet = null;
|
||||
let reconectNum = 0;
|
||||
const timeout = 5000; // 超时重连间隔
|
||||
|
||||
function reconnect () {
|
||||
if (lockReconnect) return;
|
||||
lockReconnect = true;
|
||||
// 没连接上会一直重连,设置延迟避免请求过多
|
||||
setTimeout(function () {
|
||||
timeoutFlag = true;
|
||||
Socket.init();
|
||||
console.info(`正在重连第${reconectNum + 1}次`);
|
||||
reconectNum++;
|
||||
lockReconnect = false;
|
||||
}, timeout); // 这里设置重连间隔(ms)
|
||||
}
|
||||
|
||||
//心跳检测
|
||||
const heartCheck = {
|
||||
timeout, // 毫秒
|
||||
timeoutObj: null,
|
||||
serverTimeoutObj: null,
|
||||
reset: function () {
|
||||
clearInterval(this.timeoutObj);
|
||||
clearTimeout(this.serverTimeoutObj);
|
||||
return this;
|
||||
},
|
||||
start: function () {
|
||||
const self = this;
|
||||
let count = 0;
|
||||
let WS = Socket;
|
||||
this.timeoutObj = setInterval(() => {
|
||||
if (count < 3) {
|
||||
if (WS.obj.readyState === 1) {
|
||||
WS.obj.send('HeartBeat');
|
||||
console.info(`HeartBeat第${count + 1}次`);
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
clearInterval(this.timeoutObj);
|
||||
count = 0;
|
||||
if (WS.obj.readyState === 0 && WS.obj.readyState === 1) {
|
||||
WS.obj.close();
|
||||
}
|
||||
}
|
||||
}, self.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
Socket.init = (onopenFunc = (data) => {}, doFunc = () => {}) => {
|
||||
if (Socket.connected) {
|
||||
if (Socket.initFunc) {
|
||||
Socket.initFunc();
|
||||
Socket.initFunc = null;
|
||||
}
|
||||
doFunc();
|
||||
return;
|
||||
}
|
||||
|
||||
timeoutSet = setTimeout(() => {
|
||||
if (timeoutFlag && reconectNum < 3) {
|
||||
console.info(`重连`);
|
||||
reconectNum++;
|
||||
Socket.init();
|
||||
}
|
||||
}, timeout);
|
||||
|
||||
let WS = Socket;
|
||||
WS.obj = new WebSocket(WS.url);
|
||||
WS.obj.onopen = () => {
|
||||
console.log('已连接' + WS.url);
|
||||
WS.connected = true;
|
||||
Socket.initFunc = doFunc;
|
||||
reconectNum = 0;
|
||||
timeoutFlag = false;
|
||||
clearTimeout(timeoutSet);
|
||||
heartCheck.reset().start();
|
||||
onopenFunc(WS);
|
||||
Socket.reload();
|
||||
if (Socket.updating) {
|
||||
Socket.updating = false;
|
||||
}
|
||||
};
|
||||
|
||||
WS.obj.onmessage = (event) => {
|
||||
heartCheck.reset().start();
|
||||
let command = Command.parse(event.data);
|
||||
command = MJSON.decode(command);
|
||||
if (Socket.debug)
|
||||
console.log('receive -> ', event.data);
|
||||
Command.run(command);
|
||||
};
|
||||
|
||||
WS.obj.onerror = (event) => {
|
||||
console.log('WebSocket error: ', event);
|
||||
reconnect();
|
||||
};
|
||||
|
||||
WS.obj.onclose = (event) => {
|
||||
WS.connected = false;
|
||||
WS.disconnectTimes += 1;
|
||||
if (WS.disconnectTimes > 255) {
|
||||
WS.disconnectTimes = 1;
|
||||
}
|
||||
console.log('已断开' + WS.url);
|
||||
|
||||
console.info(`关闭`, event.code);
|
||||
if (event.code !== 1000) {
|
||||
timeoutFlag = false;
|
||||
clearTimeout(timeoutSet);
|
||||
reconnect();
|
||||
} else {
|
||||
clearInterval(heartCheck.timeoutObj);
|
||||
clearTimeout(heartCheck.serverTimeoutObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Socket.sendCommand = (command) => {
|
||||
let WS = Mixly.WebSocket.Socket;
|
||||
if (!WS.connected) {
|
||||
layer.msg('未连接' + WS.url, {time: 1000});
|
||||
return;
|
||||
}
|
||||
let commandStr = '';
|
||||
|
||||
try {
|
||||
commandStr = JSON.stringify(MJSON.encode(command));
|
||||
if (Socket.debug)
|
||||
console.log('send -> ', commandStr);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
WS.obj.send(commandStr);
|
||||
}
|
||||
|
||||
Socket.clickConnect = () => {
|
||||
if (Socket.connected) {
|
||||
Socket.disconnect();
|
||||
} else {
|
||||
Socket.connect((WS) => {
|
||||
layer.closeAll();
|
||||
layer.msg(WS.url + '连接成功', { time: 1000 });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Socket.openLoadingBox = (title, successFunc = () => {}, endFunc = () => {}) => {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
content: $('#mixly-loader-div'),
|
||||
shade: LayerExt.SHADE_ALL,
|
||||
closeBtn: 0,
|
||||
success: function () {
|
||||
$("#webusb-cancel").css("display","none");
|
||||
$(".layui-layer-page").css("z-index", "198910151");
|
||||
successFunc();
|
||||
},
|
||||
end: function () {
|
||||
$("#mixly-loader-div").css("display", "none");
|
||||
$(".layui-layer-shade").remove();
|
||||
$("#webusb-cancel").css("display", "unset");
|
||||
if (Socket.connected)
|
||||
endFunc();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Socket.connect = (onopenFunc = (data) => {}, doFunc = () => {}) => {
|
||||
if (Socket.connected) {
|
||||
doFunc();
|
||||
return;
|
||||
}
|
||||
let title = '连接中...';
|
||||
Socket.openLoadingBox(title, () => {
|
||||
setTimeout(() => {
|
||||
Socket.init(onopenFunc);
|
||||
}, 1000);
|
||||
}, doFunc);
|
||||
}
|
||||
|
||||
Socket.disconnect = () => {
|
||||
if (!Socket.connected)
|
||||
return;
|
||||
let title = '断开中...';
|
||||
Socket.openLoadingBox(title, () => {
|
||||
Socket.obj.close();
|
||||
});
|
||||
}
|
||||
|
||||
Socket.reload = () => {
|
||||
if (!Socket.updating && Socket.disconnectTimes) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
83
mixly-sw/msg/en.json
Normal file
83
mixly-sw/msg/en.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"SETTING": "Setting",
|
||||
"PROGRESS": "Progress",
|
||||
"NAME": "Name",
|
||||
"VERSION": "Version",
|
||||
"INTRODUCTION": "introduction",
|
||||
"CLOUD_IMPORT": "Cloud import",
|
||||
"LOCAL_IMPORT": "Local import",
|
||||
"CLOUD_BOARD": "Cloud board",
|
||||
"IMPORT_BOARD": "Import board",
|
||||
"SELECT_AT_LEAST_ONE_CLOUD_BOARD": "Please select at least one cloud card",
|
||||
"UNZIPPING": "Unzipping",
|
||||
"IMPORT_SUCC": "Import successful",
|
||||
"IMPORT_FAILED": "Import failed",
|
||||
"CANCEL": "Cancel",
|
||||
"PERSONAL": "Personalise",
|
||||
"THEME": "Theme",
|
||||
"LIGHT": "Light",
|
||||
"DARK": "Dark",
|
||||
"LANGUAGE": "Language",
|
||||
"BLOCKS_RENDER": "Block renderer",
|
||||
"APPLY": "Apply",
|
||||
"RESET": "Reset",
|
||||
"CONFIG_UPDATE_SUCC": "Configuration updated successfully",
|
||||
"CONFIRM": "Confirm",
|
||||
"IMPORTING_BOARD": "Importing the board",
|
||||
"DELETING_BOARD": "Deleting the board",
|
||||
"BOARD_IMPORTED": "This board has been imported",
|
||||
"SELECT_CONFIG_FILE_ERR": "The selected file is not a configuration file",
|
||||
"FILE_NOT_EXIST": "File does not exist",
|
||||
"CONFIG_FILE_DECODE_ERR": "Configuration file parsing failed",
|
||||
"IMPORT_COMPLETE": "Import Complete",
|
||||
"BOARD_URL_READ_ERR": "Error reading board url",
|
||||
"BOARD_FILE_DOWNLOADING": "Downloading board file",
|
||||
"BOARD_FILE_DOWNLOAD_COMPLETE": "Board file download complete",
|
||||
"BOARD_FILE_DOWNLOAD_FAILED": "Failed to download board file",
|
||||
"BOARD_FILE_UNZIPPING": "Unzipping the board file",
|
||||
"BOARD_FILE_UNZIP_COMPLETE": "Board file decompression completed",
|
||||
"BOARD_FILE_UNZIP_FAILED": "Failed to decompress the board file",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOADING": "Downloading board package index",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_COMPLETE": "Board package index download complete",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_FAILED": "Failed to download the board package index",
|
||||
"BOARD_PACKAGE_DOWNLOADING": "Downloading board package",
|
||||
"BOARD_PACKAGE_DOWNLOAD_COMPLETE": "Board package download complete",
|
||||
"BOARD_PACKAGE_DOWNLOAD_FAILED": "Failed to download board package",
|
||||
"BOARD_PACKAGE_UNZIPPING": "The board package is being decompressed",
|
||||
"BOARD_PACKAGE_UNZIP_COMPLETE": "Board package decompression complete",
|
||||
"BOARD_PACKAGE_UNZIP_FAILED": "Failed to decompress the board package",
|
||||
"ALREADY_THE_LATEST_VERSION": "Already the latest version",
|
||||
"DOWNLOADING": "Downloading",
|
||||
"DOWNLOAD_COMPLETE": "Download Completed",
|
||||
"DOWNLOAD_FAILED": "Download failed",
|
||||
"UNZIP_COMPLETE": "Decompression complete",
|
||||
"UNZIP_FAILED": "Decompression failed",
|
||||
"TO_BE_UPDATED": "To be updated",
|
||||
"INSTALLED": "Installed",
|
||||
"TO_BE_INSTALLED": "To be installed",
|
||||
"STATUS": "Status",
|
||||
"CLOUD_BOARD_JSON_DOWNLOADING": "Cloud board JSON downloading",
|
||||
"CLOUD_BOARD_JSON_DOWNLOAD_FAILED": "Cloud board JSON download failed",
|
||||
"COMPILE_WITH_OTHERS": "Compile .c and .h",
|
||||
"RESET_BOARD": "Reset board",
|
||||
"MANAGE_BOARD": "Manage board",
|
||||
"AUTO_CHECK_UPDATE": "Automatically check for updates",
|
||||
"AUTO_OPEN_SERIAL_PORT": "Auto open the SerialPort after uploading",
|
||||
"SOFTWARE": "Software",
|
||||
"BOARD": "Board",
|
||||
"FOLLOW_SYS": "Follow the system",
|
||||
"UPDATE": "Update",
|
||||
"SERVER": "Server",
|
||||
"CLIENT": "Client",
|
||||
"LATEST": "latest",
|
||||
"UPDATE": "Update",
|
||||
"INFO": "The page will be automatically reloaded after the update is in progress.<br/>if the page has not been reloaded for a long time,<br/>try to reload the page manually.",
|
||||
"WORKSPACE_HIGHLIGHT": "Workspace highlight",
|
||||
"WORKSPACE_GRID": "Workspace grid",
|
||||
"WORKSPACE_MINIMAP": "Workspace minimap",
|
||||
"WORKSPACE_MULTISELECT": "Workspace multiselect",
|
||||
"CODE_LANG": "Code language",
|
||||
"ENABLE": "Enable",
|
||||
"DISABLE": "Disable",
|
||||
"EXPERIMENTAL": "Experimental. Expected behavior may change in the future."
|
||||
}
|
||||
83
mixly-sw/msg/zh-hans.json
Normal file
83
mixly-sw/msg/zh-hans.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"SETTING": "设置",
|
||||
"PROGRESS": "进度",
|
||||
"NAME": "名称",
|
||||
"VERSION": "版本",
|
||||
"INTRODUCTION": "介绍",
|
||||
"CLOUD_IMPORT": "云端导入",
|
||||
"LOCAL_IMPORT": "本地导入",
|
||||
"CLOUD_BOARD": "云端板卡",
|
||||
"IMPORT_BOARD": "导入板卡",
|
||||
"SELECT_AT_LEAST_ONE_CLOUD_BOARD": "请至少选择一块云端板卡",
|
||||
"UNZIPPING": "解压中",
|
||||
"IMPORT_SUCC": "导入成功",
|
||||
"IMPORT_FAILED": "导入失败",
|
||||
"CANCEL": "取消",
|
||||
"PERSONAL": "个性化",
|
||||
"THEME": "主题",
|
||||
"LIGHT": "浅色",
|
||||
"DARK": "深色",
|
||||
"LANGUAGE": "语言",
|
||||
"BLOCKS_RENDER": "渲染器",
|
||||
"APPLY": "应用",
|
||||
"RESET": "复位",
|
||||
"CONFIG_UPDATE_SUCC": "配置更新成功",
|
||||
"CONFIRM": "CONFIRM",
|
||||
"IMPORTING_BOARD": "板卡导入中",
|
||||
"DELETING_BOARD": "板卡删除中",
|
||||
"BOARD_IMPORTED": "此板卡已导入",
|
||||
"SELECT_CONFIG_FILE_ERR": "所选文件非配置文件",
|
||||
"FILE_NOT_EXIST": "文件不存在",
|
||||
"CONFIG_FILE_DECODE_ERR": "配置文件解析失败",
|
||||
"IMPORT_COMPLETE": "导入完成",
|
||||
"BOARD_URL_READ_ERR": "板卡URL读取出错",
|
||||
"BOARD_FILE_DOWNLOADING": "板卡文件下载中",
|
||||
"BOARD_FILE_DOWNLOAD_COMPLETE": "板卡文件下载完成",
|
||||
"BOARD_FILE_DOWNLOAD_FAILED": "板卡文件下载失败",
|
||||
"BOARD_FILE_UNZIPPING": "板卡文件解压中",
|
||||
"BOARD_FILE_UNZIP_COMPLETE": "板卡文件解压完成",
|
||||
"BOARD_FILE_UNZIP_FAILED": "板卡文件解压失败",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOADING": "板卡包索引下载中",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_COMPLETE": "板卡包索引下载完成",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_FAILED": "板卡包索引下载失败",
|
||||
"BOARD_PACKAGE_DOWNLOADING": "板卡包下载中",
|
||||
"BOARD_PACKAGE_DOWNLOAD_COMPLETE": "板卡包下载完成",
|
||||
"BOARD_PACKAGE_DOWNLOAD_FAILED": "板卡包下载失败",
|
||||
"BOARD_PACKAGE_UNZIPPING": "板卡包解压中",
|
||||
"BOARD_PACKAGE_UNZIP_COMPLETE": "板卡包解压完成",
|
||||
"BOARD_PACKAGE_UNZIP_FAILED": "板卡包解压失败",
|
||||
"ALREADY_THE_LATEST_VERSION": "已是最新版",
|
||||
"DOWNLOADING": "下载中",
|
||||
"DOWNLOAD_COMPLETE": "下载完成",
|
||||
"DOWNLOAD_FAILED": "下载失败",
|
||||
"UNZIP_COMPLETE": "解压完成",
|
||||
"UNZIP_FAILED": "解压失败",
|
||||
"TO_BE_UPDATED": "待更新",
|
||||
"INSTALLED": "已安装",
|
||||
"TO_BE_INSTALLED": "待安装",
|
||||
"STATUS": "状态",
|
||||
"CLOUD_BOARD_JSON_DOWNLOADING": "云端板卡JSON下载中",
|
||||
"CLOUD_BOARD_JSON_DOWNLOAD_FAILED": "云端板卡JSON下载失败",
|
||||
"COMPILE_WITH_OTHERS": "同时编译同目录.c和.h",
|
||||
"RESET_BOARD": "复位板卡",
|
||||
"MANAGE_BOARD": "管理板卡",
|
||||
"AUTO_CHECK_UPDATE": "自动检查更新",
|
||||
"AUTO_OPEN_SERIAL_PORT": "上传结束后自动打开串口",
|
||||
"SOFTWARE": "软件",
|
||||
"BOARD": "板卡",
|
||||
"FOLLOW_SYS": "跟随系统",
|
||||
"UPDATE": "检查更新",
|
||||
"SERVER": "服务端",
|
||||
"CLIENT": "客户端",
|
||||
"LATEST": "已最新",
|
||||
"UPDATE": "更新",
|
||||
"INFO": "正在更新中,更新结束后将会自动重载页面,<br/>若页面长时间未重载请尝试手动重载页面。",
|
||||
"WORKSPACE_HIGHLIGHT": "工作区高亮",
|
||||
"WORKSPACE_GRID": "工作区网格",
|
||||
"WORKSPACE_MINIMAP": "工作区缩略图",
|
||||
"WORKSPACE_MULTISELECT": "工作区多重选择",
|
||||
"CODE_LANG": "编程语言",
|
||||
"ENABLE": "开启",
|
||||
"DISABLE": "关闭",
|
||||
"EXPERIMENTAL": "实验性。预期行为可能会在未来发生变更。"
|
||||
}
|
||||
83
mixly-sw/msg/zh-hant.json
Normal file
83
mixly-sw/msg/zh-hant.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"SETTING": "設置",
|
||||
"PROGRESS": "進度",
|
||||
"NAME": "名稱",
|
||||
"VERSION": "版本",
|
||||
"INTRODUCTION": "介紹",
|
||||
"CLOUD_IMPORT": "雲端導入",
|
||||
"LOCAL_IMPORT": "本地導入",
|
||||
"CLOUD_BOARD": "雲端闆卡",
|
||||
"IMPORT_BOARD": "導入闆卡",
|
||||
"SELECT_AT_LEAST_ONE_CLOUD_BOARD": "請選擇至少一塊雲端闆卡",
|
||||
"UNZIPPING": "解壓中",
|
||||
"IMPORT_SUCC": "導入成功",
|
||||
"IMPORT_FAILED": "導入失敗",
|
||||
"CANCEL": "取消",
|
||||
"PERSONAL": "個性化",
|
||||
"THEME": "主題",
|
||||
"LIGHT": "淺色",
|
||||
"DARK": "深色",
|
||||
"LANGUAGE": "語言",
|
||||
"BLOCKS_RENDER": "塊渲染器",
|
||||
"APPLY": "應用",
|
||||
"RESET": "复位",
|
||||
"CONFIG_UPDATE_SUCC": "配置更新成功",
|
||||
"CONFIRM": "確認",
|
||||
"IMPORTING_BOARD": "闆卡導入中",
|
||||
"DELETING_BOARD": "闆卡刪除中",
|
||||
"BOARD_IMPORTED": "此闆卡已導入",
|
||||
"SELECT_CONFIG_FILE_ERR": "所選文件非配置文件",
|
||||
"FILE_NOT_EXIST": "文件不存在",
|
||||
"CONFIG_FILE_DECODE_ERR": "配置文件解析失敗",
|
||||
"IMPORT_COMPLETE": "導入完成",
|
||||
"BOARD_URL_READ_ERR": "闆卡URL讀取出錯",
|
||||
"BOARD_FILE_DOWNLOADING": "闆卡文件下載中",
|
||||
"BOARD_FILE_DOWNLOAD_COMPLETE": "闆卡文件下載完成",
|
||||
"BOARD_FILE_DOWNLOAD_FAILED": "闆卡文件下載失敗",
|
||||
"BOARD_FILE_UNZIPPING": "闆卡文件解壓中",
|
||||
"BOARD_FILE_UNZIP_COMPLETE": "闆卡文件解壓完成",
|
||||
"BOARD_FILE_UNZIP_FAILED": "闆卡文件解壓失敗",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOADING": "闆卡包索引下載中",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_COMPLETE": "闆卡包索引下載完成",
|
||||
"BOARD_PACKAGE_INDEX_DOWNLOAD_FAILED": "闆卡包索引下載失敗",
|
||||
"BOARD_PACKAGE_DOWNLOADING": "闆卡包下載中",
|
||||
"BOARD_PACKAGE_DOWNLOAD_COMPLETE": "闆卡包下載完成",
|
||||
"BOARD_PACKAGE_DOWNLOAD_FAILED": "闆卡包下載失敗",
|
||||
"BOARD_PACKAGE_UNZIPPING": "闆卡包解壓中",
|
||||
"BOARD_PACKAGE_UNZIP_COMPLETE": "闆卡包解壓完成",
|
||||
"BOARD_PACKAGE_UNZIP_FAILED": "闆卡包解壓失敗",
|
||||
"ALREADY_THE_LATEST_VERSION": "已是最新版",
|
||||
"DOWNLOADING": "下载中",
|
||||
"DOWNLOAD_COMPLETE": "下載完成",
|
||||
"DOWNLOAD_FAILED": "下載失敗",
|
||||
"UNZIP_COMPLETE": "解壓完成",
|
||||
"UNZIP_FAILED": "解壓失敗",
|
||||
"TO_BE_UPDATED": "已安装",
|
||||
"INSTALLED": "已安裝",
|
||||
"TO_BE_INSTALLED": "待安裝",
|
||||
"STATUS": "狀態",
|
||||
"CLOUD_BOARD_JSON_DOWNLOADING": "雲端闆卡JSON下載中",
|
||||
"CLOUD_BOARD_JSON_DOWNLOAD_FAILED": "雲端闆卡JSON下載失敗",
|
||||
"COMPILE_WITH_OTHERS": "同時編譯同目錄.c和.h",
|
||||
"RESET_BOARD": "復位闆卡",
|
||||
"MANAGE_BOARD": "管理闆卡",
|
||||
"AUTO_CHECK_UPDATE": "自動檢查更新",
|
||||
"AUTO_OPEN_SERIAL_PORT": "上傳結束後自動打開串口",
|
||||
"SOFTWARE": "軟件",
|
||||
"BOARD": "板卡",
|
||||
"FOLLOW_SYS": "跟隨系統",
|
||||
"UPDATE": "檢查更新",
|
||||
"SERVER": "服務器",
|
||||
"CLIENT": "用戶端",
|
||||
"LATEST": "已最新",
|
||||
"UPDATE": "更新",
|
||||
"INFO": "正在更新中,更新結束後將會自動重載頁面,<br/>若頁面長時間未重載請嘗試手動重載頁面。",
|
||||
"WORKSPACE_HIGHLIGHT": "工作區高亮",
|
||||
"WORKSPACE_GRID": "工作區網格",
|
||||
"WORKSPACE_MINIMAP": "工作區縮略圖",
|
||||
"WORKSPACE_MULTISELECT": "工作區多重選擇",
|
||||
"CODE_LANG": "程式碼語言",
|
||||
"ENABLE": "開啟",
|
||||
"DISABLE": "關閉",
|
||||
"EXPERIMENTAL": "實驗性。 預期行為可能會在未來發生變更。"
|
||||
}
|
||||
143
mixly-sw/templete/interface.html
Normal file
143
mixly-sw/templete/interface.html
Normal file
@@ -0,0 +1,143 @@
|
||||
<style>
|
||||
.container {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.blue_icons {
|
||||
filter: invert(13%) sepia(24%) saturate(1450%) hue-rotate(207deg) brightness(93%) contrast(105%);
|
||||
}
|
||||
|
||||
.slider-area {
|
||||
height: 390px !important;
|
||||
}
|
||||
|
||||
* {
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
$(window).scroll(function () {
|
||||
if ($(window).scrollTop() >= 50) {
|
||||
$('.header-area').css('background', '#1B173D');
|
||||
} else {
|
||||
$('.header-area').css('background', 'transparent');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<section class="slider-area" id="home">
|
||||
<div class="container">
|
||||
<div class="col-md-6 col-sm-6 hidden-xs">
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||
<div class="row">
|
||||
<div class="slider-inner text-right">
|
||||
<b>
|
||||
<h2>Mixly</h2>
|
||||
</b>
|
||||
<h5>Make Programming Easier</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<style>
|
||||
/*#add-board:hover {
|
||||
-webkit-transform: rotate(0deg) scale(1.2) !important;
|
||||
transform: rotate(1deg) scale(1.2) !important;
|
||||
}*/
|
||||
|
||||
.setting-card>div:nth-child(1) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2) {
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 8px rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] .setting-card>div:nth-child(2) {
|
||||
background-color: #2d2c2c;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] .setting-card>div:nth-child(2) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2):hover {
|
||||
opacity: 1;
|
||||
box-shadow: 0 0 15px rgb(0 0 0 / 30%);
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2)>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2)>div>form {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2) .layui-form-switch {
|
||||
height: 24px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2) .layui-form-onswitch {
|
||||
border-color: #686768;
|
||||
background-color: #3f3e40;
|
||||
}
|
||||
|
||||
.setting-card>div:nth-child(2) button {
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.service-single img:hover {
|
||||
-webkit-transform: rotate(0deg) scale(1.025);
|
||||
transform: rotate(-3deg) scale(1.025);
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] .service-single:hover {
|
||||
box-shadow: 0 0 15px rgb(0 0 0 / 30%) !important;
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] .service-single:hover {
|
||||
box-shadow: 0 0 15px rgb(85 85 85 / 30%) !important;
|
||||
}
|
||||
|
||||
.fontello-icon {
|
||||
font-family: "fontello" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</style>
|
||||
<div class="service-area" id="board-area" style="padding-left: 0px;padding-right: 0px;">
|
||||
<div class="container" style="width:100%;padding-left: 0px;padding-right: 0px;">
|
||||
<div class="layui-carousel" id="board-switch" lay-filter="board-switch-filter"
|
||||
style="background-color:rgba(0,0,0,0);padding-left: 0px;padding-right: 0px;">
|
||||
<div id="mixly-board" carousel-item="" style="background-color:rgba(0,0,0,0);">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer id="footer" role="contentinfo" style="position: absolute; bottom: 0px;left: 0px;width: 100%;"></footer>
|
||||
4
mixly-sw/templete/loader-div.html
Normal file
4
mixly-sw/templete/loader-div.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div id="mixly-loader-div" style="display:none; margin:12px" align="center">
|
||||
<progress id="mixly-loader"></progress>
|
||||
<button id="mixly-loader-btn">{{d.btnName}}</button>
|
||||
</div>
|
||||
19
mixly-sw/templete/progress-bar-div.html
Normal file
19
mixly-sw/templete/progress-bar-div.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card layui-panel" id="{{d.boardPanelId}}">
|
||||
<div class="layui-card-header">{{d.boardType}}</div>
|
||||
<div class="layui-card-body">
|
||||
<div style="padding: 0px;position: relative;height: 25px;">
|
||||
<div class="layui-progress" lay-filter="{{d.progressFilter}}" lay-showPercent="yes"
|
||||
style="position: absolute;left: 5px;right: 25px;top: 12px;display: inline-block;">
|
||||
<div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>
|
||||
</div>
|
||||
<div style="display: inline-block;position: absolute;right: 5px;top: 2px;">
|
||||
<i id="{{d.progressStatusId}}" class="progress-status layui-icon layui-icon-close-fill"
|
||||
style="font-size: 15px; color: #1E9FFF;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
356
mixly-sw/templete/setting-div.html
Normal file
356
mixly-sw/templete/setting-div.html
Normal file
@@ -0,0 +1,356 @@
|
||||
<style type="text/css">
|
||||
#setting-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#setting-menu-left {
|
||||
width: 160px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#setting-menu-options {
|
||||
margin: 5px;
|
||||
width: 150px;
|
||||
border-left-width: 10px;
|
||||
}
|
||||
|
||||
#setting-menu-body {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
left: 160px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
/* border-radius: 0px 0px 5px 0px; */
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu-body {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#setting-menu-top {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 0px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
#setting-menu-bottom {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 0px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
#setting-menu-btn-group {
|
||||
float: right;
|
||||
padding-top: 4px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#setting-menu .layui-table-header {
|
||||
border-right-width: 5px !important;
|
||||
}
|
||||
|
||||
.layui-table-tips-c:before {
|
||||
position: relative;
|
||||
right: 1px;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
#setting-menu-body .menu-body {
|
||||
height: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#setting-menu .layui-nav .layui-nav-item {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#setting-menu .layui-nav .layui-nav-item a {
|
||||
padding-top: 1px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-bg-cyan {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-nav .layui-nav-item.layui-this a {
|
||||
color: #fff;
|
||||
background-color: #009688;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-nav .layui-nav-item a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-nav-tree .layui-nav-item:hover {
|
||||
background-color: #f2f2f2;
|
||||
transition: 0.5s all;
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] #setting-menu .layui-bg-cyan {
|
||||
background-color: #2a2a2b !important;
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] #setting-menu .layui-nav .layui-this a {
|
||||
color: #fff;
|
||||
background-color: var(--lay-color-normal);
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] #setting-menu .layui-nav .layui-nav-item a {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] #setting-menu .layui-nav-tree .layui-nav-item:hover {
|
||||
background-color: #afa7a7;
|
||||
transition: 0.5s all;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-table-tool {
|
||||
background-color: #fff;
|
||||
border-bottom-width: 0px;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] #setting-menu .layui-table-box {
|
||||
border: 4px solid #f8f8f8;
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] #setting-menu .layui-table-box {
|
||||
border: 4px solid #302d2d;
|
||||
}
|
||||
|
||||
.setting-menu-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-wrap: nowrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.setting-menu-info > div:nth-child(1) {
|
||||
height: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.setting-menu-info > div:nth-child(2) {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
html[data-bs-theme=light] .setting-menu-info > div:nth-child(2) {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
html[data-bs-theme=dark] .setting-menu-info > div:nth-child(2) {
|
||||
border-top: 1px solid #454343;
|
||||
}
|
||||
|
||||
#setting-menu-user .layui-form-pane {
|
||||
padding: 5px 5px 1px 5px;
|
||||
}
|
||||
|
||||
#setting-menu-update .layui-panel {
|
||||
margin: 5px;
|
||||
}
|
||||
</style>
|
||||
<div id="setting-menu" class="layui-layer-wrap">
|
||||
<div id="setting-menu-top">
|
||||
<div id="setting-menu-left">
|
||||
<ul id="setting-menu-options" class="layui-nav layui-nav-tree layui-bg-cyan layui-inline"
|
||||
lay-filter="setting-menu-filter">
|
||||
<li class="layui-nav-item layui-this" lay-id="0">
|
||||
<a m-id="0" href="javascript:;">{{ d.personalise }}</a>
|
||||
</li>
|
||||
{{# if(d.env === 'electron'){ }}
|
||||
<li class="layui-nav-item" lay-id="1">
|
||||
<a m-id="1" href="javascript:;">{{ d.importBoard }}</a>
|
||||
</li>
|
||||
{{# } }}
|
||||
{{# if(d.env === 'web-socket'){ }}
|
||||
<li class="layui-nav-item" lay-id="2">
|
||||
<a m-id="2" href="javascript:;">{{ d.checkForUpdates }}</a>
|
||||
</li>
|
||||
{{# } }}
|
||||
</ul>
|
||||
</div>
|
||||
<div id="setting-menu-body">
|
||||
<div class="menu-body layui-show">
|
||||
<div id="setting-menu-user" class="setting-menu-info">
|
||||
<div>
|
||||
<div class="layui-collapse" lay-filter="menu-user-collapse-filter" lay-accordion="">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">{{ d.softwareSettings }}</h2>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.theme }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="theme" lay-ignore>
|
||||
<option value="light">{{ d.light }}</option>
|
||||
<option value="dark">{{ d.dark }}</option>
|
||||
<option value="auto">{{ d.autoWithSys }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.language }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="language" lay-ignore>
|
||||
<option value="zh-hans">简体中文</option>
|
||||
<option value="zh-hant">繁體中文</option>
|
||||
<option value="en">English</option>
|
||||
<option value="auto">{{ d.autoWithSys }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{# if(d.env === 'electron'){ }}
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.autoUpdate }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="autoUpdate" lay-ignore>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{# if(d.env === 'electron'){ }}
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">{{ d.boardSettings }}</h2>
|
||||
<div class="layui-colla-content">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.compileCAndH }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="compileCAndH" lay-ignore>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.autoOpenPort }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="autoOpenPort" lay-ignore>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">Blockly</h2>
|
||||
<div class="layui-colla-content">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.blocklyContentHighlight }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="blocklyContentHighlight"
|
||||
lay-ignore>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.blocklyShowGrid }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="blocklyShowGrid" lay-ignore>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">
|
||||
{{ d.blocklyShowMinimap }} <a class="icon-beaker"
|
||||
style="font-size: 14px;" title="{{ d.experimental }}"></a>
|
||||
</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="blocklyShowMinimap" lay-ignore>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">
|
||||
{{ d.blocklyMultiselect }} <a class="icon-beaker"
|
||||
style="font-size: 14px;" title="{{ d.experimental }}"></a>
|
||||
</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="blocklyMultiselect" lay-ignore>
|
||||
<option value="no">{{ d.no }}</option>
|
||||
<option value="yes">{{ d.yes }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">{{ d.blockRenderer }}</label>
|
||||
<div class="layui-input-block layui-row layui-col-space10">
|
||||
<select class="setting-menu-item" value="blockRenderer" lay-ignore>
|
||||
<option value="geras">geras</option>
|
||||
<option value="zelos">zelos</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button class="layui-btn self-adaption-btn layui-btn-sm" value="apply">{{ d.apply }}</button>
|
||||
<button class="layui-btn self-adaption-btn layui-btn-sm" value="reset">{{ d.reset }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{# if(d.env === 'electron'){ }}
|
||||
<div class="menu-body" id="import-board">
|
||||
<div class="layui-hide" id="import-board-page" lay-filter="import-board-page-filter"></div>
|
||||
</div>
|
||||
{{# } }}
|
||||
{{# if(d.env === 'web-socket'){ }}
|
||||
<div class="menu-body">
|
||||
<div id="setting-menu-update" class="setting-menu-info">
|
||||
<div>
|
||||
<div id="setting-menu-update-server" class="layui-card layui-panel">
|
||||
<div class="layui-card-header">
|
||||
<label>{{ d.server }}</label>
|
||||
<span class="layui-badge layui-bg-green" value="latest">{{ d.latest }}</span>
|
||||
<span class="layui-badge" value="obsolete">{{ d.obsolete }}</span>
|
||||
</div>
|
||||
<div class="layui-card-body" class="">
|
||||
<label>{{ d.version }}: </label>
|
||||
<text>1.0.0</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button class="layui-btn self-adaption-btn layui-btn-sm" value="update">{{ d.update }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="setting-menu-bottom">
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user