浏览代码

Merge pull request #64 from sunjc826/show_hidden_files

Implement 'Show Hidden Files' feature
Nariman Jelveh 1 年之前
父节点
当前提交
6d3637fb6c
共有 7 个文件被更改,包括 96 次插入7 次删除
  1. 2 1
      .gitignore
  2. 12 0
      src/UI/UIDesktop.js
  3. 2 1
      src/UI/UIItem.js
  4. 12 0
      src/UI/UIWindow.js
  5. 12 0
      src/css/style.css
  6. 13 0
      src/globals.js
  7. 43 5
      src/helpers.js

+ 2 - 1
.gitignore

@@ -4,4 +4,5 @@ node_modules/
 *.tgz
 license.config.json
 license-header.txt
-dist/
+dist/
+.vscode/

+ 12 - 0
src/UI/UIDesktop.js

@@ -683,6 +683,18 @@ async function UIDesktop(options){
                         }
                     },
                     // -------------------------------------------
+                    // Show/Hide hidden files
+                    // -------------------------------------------
+                    {
+                        html: `${window.user_preferences.show_hidden_files ? 'Hide' : 'Show'} hidden files`,
+                        onClick: function(){
+                            window.mutate_user_preferences({
+                                show_hidden_files : !window.user_preferences.show_hidden_files,
+                            });
+                            window.show_or_hide_files(document.querySelectorAll('.item-container'));
+                        }
+                    },
+                    // -------------------------------------------
                     // -
                     // -------------------------------------------
                     '-',

+ 2 - 1
src/UI/UIItem.js

@@ -46,6 +46,7 @@ function UIItem(options){
 
     // set options defaults
     options.disabled = options.disabled ?? false;
+    options.visible = options.visible ?? 'visible'; // one of 'visible', 'revealed', 'hidden'
     options.is_dir = options.is_dir ?? false;
     options.is_selected = options.is_selected ?? false;
     options.is_shared = options.is_shared ?? false;
@@ -71,7 +72,7 @@ function UIItem(options){
     // --------------------------------------------------------
     let h = '';
     h += `<div  id="item-${item_id}" 
-                class="item${options.is_selected ? ' item-selected':''} ${options.disabled ? 'item-disabled':''}" 
+                class="item${options.is_selected ? ' item-selected':''} ${options.disabled ? 'item-disabled':''} item-${options.visible}" 
                 data-id="${item_id}" 
                 data-name="${html_encode(options.name)}" 
                 data-metadata="${html_encode(options.metadata)}" 

+ 12 - 0
src/UI/UIWindow.js

@@ -1880,6 +1880,18 @@ async function UIWindow(options) {
                             }
                         },
                         // -------------------------------------------
+                        // Show/Hide hidden files
+                        // -------------------------------------------
+                        {
+                            html: `${window.user_preferences.show_hidden_files ? "Hide" : "Show"} hidden files`,
+                            onClick: function(){
+                                window.mutate_user_preferences({
+                                    show_hidden_files : !window.user_preferences.show_hidden_files,
+                                });
+                                window.show_or_hide_files(document.querySelectorAll('.item-container'));
+                            }
+                        },
+                        // -------------------------------------------
                         // -
                         // -------------------------------------------
                         '-',

+ 12 - 0
src/css/style.css

@@ -306,6 +306,18 @@ input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, sel
     pointer-events: none;
 }
 
+.item-revealed {
+    opacity: 0.9;
+}
+
+.item-hidden {
+    display: none
+}
+
+.item-revealed.item-disabled {
+    opacity: 0.7
+}
+
 .item-container-list .item {
     height: initial;
     width: max-content;

+ 13 - 0
src/globals.js

@@ -85,6 +85,19 @@ if(window.user !== undefined && window.user !== null){
 }
 window.root_dirname = 'Puter';
 
+// user preferences, persisted across sessions, cached in localStorage
+try {
+    window.user_preferences = JSON.parse(localStorage.getItem('user_preferences'))
+}catch(e){
+    window.user_preferences = null;
+}
+// default values
+if (window.user_preferences === null) {
+    window.user_preferences = {
+        show_hidden_files: false,
+    }
+}
+
 window.window_stack = []
 window.toolbar_height = 30;
 window.default_taskbar_height = 50;

+ 43 - 5
src/helpers.js

@@ -656,7 +656,13 @@ window.refresh_user_data = async (auth_token)=>{
     // update local user data
     if(whoami){
         update_auth_data(auth_token, whoami)
-    } 
+    }
+
+    // update local user preferences
+    const user_preferences = {
+        show_hidden_files: (await puter.kv.get('user_preferences.show_hidden_files')) === 'true',
+    };
+    update_user_preferences(user_preferences);
 }
 
 window.update_auth_data = (auth_token, user)=>{
@@ -710,6 +716,20 @@ window.update_auth_data = (auth_token, user)=>{
     }
 }
 
+window.mutate_user_preferences = function(user_preferences_delta) {
+    for (const [key, value] of Object.entries(user_preferences_delta)) {
+        // Don't wait for set to be done for better efficiency
+        puter.kv.set(`user_preferences.${key}`, String(value));
+    }
+    // There may be syncing issues across multiple devices
+    update_user_preferences({ ...window.user_preferences, ...user_preferences_delta });
+}
+
+window.update_user_preferences = function(user_preferences) {
+    window.user_preferences = user_preferences;
+    localStorage.setItem('user_preferences', JSON.stringify(user_preferences));
+}
+
 window.sendWindowWillCloseMsg = function(iframe_element) {
     return new Promise(function(resolve){
         const msg_id = uuidv4();
@@ -1255,11 +1275,18 @@ window.refresh_item_container = function(el_item_container, options){
                 if(!window.check_fsentry_against_allowed_file_types_string(fsentry, allowed_file_types))
                     is_disabled = true;
 
-                // skip if hidden (i.e. name starts with `.`)
-                if(fsentry.name.startsWith('.'))
-                    continue;
+                // set visibility based on user preferences and whether file is hidden by default
+                const is_hidden_file = fsentry.name.startsWith('.');
+                let visible;
+                if (!is_hidden_file){
+                    visible = 'visible';
+                }else if (window.user_preferences.show_hidden_files) {
+                    visible = 'revealed';
+                }else{
+                    visible = 'hidden';
+                }
 
-                //metadata
+                // metadata
                 let metadata;
                 if(fsentry.metadata !== ''){
                     try{
@@ -1295,6 +1322,7 @@ window.refresh_item_container = function(el_item_container, options){
                         modified: fsentry.modified,
                         suggested_apps: fsentry.suggested_apps,
                         disabled: is_disabled,
+                        visible: visible,
                     });
                 }
             }
@@ -1380,6 +1408,16 @@ window.sort_items = (item_container, sort_by, sort_order)=>{
     }).appendTo(item_container);
 }
 
+window.show_or_hide_files = (item_containers) => {
+    const show_hidden_files = window.user_preferences.show_hidden_files;
+    const class_to_add = show_hidden_files ? 'item-revealed' : 'item-hidden';
+    const class_to_remove = show_hidden_files ? 'item-hidden' : 'item-revealed';
+    $(item_containers)
+        .find('.item')
+        .filter((_, item) => item.dataset.name.startsWith('.'))
+        .removeClass(class_to_remove).addClass(class_to_add);
+}
+
 window.create_folder = async(basedir, appendto_element)=>{
 	let dirname = basedir;
     let folder_name = 'New Folder';