From 172aa01e1cc07ff2e457fec80be130e70a7f8f30 Mon Sep 17 00:00:00 2001 From: jelveh Date: Fri, 17 Jul 2026 14:23:52 -0700 Subject: [PATCH] Trim file context menu actions --- .../src/helpers/generate_file_context_menu.js | 229 ------------------ 1 file changed, 229 deletions(-) diff --git a/src/gui/src/helpers/generate_file_context_menu.js b/src/gui/src/helpers/generate_file_context_menu.js index f3cebd80e..b5ea19f8a 100644 --- a/src/gui/src/helpers/generate_file_context_menu.js +++ b/src/gui/src/helpers/generate_file_context_menu.js @@ -27,102 +27,8 @@ import UIWindowPublishWorker from '../UI/UIWindowPublishWorker.js'; import open_item from './open_item.js'; import launch_app from './launch_app.js'; import path from '../lib/path.js'; -import mime from '../lib/mime.js'; import { isWeblinkName, weblinkChangeIconMenuItem } from './weblink.js'; -const AI_APP_NAME = 'ai'; - -/** - * Parses item metadata for AI payload - * @param {string} metadata - JSON string of metadata - * @returns {Object|undefined} Parsed metadata or undefined - */ -const parseItemMetadataForAI = (metadata) => { - if ( ! metadata ) { - return undefined; - } - try { - return JSON.parse(metadata); - } catch ( error ) { - console.warn('Failed to parse item metadata for AI payload.', error); - return undefined; - } -}; - -/** - * Builds AI payload from item elements - * @param {jQuery} $elements - jQuery collection of elements - * @returns {Array} Array of item data for AI - */ -const buildAIPayloadFromItems = ($elements) => { - return $elements.get().map((element) => { - const $element = $(element); - return { - uid: $element.attr('data-uid'), - path: $element.attr('data-path'), - name: $element.attr('data-name'), - is_dir: $element.attr('data-is_dir') === '1', - is_shortcut: $element.attr('data-is_shortcut') === '1', - shortcut_to: $element.attr('data-shortcut_to') || undefined, - shortcut_to_path: $element.attr('data-shortcut_to_path') || undefined, - size: $element.attr('data-size') || undefined, - type: $element.attr('data-type') || undefined, - modified: $element.attr('data-modified') || undefined, - metadata: parseItemMetadataForAI($element.attr('data-metadata')), - }; - }); -}; - -/** - * Ensures AI app iframe is available - * @returns {Promise} AI app iframe or null - */ -const ensureAIAppIframe = async () => { - let $aiWindow = $(`.window[data-app="${AI_APP_NAME}"]`); - if ( $aiWindow.length === 0 ) { - try { - await launch_app({ name: AI_APP_NAME }); - } catch ( error ) { - console.error('Failed to launch AI app.', error); - return null; - } - $aiWindow = $(`.window[data-app="${AI_APP_NAME}"]`); - } - - if ( $aiWindow.length === 0 ) { - return null; - } - - $aiWindow.makeWindowVisible(); - const iframe = $aiWindow.find('.window-app-iframe').get(0); - return iframe ?? null; -}; - -/** - * Sends selection to AI app - * @param {jQuery} $elements - jQuery collection of elements - */ -const sendSelectionToAIApp = async ($elements) => { - const items = buildAIPayloadFromItems($elements); - if ( items.length === 0 ) { - return; - } - - const aiIframe = await ensureAIAppIframe(); - if ( !aiIframe || !aiIframe.contentWindow ) { - await UIAlert({ - message: i18n('ai_app_unavailable'), - }); - return; - } - - aiIframe.contentWindow.postMessage({ - msg: 'ai:openFsEntries', - items, - source: 'desktop-context-menu', - }, '*'); -}; - /** * Generates context menu items for file/folder operations * @@ -187,40 +93,6 @@ const generate_file_context_menu = async function (options) { menu_items.push('-'); } - // ------------------------------------------- - // Open in New Window - // (only if the item is on a window) - // ------------------------------------------- - if ( $(el_item).closest('.window-body').length > 0 && fsentry.is_dir ) { - menu_items.push({ - html: i18n('open_in_new_window'), - onClick: function () { - if ( fsentry.is_dir ) { - open_item({ item: el_item, new_window: true }); - } - }, - }); - - // ------------------------------------------- - // Separator - // ------------------------------------------- - if ( !is_trash && !is_trashed && fsentry.is_dir ) { - menu_items.push('-'); - } - } - - // ------------------------------------------- - // Open in AI - // ------------------------------------------- - if ( !is_trashed && !is_trash ) { - menu_items.push({ - html: i18n('open_in_ai'), - onClick: async function () { - await sendSelectionToAIApp($(el_item)); - }, - }); - } - // ------------------------------------------- // Publish As Website // ------------------------------------------- @@ -330,107 +202,6 @@ const generate_file_context_menu = async function (options) { }); } - // ------------------------------------------- - // Set as Wallpaper - // ------------------------------------------- - const mime_type = mime.getType($(el_item).attr('data-name')) ?? 'application/octet-stream'; - if ( !is_trashed && !is_trash && !fsentry.is_dir && mime_type.startsWith('image/') ) { - menu_items.push({ - html: i18n('set_as_background'), - onClick: async function () { - const read_url = await puter.fs.sign(undefined, { uid: $(el_item).attr('data-uid'), action: 'read' }); - window.set_desktop_background({ - url: read_url.items.read_url, - fit: window.desktop_bg_fit, - }); - // Update dashboard desktop view background if visible - const $desktopView = $('.files.desktop-view'); - if ( $desktopView.length ) { - $desktopView.css({ - 'background-image': `url(${read_url.items.read_url})`, - 'background-size': (window.desktop_bg_fit === 'repeat') ? 'auto' : (window.desktop_bg_fit || 'cover'), - 'background-repeat': (window.desktop_bg_fit === 'repeat') ? 'repeat' : 'no-repeat', - 'background-position': 'center center', - 'background-color': '', - }); - } - try { - $.ajax({ - url: `${window.api_origin}/set-desktop-bg`, - type: 'POST', - data: JSON.stringify({ - url: window.desktop_bg_url, - color: window.desktop_bg_color, - fit: window.desktop_bg_fit, - }), - async: true, - contentType: 'application/json', - headers: { - 'Authorization': `Bearer ${window.auth_token}`, - }, - statusCode: { - 401: function (xhr) { - window.handle401(xhr); - }, - }, - }); - } catch ( err ) { - // Ignore - } - }, - }); - } - - // ------------------------------------------- - // Zip - // ------------------------------------------- - if ( !is_trash && !is_trashed && !$(el_item).attr('data-path').endsWith('.zip') ) { - menu_items.push({ - html: i18n('zip'), - onClick: function () { - window.zipItems(el_item, path.dirname($(el_item).attr('data-path')), false); - }, - }); - } - - // ------------------------------------------- - // Unzip - // ------------------------------------------- - if ( !is_trash && !is_trashed && $(el_item).attr('data-path').endsWith('.zip') ) { - menu_items.push({ - html: i18n('unzip'), - onClick: async function () { - let filePath = $(el_item).attr('data-path'); - window.unzipItem(filePath); - }, - }); - } - - // ------------------------------------------- - // Tar - // ------------------------------------------- - if ( !is_trash && !is_trashed && !$(el_item).attr('data-path').endsWith('.tar') ) { - menu_items.push({ - html: i18n('tar'), - onClick: function () { - window.tarItems(el_item, path.dirname($(el_item).attr('data-path')), false); - }, - }); - } - - // ------------------------------------------- - // Untar - // ------------------------------------------- - if ( !is_trash && !is_trashed && $(el_item).attr('data-path').endsWith('.tar') ) { - menu_items.push({ - html: i18n('untar'), - onClick: async function () { - let filePath = $(el_item).attr('data-path'); - window.untarItem(filePath); - }, - }); - } - // ------------------------------------------- // Restore // -------------------------------------------