personalization.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="mobile-web-app-capable" content="yes">
  5. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  6. <meta charset="UTF-8">
  7. <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
  8. <script src="../../script/jquery.min.js"></script>
  9. <script src="../../script/semantic/semantic.min.js"></script>
  10. <script src="../../script/ao_module.js"></script>
  11. <style>
  12. .hidden{
  13. display:none;
  14. }
  15. .backgroundpreview{
  16. border: 1px solid #898989;
  17. }
  18. .colorpallete{
  19. border: 1px solid transparent;
  20. cursor: pointer;
  21. }
  22. .colorpallete:hover{
  23. border: 1px solid white;
  24. }
  25. </style>
  26. </head>
  27. <body>
  28. <div class="ui tabular menu" style="position:fixed; top:0px; left:0px; width: 100%;">
  29. <div class="active item" data-tab="wallpaper">Wallpaper</div>
  30. <div class="item" data-tab="sound">Sound</div>
  31. <div class="item" data-tab="theme">Theme</div>
  32. <div class="item" data-tab="advance">Advance</div>
  33. </div>
  34. <div style="position:fixed; top: 42px; left:0px; width: 100%; height: calc(100% - 42px); overflow-y:auto;">
  35. <div class="ui active tab" data-tab="wallpaper">
  36. <!-- Wallpaper Functions -->
  37. <br>
  38. <div class="ui container">
  39. <h3 class="ui header">
  40. <i class="image outline icon"></i>
  41. <div class="content">
  42. Wallpapers
  43. <div class="sub header">Manage your desktop preferences</div>
  44. </div>
  45. </h3>
  46. <div class="ui divider"></div>
  47. <div class="ui grid">
  48. <div class="ten wide column">
  49. <img id="mainBackground" class="ui fluid image backgroundpreview" src="">
  50. </div>
  51. <div class="six wide column">
  52. </div>
  53. </div>
  54. <div class="ui divider"></div>
  55. <div id="backgroundPreviewList" class="ui grid">
  56. <div class="four wide column">
  57. <img class="ui fluid image backgroundpreview" src="">
  58. </div>
  59. <div class="four wide column">
  60. <img class="ui fluid image backgroundpreview" src="">
  61. </div>
  62. <div class="four wide column">
  63. <img class="ui fluid image backgroundpreview" src="">
  64. </div>
  65. <div class="four wide column">
  66. <img class="ui fluid image backgroundpreview" src="">
  67. </div>
  68. </div>
  69. <div class="ui divider"></div>
  70. <h4 class="ui header">
  71. Background Wallpaper
  72. <div class="sub header">Set your desktop background wallpaper theme.</div>
  73. </h4>
  74. <select id="wallpaperlist" class="ui fluid dropdown allowSelectDefaultThemes" onchange="handleBackgroundSelectionChange(this.value);">
  75. <option value="">Wallpaper Packs</option>
  76. </select>
  77. <small>This option will be disabled by default if you have set your "User Defined Wallpaper" in Advance tab.</small>
  78. <br> <br>
  79. <button class="ui small green right floated button allowSelectDefaultThemes" onclick="applyWallpaper();"><i class="checkmark icon"></i> Apply Wallpaper</button>
  80. <br><br><br>
  81. <div class="ui green segment" style="display:none" id="wallpaperChangeConfirm">
  82. <h4 class="ui header">
  83. <i class="checkmark green icon"></i>
  84. <div class="content">
  85. Wallpaper Updated
  86. <div class="sub header">You should be seeing your desktop wallpaper change in a moment.</div>
  87. </div>
  88. </h4>
  89. </div>
  90. <!-- Wallpaper change interval-->
  91. <div class="ui divider"></div>
  92. <h4 class="ui header">
  93. Wallpaper Interval
  94. <div class="sub header">Set the interval between the wallpaper image cycles.</div>
  95. </h4>
  96. <select id="changeInterval" class="ui fluid dropdown" onchange="handleIntervalChange(this.value);">
  97. <option value="10">10 seconds</option>
  98. <option value="30">30 seconds</option>
  99. <option value="60">60 seconds</option>
  100. <option value="180">3 minutes</option>
  101. <option value="300">5 minutes</option>
  102. <option value="600">10 minutes</option>
  103. <option value="1800">30 minutes</option>
  104. <option value="3600">1 hour</option>
  105. </select>
  106. <div class="ui green segment" style="display:none" id="interfaceChangeConfirm">
  107. <h4 class="ui header">
  108. <i class="checkmark green icon"></i>
  109. <div class="content">
  110. Wallpaper Interval Updated
  111. <div class="sub header">This setting will only apply to this browser</div>
  112. </div>
  113. </h4>
  114. </div>
  115. </div>
  116. <br><br><br>
  117. </div>
  118. <div class="ui tab" data-tab="sound">
  119. <br>
  120. <div class="ui container">
  121. <h3 class="ui header">
  122. <i class="music icon"></i>
  123. <div class="content">
  124. System Sound
  125. <div class="sub header">Customize system sound effect</div>
  126. </div>
  127. </h3>
  128. <div class="ui divider"></div>
  129. <h4 class="ui header">
  130. Custom Startup Sound
  131. <div class="sub header">User defined startup sound to play when login to the web desktop</div>
  132. </h4>
  133. <h3 id="userSelectedStartupSound">Disabled</h3>
  134. <button class="ui small right floated button" onclick="clearStartupAudioSelection()"><i class="remove icon"></i> Clear Selection</button>
  135. <button class="ui small black right floated button" onclick="selectStartupAudio();"><i class="folder open icon"></i> Select File</button>
  136. <br><br>
  137. <div class="ui divider"></div>
  138. </div>
  139. </div>
  140. <div class="ui tab" data-tab="theme">
  141. <!-- Theme Color Related !-->
  142. <br>
  143. <div class="ui container">
  144. <h3 class="ui header">
  145. <i class="paint brush icon"></i>
  146. <div class="content">
  147. Theme Color
  148. <div class="sub header">Change the system theme color settings</div>
  149. </div>
  150. </h3>
  151. <div class="ui divider"></div>
  152. <div class="ui container">
  153. <div id="colorgrid">
  154. Loading...
  155. </div>
  156. </div>
  157. <br>
  158. <div class="ui divider"></div>
  159. <button class="ui small basic black button" onclick="restoreDefaultThemeColor();">Restore Default</button>
  160. <br><br><br>
  161. </div>
  162. </div>
  163. <div class="ui tab" data-tab="advance">
  164. <!-- Advance User Customization !-->
  165. <br>
  166. <div class="ui container">
  167. <h3 class="ui header">
  168. <i class="setting icon"></i>
  169. <div class="content">
  170. Advance Customization
  171. <div class="sub header">Manage your desktop preferences</div>
  172. </div>
  173. </h3>
  174. <div class="ui divider"></div>
  175. <h4 class="ui header">
  176. User Defined Wallpaper
  177. <div class="sub header">Advanced user customization function for desktop interface</div>
  178. </h4>
  179. <h3 id="userSelectedFolderPath">Disabled</h3>
  180. <p>If you have set a folder for loading desktop wallpapers, the image files from that folder will be used instead of the system build in wallpapers.</p>
  181. <button class="ui small right floated button" onclick="clearUserSelectedFolder();"><i class="remove icon"></i> Clear Selection</button>
  182. <button class="ui small black right floated button" onclick="selectUserFolder();"><i class="folder open icon"></i> Select Folder</button>
  183. <br><br>
  184. </div>
  185. </div>
  186. </div>
  187. <br><br>
  188. <script>
  189. var desktopThemeList = [];
  190. var isStartingUp = true;
  191. var cancelColorRestore = false; //If the user clicked on the target color pallete, do not restore the desktop to its original color before selection
  192. $(".dropdown").dropdown();
  193. $('.tabular.menu .item').tab();
  194. //Startup process
  195. initDefaultBackgroundChangeValue();
  196. initUserDefinedWallpaperFolder(function(themeName){
  197. initCurrentBackgroundPreview(themeName);
  198. });
  199. generateColorGrids();
  200. getStartupAudio();
  201. //Return the data stored in the theme settings
  202. //Will return either theme pack name or path for user defined folder
  203. function initUserDefinedWallpaperFolder(callback = undefined){
  204. $.get("../../system/desktop/theme?get=true", function(data) {
  205. if (data.includes(":/")){
  206. //This is a path
  207. $("#userSelectedFolderPath").text(data);
  208. $(".allowSelectDefaultThemes").addClass("disabled");
  209. }else{
  210. $("#userSelectedFolderPath").text("Disabled");
  211. }
  212. if (callback != undefined){
  213. callback(data);
  214. }
  215. });
  216. }
  217. function initDefaultBackgroundChangeValue(){
  218. if (localStorage.getItem("ao/desktop/backgroundInterval") == null){
  219. //No background interval set.
  220. $("#changeInterval").dropdown("set selected", "30");
  221. }else{
  222. //There is already a setting for background interval change. Use that instead
  223. var changeInterval = localStorage.getItem("ao/desktop/backgroundInterval");
  224. $("#changeInterval").dropdown("set selected", changeInterval);
  225. }
  226. }
  227. //Startup sound
  228. function selectStartupAudio(){
  229. ao_module_openFileSelector(setStartupAudio, undefined,"file",{
  230. filter: ["mp3", "aac", "ogg", "wav"]
  231. });
  232. }
  233. function setStartupAudio(filedata){
  234. var filename = filedata[0].filename;
  235. var filepath = filedata[0].filepath;
  236. $("#userSelectedStartupSound").text(filepath);
  237. $.ajax({
  238. url: "../../system/desktop/preference",
  239. method: "GET",
  240. data: {preference: "startup-audio", value: filepath},
  241. success: function(data){
  242. console.log(data);
  243. }
  244. });
  245. }
  246. function getStartupAudio(callback=undefined){
  247. $.ajax({
  248. url: "../../system/desktop/preference",
  249. method: "GET",
  250. data: {preference: "startup-audio"},
  251. success: function(data){
  252. if (data != undefined && data != ""){
  253. $("#userSelectedStartupSound").text(data);
  254. }
  255. if (callback != undefined){
  256. callback(data);
  257. }else{
  258. console.log(data);
  259. }
  260. }
  261. });
  262. }
  263. function clearStartupAudioSelection(){
  264. $.ajax({
  265. url: "../../system/desktop/preference",
  266. method: "GET",
  267. data: {preference: "startup-audio", remove: "true"},
  268. success: function(data){
  269. $("#userSelectedStartupSound").text("Disabled");
  270. }
  271. });
  272. }
  273. //Change the interval to the given
  274. function handleIntervalChange(newInterval){
  275. //Show change finsihed
  276. if (isStartingUp){
  277. //Ignore startup change
  278. return;
  279. }
  280. //Save interval to localStorage
  281. localStorage.setItem("ao/desktop/backgroundInterval", newInterval)
  282. $("#interfaceChangeConfirm").slideDown('fast').delay(3000).slideUp('fast');
  283. //Restart desktop background changer interval
  284. if (ao_module_virtualDesktop){
  285. console.log("Restarting desktop background changer interval")
  286. if (parent.backgroundIntervalCounter){
  287. parent.clearInterval(parent.backgroundIntervalCounter);
  288. }
  289. parent.initBackgroundSwitchingAnimation();
  290. }
  291. }
  292. function selectUserFolder(){
  293. ao_module_openFileSelector(folderSelected, undefined,"folder",false);
  294. }
  295. function folderSelected(filedata){
  296. for (var i=0; i < filedata.length; i++){
  297. var filename = filedata[i].filename;
  298. var filepath = filedata[i].filepath;
  299. //Save the overwrite folder path
  300. $("#userSelectedFolderPath").text(filepath);
  301. $.get("../../system/desktop/theme?set=" + filepath, function(data) {
  302. //Reload desktop background pack
  303. if (ao_module_virtualDesktop){
  304. parent.changeDesktopTheme(filepath);
  305. }
  306. //Disable change to system build in themes
  307. $(".allowSelectDefaultThemes").addClass("disabled");
  308. //Load the preview
  309. initCurrentBackgroundPreview();
  310. });
  311. }
  312. }
  313. function clearUserSelectedFolder(){
  314. //Clear user selected folder
  315. $.get("../../system/desktop/theme?set=default", function(data) {
  316. //Reload desktop background pack
  317. if (ao_module_virtualDesktop){
  318. parent.changeDesktopTheme("default");
  319. }
  320. //Re-enable the default theme seelct
  321. $(".allowSelectDefaultThemes").removeClass("disabled");
  322. $("#userSelectedFolderPath").text("Disabled");
  323. initUserDefinedWallpaperFolder();
  324. initCurrentBackgroundPreview();
  325. });
  326. }
  327. function initCurrentBackgroundPreview(){
  328. //Get the list of theme in the system
  329. $.get("../../system/desktop/theme", function(data) {
  330. desktopThemeList = data;
  331. //Generate the wallpaper list
  332. $("#wallpaperlist").html("");
  333. var deftaultData = "";
  334. desktopThemeList.forEach(themepack => {
  335. var encodedData = encodeURIComponent(JSON.stringify(themepack));
  336. var themeName = themepack.Theme.charAt(0).toUpperCase() + themepack.Theme.slice(1);
  337. $("#wallpaperlist").append(`<option value="${encodedData}">${themeName}</option>`);
  338. if (themepack.Theme == "default"){
  339. deftaultData = encodedData;
  340. }
  341. });
  342. //Get the one the user is currently using
  343. $.get("../../system/desktop/theme?get=true", function(data) {
  344. //Get the user theme settings
  345. $(".backgroundpreview").attr('src','../../img/desktop/bg/nobg.jpg');
  346. //Check if the theme is custom path
  347. if (data.includes(":/")){
  348. //Is path. Load path preview
  349. $.get("../../system/desktop/theme?load=" + data, function(imagelist){
  350. //Load background preview
  351. loadBackgroundPreviewForCustomFolder(imagelist);
  352. //End of startup process
  353. isStartingUp = false;
  354. });
  355. }else{
  356. //Check if the theme exists
  357. var themeExists = false;
  358. var targetThemeObject;
  359. desktopThemeList.forEach(theme => {
  360. if (theme.Theme == data){
  361. //Theme exists
  362. themeExists = true;
  363. targetThemeObject = theme;
  364. }
  365. });
  366. if (themeExists == false){
  367. //This theme not exists. Do not load preview
  368. $("#wallpaperlist").dropdown("set selected","Default");
  369. }else{
  370. loadBackgroundPreview(targetThemeObject);
  371. var themeName = data.charAt(0).toUpperCase() + data.slice(1)
  372. $("#wallpaperlist").dropdown("set selected",themeName);
  373. }
  374. //End of startup process
  375. isStartingUp = false;
  376. }
  377. });
  378. });
  379. }
  380. function loadBackgroundPreviewForCustomFolder(imageList){
  381. $("#backgroundPreviewList").html("");
  382. $("#mainBackground").attr("src","../../media/?file=" + imageList[0]);
  383. for (var i = 1; i < imageList.length; i++){
  384. $("#backgroundPreviewList").append(`<div class="four wide column">
  385. <img class="ui fluid image backgroundpreview" src="${"../../media/?file=" + imageList[i]}">
  386. </div>`);
  387. }
  388. }
  389. function loadBackgroundPreview(targetThemeObject){
  390. $("#backgroundPreviewList").html("");
  391. var imageList = targetThemeObject.Bglist;
  392. $("#mainBackground").attr("src","../../img/desktop/bg/" + targetThemeObject.Theme + "/" + imageList[0]);
  393. for (var i = 1; i < imageList.length; i++){
  394. $("#backgroundPreviewList").append(`<div class="four wide column">
  395. <img class="ui fluid image backgroundpreview" src="${"../../img/desktop/bg/" + targetThemeObject.Theme + "/" + imageList[i]}">
  396. </div>`);
  397. }
  398. }
  399. function handleBackgroundSelectionChange(value){
  400. var targetThemeObject = JSON.parse(decodeURIComponent(value));
  401. loadBackgroundPreview(targetThemeObject);
  402. }
  403. function generateColorGrids(){
  404. $("#colorgrid").html("");
  405. $.getJSON("./colors.json", function(data){
  406. for (let key in data) {
  407. let colorcodes = data[key];
  408. let thisSection = '';
  409. thisSection += (`<div class="ui grid">`);
  410. thisSection += (`<div class="five wide column">
  411. ${key.charAt(0).toUpperCase() + key.slice(1)}
  412. </div>`);
  413. for (let colorIndex in colorcodes) {
  414. if (colorIndex < 300){
  415. //Skip all the light colors
  416. continue;
  417. }
  418. let colorHexCoxde = colorcodes[colorIndex];
  419. thisSection += (`<div class="one wide column colorpallete" hex="${colorHexCoxde}" material="${colorIndex}" style="background-color: ${colorHexCoxde}; text-align: center;"><br></div>`);
  420. }
  421. thisSection += "</div>"
  422. $("#colorgrid").append(thisSection);
  423. }
  424. //Bind events to change the color for preview
  425. let previousColorCode = {};
  426. $(".colorpallete").on({
  427. mouseover: function() {
  428. event.preventDefault();
  429. $(this).animate({opacity: 0.25}, 100);
  430. //Save the current color
  431. var thisColorCode = $(this).attr("hex");
  432. previousColorCode["floatWindow"] = $(parent.window.content.document).find(".floatWindow .controls").css("background-color");
  433. previousColorCode["statusbar"] = $(parent.window.content.document).find("#statusbar").css("background-color");
  434. previousColorCode["navimenu"] = $(parent.window.content.document).find("#navimenu").css("background-color");
  435. //Set the preview color
  436. if (ao_module_virtualDesktop){
  437. $(parent.window.content.document).find(".floatWindow .controls").css("background-color",hexToRgbA(thisColorCode, 0.85));
  438. $(parent.window.content.document).find("#statusbar").css("background-color",thisColorCode );
  439. $(parent.window.content.document).find("#navimenu").css("background-color",hexToRgbA(thisColorCode, 0.5));
  440. }
  441. },
  442. mouseout: function() {
  443. event.preventDefault();
  444. $(this).animate({opacity: 1}, 100);
  445. $(".themeColorSolid").css("background-color", "");
  446. //Restore the original color
  447. if (ao_module_virtualDesktop && !cancelColorRestore){
  448. $(parent.window.content.document).find(".floatWindow .controls").css("background-color",previousColorCode["floatWindow"]);
  449. $(parent.window.content.document).find("#statusbar").css("background-color",previousColorCode["statusbar"]);
  450. $(parent.window.content.document).find("#navimenu").css("background-color",previousColorCode["navimenu"]);
  451. }else if (cancelColorRestore){
  452. cancelColorRestore = false;
  453. }
  454. }
  455. });
  456. //Setting the current theme
  457. $(".colorpallete").on("click", function(){
  458. var colorCode = $(this).attr("hex");
  459. writePreference("themecolor",colorCode, function(data){
  460. if (data.error != undefined){
  461. alert(data.error);
  462. }
  463. //Tick the current using color
  464. tickTheCurrentSelectedThemeColor();
  465. //Update the desktop theme color
  466. if (ao_module_virtualDesktop){
  467. cancelColorRestore=true;
  468. parent.setThemeColor(colorCode);
  469. }
  470. });
  471. });
  472. tickTheCurrentSelectedThemeColor();
  473. });
  474. }
  475. function restoreDefaultThemeColor(){
  476. $.ajax({
  477. url: "../../system/file_system/preference",
  478. data: {key: "themecolor", remove: true},
  479. success: function(data){
  480. if (data.error !== undefined){
  481. console.log(data.error);
  482. }else{
  483. if (ao_module_virtualDesktop){
  484. //Just emulate the restored effect first,
  485. //The theme color will restore after refresh
  486. parent.setThemeColor("#262626");
  487. }
  488. }
  489. }
  490. });
  491. }
  492. function tickTheCurrentSelectedThemeColor(){
  493. //Tick the one that is currently using
  494. readPreference("themecolor", function(data){
  495. if (data.error == undefined){
  496. //See if there is a colorpallete match the hex string
  497. $(".colorpallete").each(function(){
  498. if ($(this).attr("hex") == data){
  499. //This is the pallete to tick
  500. $(this).html(`<i style="color:white; margin-left: -4px;" class="checkmark icon"></i>`);
  501. }else{
  502. $(this).html(`<br>`);
  503. }
  504. })
  505. }
  506. })
  507. }
  508. function readPreference(key, callback=undefined){
  509. $.ajax({
  510. url: "../../system/file_system/preference",
  511. data: {key: key},
  512. success: function(data){
  513. if (callback != undefined){
  514. callback(data);
  515. }
  516. }
  517. });
  518. }
  519. function writePreference(key, value, callback=undefined){
  520. $.ajax({
  521. url: "../../system/file_system/preference",
  522. data: {key: key, value: value},
  523. success: function(data){
  524. if (callback != undefined){
  525. callback(data);
  526. }
  527. }
  528. })
  529. }
  530. function hexToRgbA(hex, transparent=1){
  531. var c;
  532. if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
  533. c= hex.substring(1).split('');
  534. if(c.length== 3){
  535. c= [c[0], c[0], c[1], c[1], c[2], c[2]];
  536. }
  537. c= '0x'+c.join('');
  538. return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',' + transparent + ')';
  539. }
  540. throw new Error('Bad Hex');
  541. }
  542. function applyWallpaper(){
  543. var targetWallpaper =JSON.parse(decodeURIComponent($("#wallpaperlist").val()));
  544. $.get("../../system/desktop/theme?set=" + targetWallpaper.Theme, function(data) {
  545. if (ao_module_virtualDesktop == true){
  546. parent.changeDesktopTheme(targetWallpaper.Theme);
  547. }
  548. if (data.includes("Error")) {
  549. console.log(data);
  550. return;
  551. }
  552. //Reload the preview
  553. initCurrentBackgroundPreview();
  554. //Show change finsihed
  555. $("#wallpaperChangeConfirm").slideDown('fast').delay(3000).slideUp('fast');
  556. });
  557. }
  558. </script>
  559. </body>
  560. </html>