mobile.system 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. <html>
  2. <head>
  3. <title>ArozOS Mobile</title>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="manifest" href="manifest.webmanifest">
  7. <link rel="stylesheet" href="script/semantic/semantic.css">
  8. <link rel="stylesheet" href="script/ao.css">
  9. <script type="text/javascript" src="script/jquery.min.js"></script>
  10. <script type="text/javascript" src="script/semantic/semantic.js"></script>
  11. <script type="text/javascript" src="script/ao_module.js"></script>
  12. <style>
  13. document, body{
  14. height: 100%;
  15. }
  16. .themeColor{
  17. background-color:#1c1c1c;
  18. }
  19. .taskBar{
  20. position:fixed;
  21. top:0px;
  22. left:0px;
  23. width:30px;
  24. height:100%;
  25. overflow: visible !important;
  26. z-index:999;
  27. }
  28. #mainFrame{
  29. width: calc(100% - 30px);
  30. position:fixed;
  31. top:0px;
  32. right:0px;
  33. overflow: hidden;
  34. }
  35. .toggleTaskBar{
  36. position:absolute;
  37. bottom:0px;
  38. right:0px;
  39. margin-right:-20px;
  40. width:30px;
  41. height:90px;
  42. border-radius: 0px 10px 10px 0px;
  43. }
  44. #listMenu{
  45. z-index:1000;
  46. position:fixed;
  47. top:0px;
  48. left:0px;
  49. width:100%;
  50. height:100%;
  51. padding:12px;
  52. background-color: #fcffff;
  53. box-shadow: 3px 3px 5px 0px rgba(207, 207, 207, 0.37);
  54. }
  55. #listMenu .searchBar {
  56. width: 100%;
  57. border-bottom: 2px solid #34b7eb;
  58. }
  59. #listMenu .listItemWrapper {
  60. overflow: hidden;
  61. }
  62. #listMenu .listItemWrapper .groups {
  63. background-color: #f5f5f5;
  64. width: 120px;
  65. height: calc(100% - 40px);
  66. display: inline-block;
  67. overflow-y: auto;
  68. padding-top: 8px;
  69. }
  70. #listMenu .listItemWrapper .groups .item {
  71. padding-left: 7px;
  72. padding-bottom: 6px;
  73. padding-top: 6px;
  74. cursor: pointer;
  75. }
  76. #listMenu .listItemWrapper .groups .item.selected {
  77. color: #34b7eb;
  78. }
  79. #listMenu .listItemWrapper .groups .item:hover {
  80. background-color: #dedede;
  81. }
  82. #listMenuItem{
  83. width: calc(100% - 130px) !important;
  84. float: right;
  85. overflow-y: auto;
  86. height: calc(100% - 40px) !important;
  87. }
  88. #listMenuItem img{
  89. width: 50px;
  90. }
  91. .module.item{
  92. padding:8px;
  93. }
  94. .hideListMenuButton{
  95. position: absolute;
  96. bottom:22px;
  97. left:32px;
  98. cursor:pointer;
  99. }
  100. .hideListMenuButton img{
  101. left:12px;
  102. width:50px;
  103. }
  104. .listMenuLauncher{
  105. position:absolute;
  106. bottom:12px;
  107. left:12px;
  108. cursor:pointer;
  109. }
  110. .blurred{
  111. filter: blur(3px);
  112. }
  113. #backdrop {
  114. background-repeat: no-repeat;
  115. background-size: cover;
  116. background-position: center;
  117. background-image: url('img/desktop/bg/init.jpg');
  118. width: 100%;
  119. height: 100%;
  120. overflow-x: hidden;
  121. pointer-events: none;
  122. }
  123. #windowButtonWrapper{
  124. padding-top:6px;
  125. }
  126. .floatWindowButton{
  127. padding: 5px;
  128. }
  129. .floatWindowButton .minimizedIcon{
  130. width: 20px;
  131. height:20px;
  132. }
  133. .floatWindowButton .normalElements{
  134. padding:8px;
  135. border-bottom: 1px solid #4a4a4a;
  136. cursor:pointer;
  137. vertical-align:middle;
  138. position: relative;
  139. }
  140. .floatWindowButton .normalizedIcon{
  141. width:40;
  142. height:40px;
  143. margin-right:12px;
  144. }
  145. .normalElements .windowTitle{
  146. display:inline-block;
  147. width:200px !important;
  148. vertical-align:middle;
  149. white-space: nowrap;
  150. overflow: hidden;
  151. text-overflow: ellipsis;
  152. }
  153. .fwtab{
  154. position: absolute;
  155. top:0px;
  156. right: 0px;
  157. width: 100%;
  158. height: 100%;
  159. }
  160. #windowWrapper{
  161. height: 100%;
  162. width: 100%;
  163. position: absolute;
  164. top:0px;
  165. right:0px;
  166. }
  167. .floatWindowWrapper{
  168. width: 100%;
  169. height: 100%;
  170. }
  171. .floatWindow{
  172. width: 100%;
  173. height: 100%;
  174. position: absolute;
  175. }
  176. .fwtab iframe{
  177. border: 0px solid transparent;
  178. height: 100%;
  179. }
  180. .floatWindowButton .closebutton{
  181. position: absolute;
  182. font-size: 120%;
  183. color:white;
  184. right: 4px;
  185. top: 4px;
  186. }
  187. </style>
  188. </head>
  189. <body>
  190. <div class="taskBar themeColor" >
  191. <div class="toggleTaskBar themeColor" shown="false" onclick="toggleTaskBar(this);">
  192. <img class="ui image sidebararrow" style="margin-top:8px; margin-left: -10px;" src="img/mobile/keyboard_arrow_right-white-48dp.svg"></img>
  193. </div>
  194. <div class="listMenuLauncher" onclick="showListMenu();">
  195. <img src="img/mobile/apps-white-48dp.svg" style="width: 30px;"/>
  196. </div>
  197. <div id="windowButtonWrapper">
  198. </div>
  199. </div>
  200. <div id="listMenu" style="left:-100%;">
  201. <div class="searchBar" onkeydown="searchModule(event);">
  202. <div class="ui icon fluid input" style="border-radius: 0px !important;">
  203. <input id="searchBar" type="text" placeholder="Search">
  204. <i class="search icon"></i>
  205. </div>
  206. </div>
  207. <dib class="listItemWrapper">
  208. <div class="groups">
  209. <div id="searchResults" class="item" style="display:none;">Search Results</div>
  210. <div class="item groupType selected" group="All">All</div>
  211. <div class="item groupType" group="Media">Media</div>
  212. <div class="item groupType" group="Office">Office</div>
  213. <div class="item groupType" group="Download">Download</div>
  214. <div class="item groupType" group="Files">Files</div>
  215. <div class="item groupType" group="Internet">Internet</div>
  216. <div class="item groupType" group="System Settings">System Settings</div>
  217. <div class="item groupType" group="System Tools">System Tools</div>
  218. <div class="item groupType" group="Utilities">Utilities</div>
  219. <div class="item groupType" group="Other">Other</div>
  220. <div class="hideListMenuButton" onclick="closeListMenu();">
  221. <img class="ui image" src="img/mobile/cancel-black-48dp.svg"></img>
  222. <p>Close Menu</p>
  223. </div>
  224. </div>
  225. <div id="listMenuItem" class="items" align="left">
  226. </div>
  227. </div>
  228. </div>
  229. <div id="mainFrame">
  230. <div id="backdrop">
  231. </div>
  232. <div id="windowWrapper">
  233. </div>
  234. </div>
  235. <script>
  236. var isDesktopMode = true; //Try to emulate Desktop mode
  237. var moduleInstalled = []; //List of installed modules on the system
  238. var desktopThemeList = []; //List of themes installed, same as desktop theme
  239. //initiation Functions
  240. initModuleList();
  241. bindGroupTypeEvents();
  242. initBackdropImage();
  243. //Bind background click
  244. $("#mainFrame").on("touchstart", function(evt){
  245. if ($(this).hasClass("blurred") && $(".taskBar").find(".toggleTaskBar").attr("shown") == "true"){
  246. //hide the taskbar
  247. hideTaskBar();
  248. }
  249. });
  250. //Initialize background image
  251. function initBackdropImage(){
  252. $.get("system/desktop/theme", function(data) {
  253. //Return a list of theme stored on the system
  254. desktopThemeList = data;
  255. $.get("system/desktop/theme?get=true", function(data) {
  256. //Get the user theme settings
  257. changeDesktopTheme(data);
  258. });
  259. });
  260. }
  261. function changeDesktopTheme(themename){
  262. //Match the given theme to the themename
  263. if (themename.includes(":/") == false){
  264. //This is a path
  265. for (var i =0; i < desktopThemeList.length ; i++){
  266. if (desktopThemeList[i].Theme == themename){
  267. var targetImage = desktopThemeList[i].Bglist[0];
  268. $("#backdrop").css("background-image", `url(img/desktop/bg/${themename}/${targetImage})`)
  269. }
  270. }
  271. }else{
  272. //This is a path (user defined background folder)
  273. $.get("system/desktop/theme?load=" + themename, function(data){
  274. if (data.error !== undefined){
  275. //The folder is gone. Use default instead
  276. console.log(data.error);
  277. changeDesktopTheme("default");
  278. }else{
  279. $("#backdrop").css("background-image", `url(media/?file=${data[0]})`)
  280. }
  281. });
  282. }
  283. }
  284. function toggleFullScreen() {
  285. var doc = window.document;
  286. var docEl = doc.documentElement;
  287. var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
  288. var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
  289. if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
  290. requestFullScreen.call(docEl);
  291. }
  292. else {
  293. cancelFullScreen.call(doc);
  294. }
  295. }
  296. //Sidebar
  297. function toggleTaskBar(obj){
  298. if ($(obj).attr("shown") == "true"){
  299. hideTaskBar();
  300. }else{
  301. showTaskBar();
  302. }
  303. }
  304. function hideTaskBar(){
  305. //Hide the taskBar
  306. $(".taskBar").animate({
  307. width: "30px"
  308. },300, "swing");
  309. $(".taskBar").find('.sidebararrow').attr("src","img/mobile/keyboard_arrow_right-white-48dp.svg");
  310. $(".taskBar").find(".toggleTaskBar").attr("shown","false");
  311. $("#mainFrame").removeClass("blurred");
  312. //Minimize all fwbuttons
  313. $(".floatWindowButton").each(function(){
  314. $(this).find(".minimizedElements").show();
  315. $(this).find(".normalElements").hide();
  316. });
  317. }
  318. function showTaskBar(){
  319. //Show the taskbar
  320. $(".taskBar").animate({
  321. width: "300px"
  322. }, 300, "swing", function(){
  323. //Switch all fwbuttons to normal size
  324. $(".floatWindowButton").each(function(){
  325. $(this).find(".minimizedElements").hide();
  326. $(this).find(".normalElements").show();
  327. });
  328. });
  329. $(".taskBar").find('.sidebararrow').attr("src","img/mobile/keyboard_arrow_left-white-48dp.svg");
  330. $(".taskBar").find(".toggleTaskBar").attr("shown","true");
  331. $("#mainFrame").addClass("blurred");
  332. }
  333. //List all modules
  334. function initModuleList(){
  335. $.ajax({
  336. url: "system/modules/list",
  337. success: function(data) {
  338. moduleInstalled = data;
  339. listModulesType("All");
  340. }
  341. });
  342. }
  343. //ListMenu group classification events
  344. function bindGroupTypeEvents(){
  345. $(".groupType").on("click",function(evt){
  346. //Clear all serach results
  347. $("#searchResults").slideUp('fast');
  348. listModulesType($(this).attr("group"));
  349. $(".groupType.selected").removeClass("selected");
  350. $(this).addClass("selected");
  351. /*
  352. var classificationObject = this;
  353. if ($(this).attr("group") == "All"){
  354. $('.item.module').show();
  355. } else if ($(this).attr("group") == "Other"){
  356. var excludeList = ["Media", "Office", "Download", "Files", "Internet", "System Settings", "System Tools", "Utilties"];
  357. $('.item.module').each(function(){
  358. if (excludeList.includes($(this).attr("group")) == false){
  359. $(this).show();
  360. }else{
  361. $(this).hide();
  362. }
  363. });
  364. }else{
  365. $('.item.module').each(function(){
  366. if ($(this).attr("group") == $(classificationObject).attr("group")){
  367. $(this).show();
  368. }else{
  369. $(this).hide();
  370. }
  371. });
  372. }
  373. */
  374. });
  375. }
  376. function searchModule(event) {
  377. if (event.which == 13) {
  378. var keyword = $("#searchBar").val().toLowerCase();
  379. var results = [];
  380. var lessAccurateResults = [];
  381. $(".groupType.selected").removeClass("selected");
  382. $("#searchResults").addClass("selected").slideDown('fast');
  383. //Load all search results
  384. for (var i = 0; i < moduleInstalled.length; i++) {
  385. var thisModule = moduleInstalled[i];
  386. var pathInfo = thisModule["StartDir"].split("/");
  387. for (var j = 0; j < pathInfo.length; j++) {
  388. pathInfo[j] = pathInfo[j].toLowerCase();
  389. }
  390. if (thisModule["Name"].toLowerCase().includes(keyword)) {
  391. results.push(thisModule);
  392. } else if (pathInfo.includes(keyword.toLowerCase()) || pathInfo.includes(keyword.split(" ").join("_").toLowerCase())) {
  393. lessAccurateResults.push(thisModule);
  394. }
  395. }
  396. results = results.concat(lessAccurateResults);
  397. //Append the results to list
  398. $("#listMenuItem").html("");
  399. for (var i = 0; i < results.length; i++) {
  400. generateListMenuItem(results[i]);
  401. }
  402. if (results.length == 0) {
  403. //Append a custom no results div to the content
  404. $("#listMenuItem").append(`<div class="item module"><span><img class="ui middle aligned tiny image" src="img/system/not found.png" style="padding-right: 12px;">No Results</span></div>`);
  405. }
  406. }
  407. }
  408. function listModulesType(groupType) {
  409. var listingItems = [];
  410. if (groupType == "All") {
  411. //List all of the items
  412. for (var i = 0; i < moduleInstalled.length; i++) {
  413. if (moduleInstalled[i]["StartDir"] != "") {
  414. listingItems.push(moduleInstalled[i]);
  415. }
  416. }
  417. } else if (groupType == "Other") {
  418. var excludeList = ["Media", "Office", "Download", "Files", "Internet", "System Settings", "System Tools", "Utilties"];
  419. //List the Other groups
  420. for (var i = 0; i < moduleInstalled.length; i++) {
  421. if (excludeList.includes(moduleInstalled[i]["Group"]) == false && moduleInstalled[i]["StartDir"] != "") {
  422. listingItems.push(moduleInstalled[i]);
  423. }
  424. }
  425. } else {
  426. //List the given group
  427. for (var i = 0; i < moduleInstalled.length; i++) {
  428. if (moduleInstalled[i]["Group"] == groupType && moduleInstalled[i]["StartDir"] != "") {
  429. listingItems.push(moduleInstalled[i]);
  430. }
  431. }
  432. }
  433. //List the item to the listmenu
  434. $("#listMenuItem").html("");
  435. for (var i = 0; i < listingItems.length; i++) {
  436. var thisModule = listingItems[i];
  437. generateListMenuItem(thisModule);
  438. }
  439. if (listingItems.length == 0) {
  440. $("#listMenuItem").html(`<div class="item module"><span><img class="ui middle aligned tiny image" src="img/system/not found.png" style="padding-right: 12px;">No WebApp found</span></div>`)
  441. }
  442. }
  443. function generateListMenuItem(thisModule) {
  444. var icon = thisModule["IconPath"];
  445. if (icon == "") {
  446. //Use default system icon
  447. icon = "img/system/service.png";
  448. }
  449. var name = thisModule["Name"];
  450. var startdir = thisModule["StartDir"];
  451. var group = thisModule["Group"];
  452. var fwsupport = "false";
  453. if (thisModule["SupportFW"]) {
  454. fwsupport = "true";
  455. }
  456. $("#listMenuItem").append(`<div class="item module" module="${name}" startdir="${startdir}" fw="${fwsupport}" group="${group}" onclick="openModuleFromMenu(this);">
  457. <span>
  458. <img class="ui middle aligned tiny image" src="${icon}" style="padding-right: 12px;"></img>
  459. ${name}
  460. </span>
  461. </div>`);
  462. }
  463. function closeListMenu(callback = undefined){
  464. $("#listMenu").animate({
  465. left: window.innerWidth * -1
  466. },300,"swing", function(){
  467. $(".taskBar").animate({
  468. width: "300px",
  469. },300,"swing", function(){
  470. if (typeof callback != "undefined"){
  471. callback();
  472. }
  473. });
  474. });
  475. }
  476. //Bind swip events
  477. document.addEventListener('touchstart', handleTouchStart, false);
  478. document.addEventListener('touchmove', handleTouchMove, false);
  479. var xDown = null;
  480. var yDown = null;
  481. var swipeTarget = null;
  482. var targetType = "fw";
  483. function getTouches(evt) {
  484. return evt.touches || // browser API
  485. evt.originalEvent.touches; // jQuery
  486. }
  487. function handleTouchStart(evt) {
  488. const firstTouch = getTouches(evt)[0];
  489. if ($(evt.target).hasClass("taskBar")){
  490. swipeTarget = evt.target;
  491. targetType = "taskbar"
  492. }else{
  493. swipeTarget = getFloatWindowObjectFromPath(evt.path);
  494. }
  495. xDown = firstTouch.clientX;
  496. yDown = firstTouch.clientY;
  497. };
  498. function getFloatWindowObjectFromPath(path){
  499. var targetObject = undefined;
  500. targetType = undefined
  501. path.forEach(object => {
  502. if ($(object).hasClass("floatWindowButton")){
  503. targetObject = object
  504. targetType = "fw"
  505. }
  506. })
  507. return targetObject;
  508. }
  509. function handleTouchMove(evt) {
  510. if ( ! xDown || ! yDown ) {
  511. return;
  512. }
  513. var xUp = evt.touches[0].clientX;
  514. var yUp = evt.touches[0].clientY;
  515. var xDiff = xDown - xUp;
  516. var yDiff = yDown - yUp;
  517. if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
  518. if ( xDiff > 0 ) {
  519. /* left swipe */
  520. if (swipeTarget !== undefined && targetType == "fw"){
  521. closeFloatWindow($(swipeTarget).attr("windowId"));
  522. }else if (swipeTarget !== undefined && targetType == "taskbar"){
  523. hideTaskBar();
  524. }
  525. } else {
  526. /* right swipe */
  527. if (swipeTarget !== undefined && targetType == "fw"){
  528. //Allow left or right swipe to remove fw
  529. closeFloatWindow($(swipeTarget).attr("windowId"));
  530. }else if (swipeTarget !== undefined && targetType == "taskbar"){
  531. //Right swipe on taskbar
  532. if ($(swipeTarget).find(".toggleTaskBar").attr("shown") == "true"){
  533. //Already shown. Toggle list menu
  534. showListMenu();
  535. }else{
  536. showTaskBar();
  537. }
  538. }
  539. }
  540. } else {
  541. if ( yDiff > 0 ) {
  542. /* up swipe */
  543. } else {
  544. /* down swipe */
  545. }
  546. }
  547. /* reset values */
  548. xDown = null;
  549. yDown = null;
  550. swipeTarget = null;
  551. };
  552. function showListMenu(callback = undefined){
  553. if ($(".taskBar").find(".toggleTaskBar").attr("shown") == "false"){
  554. $(".taskBar").find(".toggleTaskBar").attr("shown", "true");
  555. $(".taskBar").find('.sidebararrow').attr("src","img/mobile/keyboard_arrow_left-white-48dp.svg");
  556. $("#mainFrame").addClass("blurred");
  557. }
  558. $(".taskBar").animate({
  559. width: window.innerWidth,
  560. },300, "swing", function(){
  561. //Switch all fwbuttons to normal size
  562. $(".floatWindowButton").each(function(){
  563. $(this).find(".minimizedElements").hide();
  564. $(this).find(".normalElements").show();
  565. });
  566. //Show list menu
  567. $("#listMenu").animate({
  568. left: 0
  569. },300,"swing", function(){
  570. if (typeof callback != "undefined"){
  571. callback();
  572. }
  573. });
  574. })
  575. }
  576. function openModule(moduleName) {
  577. $.get("system/modules/getLaunchPara?module=" + moduleName, function(data) {
  578. console.log(data);
  579. if (data.error !== undefined) {
  580. //Something went wrong.
  581. console.log("Unable to open module " + moduleName);
  582. if (data.error == "Not logged in."){
  583. //Session expired
  584. window.location.href = "login.system";
  585. }
  586. }else {
  587. //Launch the given module
  588. var url = data["StartDir"];
  589. var size = [undefined, undefined];
  590. var icon = "img/system/favicon.png";
  591. if (data["IconPath"] != "") {
  592. icon = data["IconPath"];
  593. }
  594. var title = data["Name"];
  595. //Check if the module support fw mode. If yes, launch with fwmode url. IF not, launch to index
  596. if (data["SupportFW"] == true) {
  597. if (data["LaunchFWDir"] != null) {
  598. url = data["LaunchFWDir"];
  599. }
  600. if (data["InitFWSize"] != null) {
  601. size = data["InitFWSize"];
  602. }
  603. }
  604. //Launch the given module
  605. newFloatWindow({
  606. url: url,
  607. width: size[0],
  608. height: size[1],
  609. appicon: icon,
  610. title: title
  611. });
  612. closeListMenu(function(){
  613. hideTaskBar();
  614. });
  615. }
  616. });
  617. }
  618. function openModuleFromMenu(object) {
  619. var moduleName = $(object).attr("module");
  620. openModule(moduleName);
  621. }
  622. //In mobile interface, there will be some option ignored by default
  623. function newFloatWindow(options){
  624. //Hide all other floatWindows
  625. $(".floatWindowWrapper").fadeOut("fast");
  626. //Construct the new window
  627. var windowID = Date.now();
  628. var parent = options.parent || "";
  629. var callback = options.callback || "";
  630. //Create a new iframe
  631. $("#windowWrapper").append(` <div class="floatWindowWrapper" windowId="${windowID}">
  632. <div class="floatWindow" windowId="${windowID}" parent="${parent}" callback="${callback}">
  633. <div class="fwtab">
  634. <iframe src="${options.url}" style="width: 100%; height: 100%;"></iframe>
  635. </div>
  636. </div>
  637. </div>`);
  638. //Create the button
  639. var title = options.title || "New FloatWindow";
  640. $("#windowButtonWrapper").append(`
  641. <div class="floatWindowButton" windowID="${windowID}" onclick="focusTab(this)">
  642. <div class="minimizedElements">
  643. <img class="minimizedIcon" src="${options.appicon}">
  644. </div>
  645. <div class="normalElements" style="display:none;">
  646. <img class="ui normalizedIcon middle aligned image" src="${options.appicon}">
  647. <span class="windowTitle" style="color:white;">${title}</span>
  648. <div class="closebutton" onclick="closefw(this);"><i class="remove icon"></i></div>
  649. </div>
  650. </div>
  651. `);
  652. }
  653. ///Functions realted to window resize and auto scaling
  654. function updateWindowDimensions(){
  655. $("#backdrop").css({
  656. width: window.innerWidth,
  657. height: window.innerHeight
  658. });
  659. }
  660. updateWindowDimensions();
  661. $(window).on("resize", function(data){
  662. updateWindowDimensions();
  663. })
  664. //Float Window APIs
  665. function setFloatWindowTitle(id, title){
  666. $(".floatWindowButton").each(function(){
  667. if ($(this).attr("windowId") == id){
  668. $(this).find(".windowTitle").text(title);
  669. }
  670. })
  671. }
  672. function getFloatWindowByID(id){
  673. var targetObejct = undefined;
  674. $(".floatWindowWrapper").each(function(){
  675. if ($(this).attr("windowId") == id){
  676. targetObejct = $(this);
  677. }
  678. });
  679. return targetObejct;
  680. }
  681. function MoveFloatWindowToTop(targetfw){
  682. //Check if this windows is already topped
  683. if ($(targetfw).is(":visible")){
  684. //Already topped
  685. return;
  686. }
  687. $(".floatWindowWrapper").each(function(){
  688. $(this).fadeOut("fast");
  689. });
  690. console.log(targetfw);
  691. $(targetfw).parent().fadeIn("fast");
  692. }
  693. function focusTab(object){
  694. var windowID = $(object).attr("windowId");
  695. //Hide all other flowWindows
  696. $(".floatWindowWrapper").fadeOut("fast");
  697. //Show the target fw
  698. var fw = getFloatWindowByID(windowID);
  699. fw.fadeIn("fast", function(){
  700. hideTaskBar();
  701. });
  702. }
  703. function getFloatWindowByID(id){
  704. var targetObejct = undefined;
  705. $(".floatWindowWrapper").each(function(){
  706. if ($(this).attr("windowId") == id){
  707. targetObejct = $(this);
  708. }
  709. });
  710. return targetObejct;
  711. }
  712. function setFloatWindowResizePolicy(id, allowResize){
  713. //Disabled in mobile mode
  714. }
  715. function setFloatWindowSize(id, width, height){
  716. //Disabled in mobile mode
  717. }
  718. function closeFloatWindow(windowID){
  719. //Get the content iframe with that windowID
  720. var contentWindow = getFloatWindowByID(windowID).find("iframe")[0].contentWindow;
  721. console.log(contentWindow);
  722. try {
  723. if (contentWindow.ao_module_close === undefined) {
  724. //This module do not use ao_module wrapper. Close it directly.
  725. closeFwProcess(windowID);
  726. } else {
  727. //Pass the closing events to the window itself
  728. contentWindow.ao_module_close();
  729. }
  730. } catch (ex) {
  731. //Problems of closing floatWindow. Force closing.
  732. closeFwProcess(windowID);
  733. }
  734. }
  735. function closefw(object){
  736. var windowID = $(object).parent().parent().attr("windowID");
  737. closeFloatWindow(windowID);
  738. }
  739. function closeFwProcess(windowID){
  740. //Remove the window object
  741. $(".floatWindowWrapper").each(function(){
  742. if ($(this).attr("windowId") == windowID){
  743. $(this).fadeOut("fast",function(){
  744. $(this).remove();
  745. });
  746. }
  747. });
  748. //Remove the button object
  749. $(".floatWindowButton").each(function(){
  750. if ($(this).attr("windowId") == windowID){
  751. $(this).fadeOut("fast",function(){
  752. $(this).remove();
  753. });
  754. }
  755. });
  756. }
  757. </script>
  758. </body>
  759. </html>