personalization.html 26 KB

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