/** * AJAX to logout * @param {string} username username * @param {string} password password */ function logout() { $.ajax(`${CCB.base_url}api/logout`, { type: "GET", xhrFields: { withCredentials: true }, success: () => { // $('#login_iframe').attr('src', '//staging.cocorobo.hk/login/'); appendIframe("TM_login"); $('#TM_login').children().css("height", "820px"); appendIframe("TM_login_object"); $('#TM_login_object').children().css("height", "820px"); appendIframe("TM_login_posenet"); $('#TM_login_posenet').children().css("height", "820px"); appendIframe("TM_posenet_login"); $('#TM_posenet_login').children().css("height", "820px"); appendIframe("before_login"); appendIframe("cloud_askLogin"); appendIframe("TM_login_Model_download_modal"); $('#TM_login_Model_download_modal').children().css("height", "820px"); $('#TM_login_Model_download_modal').children().css("margin-top", "-225px"); appendIframe("TM_login_webcam_capture_modal"); $('#TM_login_webcam_capture_modal').children().css("width", "820px"); $('#TM_login_webcam_capture_modal').children().css("height", "820px"); appendIframe("TM_login_gesture_recog_modal"); $('#TM_login_gesture_recog_modal').children().css("width", "820px"); $('#TM_login_gesture_recog_modal').children().css("height", "820px"); appendIframe("TM_login_voice_input_modal"); $('#TM_login_voice_input_modal').children().css("width", "820px"); $('#TM_login_voice_input_modal').children().css("height", "820px"); appendIframe("TM_center_game"); $('#TM_center_game').children().css("margin-top", "-300px"); $('#TM_center_game').children().css("height", "820px"); Materialize.toast(CCB.str_group.success_userLogout, 4000); CCB.userState = false; $("#cloud_fileListArea").html(""); loginModalStatus(); $("#modal_logout_btn").addClass('blue'); $(".svgImg").css('display', 'none'); $(".translate-signout").css('opacity', '1'); } }); } /** * AJAX to get user profile * when logged * data {object}: [alias, username, school, apiKey] */ function getUserProfile(data) { $("#account_alias") .text(data.alias) .css({ "display": "inline-block", width: '80px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }); $("#userProfile_alias").text(data.alias); $("#userProfile_username").text(data.username); $("#userProfile_school").text(data.defaultSchool); USER.api_key = data.apiKey; getCoCloudEvent(); } /** * AJAX to get cloud file list * when logged * filelist {object}: a list of files name */ function getCloudFileList() { $.ajax(`${CCB.base_url}blockx/files`, { type: "GET", xhrFields: { withCredentials: true }, success: fileList => { // console.log(fileList, 'getCloudFileList') updateCloudFileList(fileList); updateCloudFilePanel(); // openCloudFile(CCB.cloudFileList[i].filename); 打开文件 let arr = window.location.search.split('&')[1] if (arr) { fileList.map(x => { if (x.filenameid == arr.split('=')[1]) { openCloudFile(x.filename) } return x; }) } } }); } /** * AJAX to update file in the cloud * @param {String} filename : the name of file * xml {String}: the file content which format is xml.Generated by (Func:)Ardublockly.generateXml() */ function updateCloudFile(filename, type) { $.ajax(`${CCB.base_url}blockx/${filename}`, { type: "PUT", xhrFields: { withCredentials: true }, data: { filename: filename, xml: type == "py" ? blockpy.components.editor.codeMirror.getValue() : Ardublockly.generateXml() }, beforeSend: () => { $("#cloud_modal_preload").css("display", "block") }, success: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.success_updateFile, 4000); let i = indexGet(filename, CCB.cloudFileList); $("#cloud_time" + i).html(getCurrentDate()); }, error: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.error_updateFile, 4000); } }); } /** * AJAX to create file in the cloud * @param {String} filename : the name of file * xml : the file content which format is xml, Generated by (Func:)Ardublockly.generateXml() */ function createCloudFile(filename) { var _tp = window.location.pathname.indexOf("/python") == 0 $.ajax(`${CCB.base_url}blockx/`, { type: "POST", xhrFields: { withCredentials: true }, data: { type: _tp ? "py" : "", filename: filename, xml: _tp ? blockpy.components.editor.codeMirror.getValue() : Ardublockly.generateXml() }, beforeSend: () => { $("#cloud_modal_preload").css("display", "block") }, success: (res) => { $("#cloud_modal_preload").css("display", "none"); console.log(res) Materialize.toast(CCB.str_group.success_uploadFile, 4000); let fileobject = { filenameId: res.filename, filename: filename, time: getCurrentDate(), type: _tp ? "py" : "", timestamp: (new Date()).valueOf() }; CCB.cloudFileList.push(fileobject); CCB.selectCloudFile = filename; relistCloudFile(filename); updateCloudFilePanel(); cloudFileState("over", 0); }, error: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.error_uploadFile, 4000); } }); } /** * AJAX to get file in the cloud and load into workspace * @param {String} filename : the name of file */ function openCloudFile(filename) { $.ajax(`${CCB.base_url}blockx/${filename}`, { type: "GET", xhrFields: { withCredentials: true }, before: () => { $("#cloud_modal_preload").css("display", "block") }, success: data => { var file = data.xml; var date = data.date; Materialize.toast(CCB.str_group.success_downloadFile, 4000); if (data.type == "py") { blockpy.components.editor.codeMirror.setValue(file); } else { loadCloudXmlFile(file, filename); } $("#cloud_storage_modal").modal("close"); $("#cloud_modal_preload").css("display", "none"); let i = indexGet(filename, CCB.cloudFileList); CCB.selectCloudFile = filename; relistCloudFile(filename); updateCloudFilePanel(); }, error: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.error_downloadFile, 4000); } }); } /** * AJAX to delete file in the cloud * @param {String} filename : the name of file */ function deleteCloudFile(filename) { $.ajax(`${CCB.base_url}blockx/${filename}`, { type: "DELETE", xhrFields: { withCredentials: true }, beforeSend: () => { $("#cloud_modal_preload").css("display", "block") }, success: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.success_deleteFile, 4000); let i = indexGet(filename, CCB.cloudFileList); CCB.cloudFileList.splice(i, 1); if (CCB.selectCloudFile == filename) { CCB.selectCloudFile = null; } cloudFileState("over", i); updateCloudFilePanel(); }, error: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.error_deleteFile, 4000); } }); } /** * AJAX to Rename file in the cloud * @param {String} oldname : the orign name of file * @param {String} newname : the name to be modified */ function renameCloudFile(newName, oldName) { $.ajax(`${CCB.base_url}blockx/modify`, { type: "PUT", xhrFields: { withCredentials: true }, data: { currentFilename: oldName, newFilename: newName }, beforeSend: () => { $("#cloud_modal_preload").css("display", "block") }, success: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.success_renameFile, 4000); let i = indexGet(oldName, CCB.cloudFileList); CCB.cloudFileList[i].filename = newName; CCB.cloudFileList[i].filenameId = CCB.cloudFileList[i].filenameId.split("_")[0]+"_"+newName if (CCB.selectCloudFile == oldName) { CCB.selectCloudFile = newName; } $("#cloud_name" + i).html(newName + ".xml"); document.getElementById("cloud_name" + i).title = newName + ".xml"; // document.getElementById(oldName).id = newName; cloudFileState("over", i); }, error: () => { $("#cloud_modal_preload").css("display", "none"); Materialize.toast(CCB.str_group.error_renameFile, 4000); } }); } /** * AJAX to get CocoCloud event list * when logged * list {object}: a list of event info,including {name, url, type, eventAPIKey} */ function getCoCloudEvent() { $('.get_event').text(CCB.str_group.get_data_cloud_event) $.ajax(`${CCB.base_url}iot/data/apikey/${USER.api_key}/event/`, { type: "GET", xhrFields: { withCredentials: true }, success: data => { $('.get_event').text('') USER.events = data; updateCoEvent(); AICloudEvents(data); } }); } /** * function to update login modal when logged in or out */ function loginModalStatus() { if (CCB.userState == true) { $("#account_loginTitle").css("display", "none"); $("#before_login").css("display", "none"); $("#after_login").css("display", "block"); $("#cloud_askLogin").css("display", "none"); $("#cloud_fileListArea").css("display", "block"); var str = ''; $("#cloud_fileListArea").append(str); $("#login_modal > .modal-footer").css("display", "block"); /*Teachable Machine*/ $("#Teachable_Machine").css("background", "rgb(237, 237, 238)"); $("#Object_recog_modal").css("background", "rgb(237, 237, 238)"); // $("#TM_iframe_posenet").css("overflow-y", "scroll"); // $("#TM_iframe_posenet").css("overflow-x", "hidden"); // $("#TM_iframe_object").css("overflow-y", "scroll"); // $("#TM_iframe_object").css("overflow-x", "hidden"); $("#TM_login").css("display", "none"); $("#TM_iframe").css("display", "block"); $("#TM_login_object").css("display", "none"); $("#TM_iframe_object").css("display", "block"); $("#TM_iframe_posenet").css("display", "block"); $("#TM_posenet_iframe").css("display", "block"); $("#TM_login_Model_download_modal").css("display", "none"); $("#Model_download_modal").css("display", "block"); $("#TM_login_webcam_capture_modal").css("display", "none"); $("#gestureRecognitionTitle").css("display", "block"); $("#TM_login_gesture_recog_modal").css("display", "none"); $("#emotionRecognitionTitle").css("display", "block"); $("#TM_login_voice_input_modal").css("display", "none"); $("#voice_input_modal_reg").css("display", "block"); document.getElementById("api-key").value = $("#cloud_events").val(); if (CCB.downloadModelUrl != '' && CCB.downloadModelUrl != "#WeTech_Modal") { window.open(CCB.downloadModelUrl); CCB.downloadModelUrl = ''; } else if (CCB.downloadModelUrl == "#WeTech_Modal") { $(CCB.downloadModelUrl).modal("open"); } } else if (CCB.userState == false) { $("#account_alias") .text("") .css("display", "none"); $("#account_loginTitle").css("display", "inline-block"); $("#userProfile_alias").text(""); $("#userProfile_username").text(""); $("#userProfile_school").text(""); $("#api-key").val(""); $("#api-key-alt").val(""); $("#before_login").css("display", "block"); $("#after_login").css("display", "none"); $("#cloud_askLogin").css("display", "block"); $("#cloud_fileListArea").css("display", "none"); $("#login_modal > .modal-footer").css("display", "none"); /*Teachable Machine*/ $("#Teachable_Machine").css("background", "#fff"); $("#Object_recog_modal").css("background", "#fff"); $("#TM_login").css("display", "block"); $("#TM_iframe").css("display", "none"); $("#TM_login_object").css("display", "block"); $("#TM_iframe_object").css("display", "none"); $("#TM_iframe_posenet").css("display", "none"); $("#TM_posenet_iframe").css("display", "none"); $("#TM_login_webcam_capture_modal").css("display", "block"); $("#gestureRecognitionTitle").css("display", "none"); $("#TM_login_gesture_recog_modal").css("display", "block"); $("#emotionRecognitionTitle").css("display", "none"); $("#TM_login_voice_input_modal").css("display", "block"); $("#voice_input_modal_reg").css("display", "none"); CCB.downloadModelUrl = ''; } } /** * load cloud xmlfile into workspace * @param {String} file : the content of file (xml) * @param {String} filename : the name of file */ function loadCloudXmlFile(file, filename) { var xmlfile = file; if (file.indexOf("$") == 4) { var file_mode = file.substr(0, 4); if (file_mode == "main" && CCB.mode == false) { $("#network-btn").click(); } else if (file_mode == "wifi" && CCB.mode == true) { $("#network-btn").click(); } var xmlfile = file.substr(5); } var success1 = Ardublockly.replaceBlocksfromXml(xmlfile); if (success1) { Ardublockly.renderContent(); Ardublockly.sketchNameSet(filename); } else { Ardublockly.alertMessage( Ardublockly.getLocalStr("ErrorBlockTitle"), Ardublockly.getLocalStr("ErrorBlockBody"), false ); } } /** * update CCB cloud listfiles * @param {Array} filelist : a array of file list */ function updateCloudFileList(filelist) { CCB.cloudFileList = []; var origin = [ { filename: "_new_", time: null, timestamp: null, filenameId: null, type: null } ]; var cloudlist = []; filelist.filter(val => { if (!val.type) { var filename = val.filename; var date = dateFormat(val.date); var Timestamp = val.timestamp != null ? val.timestamp : 0; cloudlist.push({ filename: filename, time: date, timestamp: Timestamp, filenameId: val.filenameid }); } }); cloudlist.sort((a, b) => { return b.timestamp - a.timestamp }) CCB.cloudFileList = origin.concat(cloudlist.slice()); } /** * update the panel of cloud modal * listing files stored in the cloud */ function updateCloudFilePanel() { var panel = document.getElementById("cloud_fileListArea"); var rowPanel, row, div; let renderContent; let { rename, cloudFileSaveAs, cloudFileSave, cloudFileCancel, cloudFileConfirm, saveNew, deleteFile, lastModified, cloudFileOpenMsg, cloudFileSaveMsg, cloudFileEditMsg, cloudFileDeleteMsg } = CCB.str_group; panel.innerHTML = ""; for (var i = 0; i < CCB.cloudFileList.length; i++) { // set a row ,each row lists three files row = document.createElement("div"); if (i % 3 == 0) { row.id = "cloud_fileAreaRow" + i / 3; row.style = "margin-bottom:0"; panel.appendChild(row); $("#cloud_fileAreaRow" + i / 3).addClass("row"); } rowPanel = document.getElementById("cloud_fileAreaRow" + Math.floor(i / 3)); div = document.createElement("div"); div.id = "cloud_fileRow" + i; if (i == 0) { renderContent = '
' + '
' + "
" + ' add' + ' ' + saveNew + '' + // ' add' + "
" + "
" + ' create' + ' ' + cloudFileSaveAs + "" + ' ' + ' " + "
" + "
" + "
"; } else { renderContent = '
' + // * * ' " + //icon option: remove_red_eye , place , personal_video , nature, edit_location ,bookmark // lock icon : https // * * '
' + "
" + '
' + '
' + ' ' + CCB.cloudFileList[i].filename + (CCB.cloudFileList[i].type ? "." + CCB.cloudFileList[i].type : '.xml') + "edit" + "

" + lastModified + ' ' + CCB.cloudFileList[i].time + " " + "

" + "
" + '
' + '

' + rename + "

" + ' ' + ' " + "
" + '
' + '

' + deleteFile + "

" + ' " + "
" + '
' + ' check_box' + "
" + "
" + "
"; } div.innerHTML = renderContent; rowPanel.appendChild(div); $("#cloud_fileRow" + i).addClass("col s4"); } if (CCB.selectCloudFile != null) { $("#cloud_fileRow1").addClass("selected"); } let tooltips_cloud = [ { selector: '.cloudBtn-open', delay: 500, position: 'bottom', tooltip: CCB.str_group.cloudFileOpenMsg }, { selector: '.cloudBtn-update', delay: 500, position: 'bottom', tooltip: CCB.str_group.cloudFileSaveMsg }, { selector: '.cloudBtn-rename', delay: 500, position: 'bottom', tooltip: CCB.str_group.cloudFileEditMsg }, { selector: '.cloudBtn-delete', delay: 500, position: 'bottom', tooltip: CCB.str_group.cloudFileDeleteMsg }, { selector: '.cloudBtn-share', delay: 500, position: 'bottom', tooltip: CCB.str_group.cloudShare }, ]; add_tooltips(tooltips_cloud); } /** * Ready to open a cloud file * @param {Integer} i the index of filelist */ function fileOpen(i) { $("#cloud_modal_preload").css("display", "block") openCloudFile(CCB.cloudFileList[i].filenameId); } function fileShare(i) { let url = window.location.href + '&Qd=' + CCB.cloudFileList[i].filenameId; let flag = copyText(url); flag ? Materialize.toast(CCB.str_group.share_success, 3000, "shareUrl") : Materialize.toast(CCB.str_group.share_fail, 3000, "shareUrl") stopPropagation() } /** * * @param {copy url} i * */ function copyText(text) { var textarea = document.createElement("input");//创建input对象 var currentFocus = document.activeElement;//当前获得焦点的元素 document.body.appendChild(textarea);//添加元素 textarea.value = text; textarea.focus(); if (textarea.setSelectionRange) textarea.setSelectionRange(0, textarea.value.length);//获取光标起始位置到结束位置 else textarea.select(); try { var flag = document.execCommand("copy");//执行复制 } catch (eo) { var flag = false; } document.body.removeChild(textarea);//删除元素 currentFocus.focus(); return flag; } /** * Ready to update a cloud file * @param {Integer} i the index of filelist */ function fileUpdate(i) { $("#cloud_modal_preload").css("display", "block") updateCloudFile(CCB.cloudFileList[i].filename, CCB.cloudFileList[i].type); stopPropagation() } /** * Ready to rename a cloud file * @param {Integer} i the index of filelist */ function fileDelete(i) { cloudFileState("delete", i); stopPropagation() } /** * Ready to rename a cloud file * set name input and confirm & cancel btn * @param {Integer} i the index of filelist */ function fileRename(i) { renameBoxSet(i); cloudFileState("rename", i); stopPropagation() } function stopPropagation(e) { e = e || window.event; if (e.stopPropagation) { //W3C阻止冒泡方法 e.stopPropagation(); } else { e.cancelBubble = true; //IE阻止冒泡方法 } } /** * Confirm to rename a cloud file * check the current filelist and launch a funciton to rename it */ function confirmRename(i) { var filename = $("#cloud_sketch_rename" + i).val(); // var originname = $('#cloud_name' + i).html(); var originname = CCB.cloudFileList[i].filename; if (filename == originname) { cloudFileState("over", i); } else if (checkFileName(filename)) { renameCloudFile(filename, originname); } } /** * cancel renaming a cloud file * set origin name display */ function cancelRename(i) { cloudFileState("over", i); stopPropagation() } /** * Confirm to Delete a cloud file * check the current filelist and launch a funciton to rename it */ function confirmDelete(i) { deleteCloudFile(CCB.cloudFileList[i].filename); stopPropagation() } /** * cancel deleting a cloud file * set origin name display */ function cancelDelete(i) { cloudFileState("over", i); stopPropagation() } /** * display the create card */ function createNew() { cloudFileState("create", 0); } /** * confirm the task of Create new file */ function confirmCreateNew() { var filename = $("#cloud_sketch_name").val(); filename = filename.replace(/(\s*$)/g, ""); if (checkFileName(filename) && filename !== '') { createCloudFile(filename); } } /** * dismiss the task of Create new file */ function cancelCreateNew() { cloudFileState("over", 0); } /** * function to decide cloudFile card state * @param {string} status a state include {"over", "delete", "rename", "create"} * @param {Integer} i the index of file in the filelist */ function cloudFileState(status, i) { if (status == "over") { $("#cloud_fileListArea").addClass("cloud-file"); $("#cloud_fileListArea").removeClass("locked"); if (i > 0) { $("#cloud_fileRow" + i).removeClass("modifiable"); $("#cloud_info_panel" + i).removeClass("unblock"); $("#new_create>div>div> i").removeClass("disabled"); $("#cloud_rename_panel" + i).addClass("unblock"); $("#cloud_delete_panel" + i).addClass("unblock"); } $("#cloud_sketch_name").val(""); $("#new_create").removeClass("active"); } else { $("#cloud_fileListArea").removeClass("cloud-file"); $("#cloud_fileListArea").addClass("locked"); if (i > 0) { $("#cloud_fileRow" + i).addClass("modifiable"); $("#cloud_info_panel" + i).addClass("unblock"); $("#new_create>div>div> i").addClass("disabled"); } if (status == "delete") $("#cloud_delete_panel" + i).removeClass("unblock"); if (status == "rename") $("#cloud_rename_panel" + i).removeClass("unblock"); if (status == "create") $("#new_create").addClass("active"); } } /** * Sets a string to the SketchName input field and triggers the events set from * cloud modal in the rename panel * @param {string?} newName Optional string to place in the sketch_name input. */ function renameBoxSet(i) { var sketchOldName = $("#cloud_name" + i).html().replace(".xml", ""); var sketchNameInput = $("#cloud_sketch_rename" + i); document.getElementById("cloud_sketch_rename" + i).addEventListener("click",function(){ stopPropagation() },true) sketchNameInput.val(sketchOldName); sketchNameInput.attr("size", sketchOldName.length); sketchNameInput.keydown(); sketchNameInput.blur(); sketchNameInput.focus().select(); } /** * fileList name checking */ function checkFileName(filename) { var reg = /[a-zA-Z0-9_-]+/; // standard format checking var reg1 = /[`~!@#$%^&*()+<>?:."{},\/;'[\]]/g; // illegal character checking var reg2 = /[\u4E00-\u9FA5]/g; // Chinese character checking var reg3 = /\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]/g //emoji checking if (filename.length > 4) { if (filename.slice(-4) === ".xml") filename = filename.slice(0, -4); } /** illegal character checking , * avoiding invalid character */ if (reg1.test(filename) || reg2.test(filename)) { // Ardublockly warning Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName"), false ); return null; } /** illegal character checking , * avoiding invalid character */ if (reg3.test(filename)) { // Ardublockly warning Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName4"), false ); return null; } /** Special spelling checking , * avoiding invalid file naming start with "_" or "-" */ if (filename.indexOf("_") == 0 || filename.indexOf("-") == 0) { // Ardublockly warning Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName1"), false ); return null; } filename = filename.replace(/ /g, "_"); var temp = reg.exec(filename); if (temp[0] != filename) { Ardublockly.alertMessage(Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName"), false ); return null; } filename = temp != null ? temp[0] : null; if (filename == null) { // filename is null Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName2"), false ); return null; } if (filename.length > 18) { //over length limitation //Ardublockly warning Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("invalidFileName3"), false ); return null; } let isFileExist = indexGet(filename, CCB.cloudFileList); //repetitive name checking if (isFileExist >= 0) { //Warning repetitive name Ardublockly.alertMessage( Ardublockly.getLocalStr("invalidNameTitle"), Ardublockly.getLocalStr("reptitiveFileName"), false ); // console.log("filename used!"); return null; } return true; } /** * relist cloud filelist * set the selected file as the index 2 in the filelist */ function relistCloudFile(filename) { let i = indexGet(filename, CCB.cloudFileList); var temp = []; var tmp = CCB.cloudFileList[i]; temp.push(tmp); CCB.cloudFileList.splice(i, 1); // cloudlist = CCB.cloudFileList.slice(1, CCB.cloudFileList.length); cloudlist.sort((a, b) => { return b.timestamp - a.timestamp }); CCB.cloudFileList = [{ filename: "_new_", time: null, timestamp: null }] .concat(temp) .concat(cloudlist) } /** * update USER coco event listfiles * @param {Map} events : a array of events with name and api-key */ function updateCoEvent() { $("#cloud_events").empty(); let temp = USER.events.map(function (event) { $("#cloud_events").append( create_opts(event.name, event.eventAPIKey, false) ); }); $("#cloud_events").material_select(); setTimeout(function () { document.getElementById("api-key").value = $("#cloud_events").val() }, 100); console.log("refetching..."); } /*----------Call getCoEvent funciton------------*/ // $("#update_Coevent").on("click", function () { // getCoCloudEvent(); // }); function updateProject() { getCoCloudEvent(); } /*----------update api-key when select event----------- */ // $("#cloud_events") // .change(function () { // $("#api-key").html(""); // // console.log($('#cloud_events').val()); // $("#api-key").html($("#cloud_events").val()); // document.getElementById("api-key").value = $("#cloud_events").val(); // }) // .trigger("change"); function changeProject() { $("#api-key").html(""); // console.log($('#cloud_events').val()); $("#api-key").html($("#cloud_events").val()); document.getElementById("api-key").value = $("#cloud_events").val(); } /* ---------Call logout function-----------------------------*/ $("#modal_logout_btn").on("click", function () { $("#modal_logout_btn").removeClass('blue'); $("#modal_logout_btn").css('background', 'rgba(0,0,0,0.3)') $(".svgImg").css('display', 'block') $(".translate-signout").css('opacity', '0.5') logout(); }); /*----------Call cloud funciton------------*/ // $('#modal_cloudFileSaveAs').on('click', function() { // $("#new_create").addClass("active"); // $('#cloud_fileListArea').removeClass('cloud-file'); // $("#cloud_fileListArea").addClass("locked") // }); // $('#confirm_create').on('click', function() { // console.log("ok"); // }); // $('#cancel_create').on('click', function() { // console.log("cancel it") // $("#new_create").removeClass("active"); // }); $("#modal_cloudFileSave").on("click", function () { if (CCB.userState == true) { // var filename = document.getElementById('cloud_sketchName').value; var reg = /[a-zA-Z0-9_]+/; // var filename = reg.exec($('#cloud_sketchName').val())[0]; let isFileExist = indexGet(filename, CCB.cloudFileList); if (isFileExist >= 0) { //filename has exist in cloud server updateCloudFile(filename); } else { createCloudFile(filename); } } else { Materialize.toast(CCB.str_group.requestLogin, 4000); } }); $("#modal_cloudFileOpen").on("click", function () { if (CCB.userState == true) { var reg = /[a-zA-Z0-9_]+/; // var filename = reg.exec($('#cloud_sketchName').val())[0]; openCloudFile(filename); } else { Materialize.toast(CCB.str_group.requestLogin, 4000); } }); $("#modal_cloudFileDelete").on("click", function () { if (CCB.userState == true) { var reg = /[a-zA-Z0-9_]+/; // var filename = reg.exec($('#cloud_sketchName').val())[0]; deleteCloudFile(filename); } else { Materialize.toast(CCB.str_group.requestLogin, 4000); } }); /** * Append login iframe of cocoblockly * @param {String} parentId the parent dom to append */ function appendIframe(parentId) { const $parent = $(`#${parentId}`); const $iframe = $(document.createElement("iframe")); $iframe.attr('src', '//cocorobo.cn/login/') // $iframe.attr("src", "//staging.cocorobo.hk/login/") .attr("scrolling", "no") .css("margin-top", "-305px") .css("height", "800px") .css("width", "100%") .css("border", "0"); $parent.append($iframe); return $iframe; } /** * Append Teachable Machine iframe * @param {String} parentId the parent dom to append */ function appendTMIframe(parentId, cb, url) { var $parent = $(`#${parentId}`); //$parent.empty() var $iframe = $('#TM_id')[0]; if (!$iframe) { $iframe = $(document.createElement("iframe")); // $iframe.attr('src', '//cocorobo.cn/login/') $iframe.attr("src", url) .attr("scrolling", "no") .attr("id", "TM_id") .attr("name", "TM") .attr("allow", "geolocation; microphone; camera; midi; encrypted-media;") // .css("margin-top", "-305px") .css("height", "100%") .css("width", "100%") .css("position", "relative") .css("background-color", "") .css("border", "0"); $iframe[0].onload = function () { cb(); } $parent.append($iframe); } return $iframe; } function appendTMPosenetIframe(parentId, cb, url) { var $parent = $(`#${parentId}`); //$parent.empty() var $iframe = $('#TM_posenet_id')[0]; if (!$iframe) { $iframe = $(document.createElement("iframe")); // $iframe.attr('src', '//cocorobo.cn/login/') $iframe.attr("src", url) .attr("scrolling", "no") .attr("id", "TM_posenet_id") .attr("name", "TM") .attr("allow", "geolocation; microphone; camera; midi; encrypted-media;") // .css("margin-top", "-305px") .css("height", "100%") .css("width", "100%") .css("position", "relative") .css("background-color", "") .css("border", "0"); $iframe[0].onload = function () { cb(); } $parent.append($iframe); } return $iframe; } function appendTMIframes(parentId, cb, url) { var $parent = $(`#${parentId}`); //$parent.empty() var $iframe = $('#TM_id_object')[0]; if (!$iframe) { $iframe = $(document.createElement("iframe")); // $iframe.attr('src', '//cocorobo.cn/login/') $iframe.attr("src", url) .attr("scrolling", "auto") .attr("id", "TM_id_object") .attr("name", "TM_id_object") .attr("allow", "geolocation; microphone; camera; midi; encrypted-media;") // .css("margin-top", "-305px") .css("height", "100%") .css("width", "100%") .css("position", "relative") .css("background-color", "") .css("border", "0"); $iframe[0].onload = function () { cb(); } $parent.append($iframe); } return $iframe; } function appendTMIframePosenet(parentId, cb, url) { var $parent = $(`#${parentId}`); //$parent.empty() var $iframe = $('#TM_id_posenet')[0]; if (!$iframe) { $iframe = $(document.createElement("iframe")); // $iframe.attr('src', '//cocorobo.cn/login/') $iframe.attr("src", url) .attr("scrolling", "auto") .attr("id", "TM_id_posenet") .attr("name", "TM_id_posenet") .attr("allow", "geolocation; microphone; camera; midi; encrypted-media;") // .css("margin-top", "-305px") .css("height", "100%") .css("width", "100%") .css("position", "relative") .css("background-color", "") .css("border", "0"); $iframe[0].onload = function () { cb(); } $parent.append($iframe); } return $iframe; } $(window).one("load", () => { if (!CCB.asIframe) { // $("#TM_iframe").load("https://cocorobo.cn/beta/ai-demos/teachable-machine/public/ #wrapper") appendIframe("TM_login"); $('#TM_login').children().css("height", "820px"); appendIframe("TM_login_object"); $('#TM_login_object').children().css("height", "820px"); appendIframe("TM_login_posenet"); $('#TM_login_posenet').children().css("height", "820px"); appendIframe("TM_posenet_login"); $("#TM_posenet_login").children().css("height", "820px"); appendIframe("before_login"); appendIframe("cloud_askLogin"); appendIframe("TM_login_Model_download_modal"); $('#TM_login_Model_download_modal').children().css("height", "820px"); $('#TM_login_Model_download_modal').children().css("margin-top", "-225px"); appendIframe("TM_login_webcam_capture_modal"); $('#TM_login_webcam_capture_modal').children().css("width", "820px"); $('#TM_login_webcam_capture_modal').children().css("height", "820px"); appendIframe("TM_login_gesture_recog_modal"); $('#TM_login_gesture_recog_modal').children().css("width", "820px"); $('#TM_login_gesture_recog_modal').children().css("height", "820px"); appendIframe("TM_login_voice_input_modal"); $('#TM_login_voice_input_modal').children().css("width", "820px"); $('#TM_login_voice_input_modal').children().css("height", "820px"); appendIframe("TM_center_game"); $('#TM_center_game').children().css("margin-top", "-300px"); $('#TM_center_game').children().css("height", "820px"); } // api.cocorobo.cn/blockx/filenameid var _id = U.UF.C.queryString("id") || U.UF.C.queryString("Qd") if (_id) { $.ajax(`${CCB.base_url}blockx/${_id}`, { type: "GET", xhrFields: { withCredentials: true }, //data: { userId: CCB.UserInfo.data.username }, success: x => { loadCloudXmlFile(x.xml, x.filename) } }); } localStorage.setItem("modetype", ""); // addObserver("Teachable_Machine") window.addEventListener("storage", function (event) { if (event.key == "modetype" && isgetmcnty == false) { if (event.newValue == "IoT") { $('#status_bar').replaceWith(`${Ardublockly.LOCALISED_TEXT.statusbar}    `); isgetmcnty = true; $('#ports').material_select(); $("#mode")[0].selectedIndex = 0; $("#mode")[0].onchange(); $('.selectMode_input')[0].value = Ardublockly.LOCALISED_TEXT.iot_module; document.getElementById("list").getElementsByTagName("li")[0].onclick(); } else if (event.newValue == "AI") { $('#status_bar').replaceWith(`${Ardublockly.LOCALISED_TEXT.statusbar}    `); isgetmcnty = true; $('#ports').material_select(); $("#mode")[0].selectedIndex = 1; $("#mode")[0].onchange(); $('.selectMode_input')[0].value = Ardublockly.LOCALISED_TEXT.ai_module; document.getElementById("list").getElementsByTagName("li")[1].onclick(); } } }); }); window.addEventListener("message", e => { let data = e.data; if (!CCB.asIframe) { if (typeof data === "object" && data.id === "loginVerify" && data.status === "logged") { $("#TM_login").empty(); $("#TM_login_object").empty(); $("#TM_login_posenet").empty(); $("#TM_posenet_login").empty(); $("#before_login").empty(); $("#cloud_askLogin").empty(); $("#TM_login_Model_download_modal").empty(); $("#TM_login_webcam_capture_modal").empty(); $("#TM_login_gesture_recog_modal").empty(); $('#TM_login_voice_input_modal').empty(); if (CCB.downloadModelUrl != '' && CCB.downloadModelUrl != '//xunlian.cocorobo.cn') { $("#center_game_modal").modal("close"); $("#app_center_modal").modal("open"); } $("#TM_center_game").empty(); Materialize.toast(CCB.str_group.success_userLogin, 3000); CCB.userState = true; getUserProfile(data.data); loginModalStatus(); getCloudFileList(); CCB.UserInfo = data; /** *post login session message into TM_iframe */ let lang = 'en'; document.location.search.substring(1).split('&').forEach((item) => { if (item.split('=')[0] == 'lang') { lang = item.split('=')[1]; } }); data.url = lang; CCB.UserInfo.boards = CCB.boards[0]; if (document.getElementById("TM_id")) { document.getElementById("TM_id").contentWindow.postMessage(data, "*"); } if (document.getElementById("TM_id_object")) { document.getElementById("TM_id_object").contentWindow.postMessage(data, "*"); } if (document.getElementById("TM_id_posenet")) { document.getElementById("TM_id_posenet").contentWindow.postMessage(data, "*"); } } } }); window.addEventListener("message", e => { let data = e.data; if (data) { switch (data.type) { case "screenshot": $("#workspace_screenshot").click(); break; case "code": var _code = getcode(); e.source.postMessage({ "code": _code }, "*") break; case "image": getimage().then(function (img) { e.source.postMessage({ "img": img }, "*") }); break; } } }); function getcode() { var _xml = blockpy.components.editor.getBlocksFromXml(); _xml.setAttribute("type", $("#mode")[0].selectedIndex == 1 ? "AI" : "IoT") var data = Blockly.Xml.domToPrettyText(_xml); return data; } getimage = async function () { let _header = window.location.protocol + "//" let _href = window.location.origin + "/"; let ws = blockpy.components.editor.blockly.svgBlockCanvas_.cloneNode(true); ws.removeAttribute("width"); ws.removeAttribute("height"); ws.removeAttribute("transform"); let styleElem = document.createElementNS("http://www.w3.org/2000/svg", "style"); styleElem.textContent = Blockly.Css.CONTENT.join(''); ws.insertBefore(styleElem, ws.firstChild); let bbox = blockpy.components.editor.blockly.svgBlockCanvas_.getBBox(); let canvas = document.createElement("canvas"); canvas.width = Math.ceil(Math.abs(bbox.x) + bbox.width + 120); canvas.height = Math.ceil(Math.abs(bbox.y) + bbox.height + 50); canvas.appendChild(ws); let ctx = canvas.getContext("2d"); let xml = new XMLSerializer().serializeToString(ws); let test = /xlink:href="[a-zA-z]+:\/\/[^\s]*"/g; let test1 = /xlink:href="blockly\/([^\s]*)"/g; let arr = xml.match(test1) if (arr != null) { let loadImage = function () { return new Promise((resolve) => { let length = arr.length; let count = 0; for (let i = 0; i < length; i++) { let dataURL; let canvas_inline = document.createElement("canvas"); let ctx1 = canvas_inline.getContext("2d"); let image_item = new Image(); image_item.setAttribute("src", arr[i].replace("xlink:href=\"", _href).replace("\"", "")); image_item.onload = function () { //convert image to base64 canvas_inline.width = image_item.width; canvas_inline.height = image_item.height; ctx1.drawImage(image_item, 0, 0); dataURL = canvas_inline.toDataURL("image/png", 1); xml = xml.replace(arr[i], "xlink:href=\"" + dataURL + "\""); count++; } } if (count == length) { return resolve(true); } }); } await loadImage(); } xml = '' + xml + ''; var img = new Image(); img.setAttribute("src", 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(xml)))); let ctxload = function () { return new Promise((resolve) => { img.onload = function () { ctx.drawImage(img, 0, 0); resolve(true) } }); } await ctxload(); return canvas.toDataURL("image/png", 1);; } window.addEventListener("resize", () => { $("#TM_id").css("height", $("#Teachable_Machine")[0].offsetHeight); $("#TM_id_object").css("height", $("#Object_recog_modal")[0].offsetHeight) }) /** *add listener on Teachable Machine modal class *@param {String} parentId dom id *listen on "open" attr, *if hasClass "open" ,start webcam for Teachable Machine iframe *else , stop webcam */ function addObserver(parentId) { let dom = document.querySelector(`#${parentId}`) var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; if (MutationObserver) { var options = { subtree: false, attributes: true, childList: false, }; var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { TMObserver_callback(); }); }); observer.observe(dom, options); } } function TMObserver_callback() { if ($("#Teachable_Machine").hasClass("open")) { document.getElementById("TM_id").contentWindow.postMessage("startCam", "*") } else { document.getElementById("TM_id").contentWindow.postMessage("stopCam", "*") } if ($("#Object_recog_modal").hasClass("open")) { document.getElementById("TM_id_object").contentWindow.postMessage("startCam", "*") } else { document.getElementById("TM_id_object").contentWindow.postMessage("stopCam", "*") } } /** * return the index of object contain filename * @param {String} filename * @param {Array} filelist contain Object [{..},{..},..,] * @return {Integer} the index of object in the array */ function indexGet(filename, filelist) { let count = -1; count = filelist.findIndex(file => { return (filename == file.filenameId || filename == file.filename); }); return count; } /** * get current Date for create file * @return {String} the Date with formatation "YYYY/MM/DD" */ function getCurrentDate() { var myDate = new Date(); var mytime = myDate.toLocaleDateString(); //�繮��硋�枏�齿𧒄�𡢿 mytime.toLocaleString(); // mytime.replace(/\//g,"-") return mytime; } function dateFormat(date) { if (date == null) { return "-/-"; } data = date.split("T")[0].replace(/-/g, "/") return data; } function downloadModel(url) { if (CCB.userState == true) { window.open(url); } else if (CCB.userState == false) { CCB.downloadModelUrl = url; $("#TM_login_Model_download_modal").css("display", "block"); $("#Model_download_modal").css("display", "none"); } } function enterTraining(url) { if (CCB.userState == true) { window.open(url); } else if (CCB.userState == false) { CCB.downloadModelUrl = url; $("#TM_login_Model_download_modal").css("display", "block"); $("#Model_download_modal").css("display", "none"); } } function openLabs(url) { if (url == "#WeTech_Modal") { if (CCB.userState == true) { $(url).modal("open"); } else if (CCB.userState == false) { CCB.downloadModelUrl = url; $("#app_center_modal").modal("close"); $("#center_game_modal").modal("open"); } } else { if (CCB.userState == true) { window.open(url); } else if (CCB.userState == false) { CCB.downloadModelUrl = url; $("#app_center_modal").modal("close"); $("#center_game_modal").modal("open"); } } }