初始化提交
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();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user