Bläddra i källkod

Enable background and builtin apps

KernelDeimos 1 år sedan
förälder
incheckning
5fbbfb4c18

+ 1 - 0
packages/backend/src/om/mappings/app.js

@@ -51,6 +51,7 @@ module.exports = {
             maxlen: 7000,
         },
         maximize_on_start: 'flag',
+        background: 'flag',
         subdomain: {
             type: 'string',
             transient: true,

+ 2 - 0
packages/backend/src/routers/apps.js

@@ -72,6 +72,7 @@ router.get('/apps', auth, express.json({limit: '50mb'}), async (req, res, next)=
                 icon: apps_res[i].icon,
                 index_url: apps_res[i].index_url,
                 godmode: apps_res[i].godmode,
+                background: apps_res[i].background,
                 maximize_on_start: apps_res[i].maximize_on_start,
                 filetype_associations: filetype_associations,
                 ...stats,
@@ -111,6 +112,7 @@ router.get('/apps/:name', auth, express.json({limit: '50mb'}), async (req, res,
                     title: app.title,
                     icon: app.icon,
                     godmode: app.godmode,
+                    background: app.background,
                     maximize_on_start: app.maximize_on_start,
                     index_url: app.index_url,
                 };

+ 6 - 1
packages/backend/src/services/database/SqliteDatabaseAccessService.js

@@ -42,7 +42,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
         this.db = new Database(this.config.path);
 
         // Database upgrade logic
-        const TARGET_VERSION = 2;
+        const TARGET_VERSION = 3;
 
         if ( do_setup ) {
             this.log.noticeme(`SETUP: creating database at ${this.config.path}`);
@@ -51,6 +51,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
                 '0002_add-default-apps.sql',
                 '0003_user-permissions.sql',
                 '0004_sessions.sql',
+                '0005_background-apps.sql',
             ].map(p => path_.join(__dirname, 'sqlite_setup', p));
             const fs = require('fs');
             for ( const filename of sql_files ) {
@@ -75,6 +76,10 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
             upgrade_files.push('0004_sessions.sql');
         }
 
+        if ( user_version <= 2 ) {
+            upgrade_files.push('0005_background-apps.sql');
+        }
+
         if ( upgrade_files.length > 0 ) {
             this.log.noticeme(`Database out of date: ${this.config.path}`);
             this.log.noticeme(`UPGRADING DATABASE: ${user_version} -> ${TARGET_VERSION}`);

+ 1 - 0
packages/backend/src/services/database/sqlite_setup/0005_background-apps.sql

@@ -0,0 +1 @@
+ALTER TABLE apps ADD COLUMN "background" BOOLEAN DEFAULT 0;

+ 30 - 21
src/UI/UIWindow.js

@@ -110,6 +110,8 @@ async function UIWindow(options) {
     options.window_css = options.window_css ?? {};
     options.window_class = (options.window_class !== undefined ? ' ' + options.window_class : '');
 
+    options.is_visible = options.is_visible ?? true;
+
     // if only one instance is allowed, bring focus to the window that is already open
     if(options.single_instance && options.app !== ''){
         let $already_open_window =  $(`.window[data-app="${html_encode(options.app)}"]`);
@@ -489,7 +491,9 @@ async function UIWindow(options) {
         $(el_window_head_icon).attr('src', window.icons['shared.svg']);
     }
     // focus on this window and deactivate other windows
-    $(el_window).focusWindow();
+    if ( options.is_visible ) {
+        $(el_window).focusWindow();
+    }
 
     if (animate_window_opening) {
         // animate window opening
@@ -517,25 +521,28 @@ async function UIWindow(options) {
 
     // onAppend() - using show() is a hack to make sure window is visible AND onAppend is called when
     // window is actually appended and usable.
-    $(el_window).show(0, function(e){
-        // if SaveFileDialog, bring focus to the el_savefiledialog_filename and select all
-        if(options.is_saveFileDialog){
-            let item_name = el_savefiledialog_filename.value;
-            const extname = path.extname('/' + item_name);
-            if(extname !== '')
-            el_savefiledialog_filename.setSelectionRange(0, item_name.length - extname.length)
-            else
-                $(el_savefiledialog_filename).select();
-    
-            $(el_savefiledialog_filename).get(0).focus({preventScroll:true});
-        }
-        //set custom window css
-        $(el_window).css(options.window_css);
-        // onAppend()
-        if(options.onAppend && typeof options.onAppend === 'function'){
-            options.onAppend(el_window);
-        }
-    })
+    // NOTE: there is another is_visible condition below
+    if ( options.is_visible ) {
+        $(el_window).show(0, function(e){
+            // if SaveFileDialog, bring focus to the el_savefiledialog_filename and select all
+            if(options.is_saveFileDialog){
+                let item_name = el_savefiledialog_filename.value;
+                const extname = path.extname('/' + item_name);
+                if(extname !== '')
+                el_savefiledialog_filename.setSelectionRange(0, item_name.length - extname.length)
+                else
+                    $(el_savefiledialog_filename).select();
+        
+                $(el_savefiledialog_filename).get(0).focus({preventScroll:true});
+            }
+            //set custom window css
+            $(el_window).css(options.window_css);
+            // onAppend()
+            if(options.onAppend && typeof options.onAppend === 'function'){
+                options.onAppend(el_window);
+            }
+        });
+    }
 
     if(options.is_saveFileDialog){
         //------------------------------------------------
@@ -960,7 +967,9 @@ async function UIWindow(options) {
         $(el_window).css('top', options.top)
         $(el_window).css('left', options.left)
     }
-    $(el_window).css('display', 'block');
+    if ( options.is_visible ) {
+        $(el_window).css('display', 'block');
+    }
 
     // mousedown on the window body will unselect selected items if neither ctrl nor command are pressed
     $(el_window_body).on('mousedown', function(e){

+ 16 - 2
src/helpers.js

@@ -1944,9 +1944,16 @@ window.launch_app = async (options)=>{
         // iframe_url
         //-----------------------------------
         let iframe_url;
+
+        // This can be any trusted URL that won't be used for other apps
+        const BUILTIN_PREFIX = 'https://builtins.namespaces.puter.com/';
+
         if(!app_info.index_url){
             iframe_url = new URL('https://'+options.name+'.' + window.app_domain + `/index.html`);
-        }else{
+        } else if ( app_info.index_url.startsWith(BUILTIN_PREFIX) ) {
+            const name = app_info.index_url.slice(BUILTIN_PREFIX.length);
+            iframe_url = new URL(`${gui_origin}/builtin/${name}`);
+        } else {
             iframe_url = new URL(app_info.index_url);
         }
 
@@ -2026,7 +2033,9 @@ window.launch_app = async (options)=>{
         // ...and finally append urm_source=puter.com to the URL
         iframe_url.searchParams.append('urm_source', 'puter.com');
 
-        UIWindow({
+        console.log('backgrounded??', app_info.background);
+
+        const el_win = UIWindow({
             element_uuid: uuid,
             title: title,
             iframe_url: iframe_url.href,
@@ -2039,11 +2048,16 @@ window.launch_app = async (options)=>{
             height: options.maximized ? `calc(100% - ${window.taskbar_height + window.toolbar_height + 1}px)` : undefined,
             width: options.maximized ? `100%` : undefined,
             app: options.name,
+            is_visible: ! app_info.background,
             is_maximized: options.maximized,
             is_fullpage: options.is_fullpage,
             ...window_options,
         }); 
 
+        if ( ! app_info.background ) {
+            $(el_win).show();
+        }
+
         // send post request to /rao to record app open
         if(options.name !== 'explorer'){
             // add the app to the beginning of the array