Fix installed and bundled plugin tabs

This commit is contained in:
Gregory Schier
2026-01-01 16:55:30 -08:00
parent ef187373c5
commit f1783feafc
3 changed files with 23 additions and 10 deletions

View File

@@ -18,6 +18,7 @@ use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use std::{fs, panic}; use std::{fs, panic};
use tauri::path::BaseDirectory;
use tauri::{AppHandle, Emitter, RunEvent, State, WebviewWindow, is_dev}; use tauri::{AppHandle, Emitter, RunEvent, State, WebviewWindow, is_dev};
use tauri::{Listener, Runtime}; use tauri::{Listener, Runtime};
use tauri::{Manager, WindowEvent}; use tauri::{Manager, WindowEvent};
@@ -82,6 +83,7 @@ struct AppMetaData {
name: String, name: String,
app_data_dir: String, app_data_dir: String,
app_log_dir: String, app_log_dir: String,
vendored_plugin_dir: String,
feature_updater: bool, feature_updater: bool,
feature_license: bool, feature_license: bool,
} }
@@ -90,12 +92,15 @@ struct AppMetaData {
async fn cmd_metadata(app_handle: AppHandle) -> YaakResult<AppMetaData> { async fn cmd_metadata(app_handle: AppHandle) -> YaakResult<AppMetaData> {
let app_data_dir = app_handle.path().app_data_dir()?; let app_data_dir = app_handle.path().app_data_dir()?;
let app_log_dir = app_handle.path().app_log_dir()?; let app_log_dir = app_handle.path().app_log_dir()?;
let vendored_plugin_dir =
app_handle.path().resolve("vendored/plugins", BaseDirectory::Resource)?;
Ok(AppMetaData { Ok(AppMetaData {
is_dev: is_dev(), is_dev: is_dev(),
version: app_handle.package_info().version.to_string(), version: app_handle.package_info().version.to_string(),
name: app_handle.package_info().name.to_string(), name: app_handle.package_info().name.to_string(),
app_data_dir: app_data_dir.to_string_lossy().to_string(), app_data_dir: app_data_dir.to_string_lossy().to_string(),
app_log_dir: app_log_dir.to_string_lossy().to_string(), app_log_dir: app_log_dir.to_string_lossy().to_string(),
vendored_plugin_dir: vendored_plugin_dir.to_string_lossy().to_string(),
feature_license: cfg!(feature = "license"), feature_license: cfg!(feature = "license"),
feature_updater: cfg!(feature = "updater"), feature_updater: cfg!(feature = "updater"),
}) })

View File

@@ -15,6 +15,7 @@ import { useDebouncedValue } from '../../hooks/useDebouncedValue';
import { useInstallPlugin } from '../../hooks/useInstallPlugin'; import { useInstallPlugin } from '../../hooks/useInstallPlugin';
import { usePluginInfo } from '../../hooks/usePluginInfo'; import { usePluginInfo } from '../../hooks/usePluginInfo';
import { usePluginsKey, useRefreshPlugins } from '../../hooks/usePlugins'; import { usePluginsKey, useRefreshPlugins } from '../../hooks/usePlugins';
import { appInfo } from '../../lib/appInfo';
import { showConfirmDelete } from '../../lib/confirm'; import { showConfirmDelete } from '../../lib/confirm';
import { minPromiseMillis } from '../../lib/minPromiseMillis'; import { minPromiseMillis } from '../../lib/minPromiseMillis';
import { Button } from '../core/Button'; import { Button } from '../core/Button';
@@ -32,11 +33,21 @@ import { TabContent, Tabs } from '../core/Tabs/Tabs';
import { EmptyStateText } from '../EmptyStateText'; import { EmptyStateText } from '../EmptyStateText';
import { SelectFile } from '../SelectFile'; import { SelectFile } from '../SelectFile';
function isPluginBundled(plugin: Plugin, vendoredPluginDir: string): boolean {
const normalizedDir = plugin.directory.replace(/\\/g, '/');
const normalizedVendoredDir = vendoredPluginDir.replace(/\\/g, '/');
return (
normalizedDir.includes(normalizedVendoredDir) ||
normalizedDir.includes('vendored/plugins') ||
normalizedDir.includes('/plugins/')
);
}
export function SettingsPlugins() { export function SettingsPlugins() {
const [directory, setDirectory] = useState<string | null>(null); const [directory, setDirectory] = useState<string | null>(null);
const plugins = useAtomValue(pluginsAtom); const plugins = useAtomValue(pluginsAtom);
const bundledPlugins = plugins.filter((p) => p.url == null); const bundledPlugins = plugins.filter((p) => isPluginBundled(p, appInfo.vendoredPluginDir));
const installedPlugins = plugins.filter((p) => p.url != null); const installedPlugins = plugins.filter((p) => !isPluginBundled(p, appInfo.vendoredPluginDir));
const createPlugin = useInstallPlugin(); const createPlugin = useInstallPlugin();
const refreshPlugins = useRefreshPlugins(); const refreshPlugins = useRefreshPlugins();
const [tab, setTab] = useState<string>(); const [tab, setTab] = useState<string>();
@@ -66,7 +77,7 @@ export function SettingsPlugins() {
</TabContent> </TabContent>
<TabContent value="installed" className="pb-0"> <TabContent value="installed" className="pb-0">
<div className="h-full grid grid-rows-[minmax(0,1fr)_auto]"> <div className="h-full grid grid-rows-[minmax(0,1fr)_auto]">
<InstalledPlugins /> <InstalledPlugins plugins={installedPlugins} />
<footer className="grid grid-cols-[minmax(0,1fr)_auto] -mx-4 py-2 px-4 border-t bg-surface-highlight border-border-subtle min-w-0"> <footer className="grid grid-cols-[minmax(0,1fr)_auto] -mx-4 py-2 px-4 border-t bg-surface-highlight border-border-subtle min-w-0">
<SelectFile <SelectFile
size="xs" size="xs"
@@ -110,7 +121,7 @@ export function SettingsPlugins() {
</div> </div>
</TabContent> </TabContent>
<TabContent value="bundled" className="pb-0"> <TabContent value="bundled" className="pb-0">
<BundledPlugins /> <BundledPlugins plugins={bundledPlugins} />
</TabContent> </TabContent>
</Tabs> </Tabs>
</div> </div>
@@ -328,9 +339,7 @@ function PluginSearch() {
); );
} }
function InstalledPlugins() { function InstalledPlugins({ plugins }: { plugins: Plugin[] }) {
const plugins = useAtomValue(pluginsAtom).filter((p) => p.url != null);
return plugins.length === 0 ? ( return plugins.length === 0 ? (
<div className="pb-4"> <div className="pb-4">
<EmptyStateText className="text-center"> <EmptyStateText className="text-center">
@@ -359,9 +368,7 @@ function InstalledPlugins() {
); );
} }
function BundledPlugins() { function BundledPlugins({ plugins }: { plugins: Plugin[] }) {
const plugins = useAtomValue(pluginsAtom).filter((p) => p.url == null);
return plugins.length === 0 ? ( return plugins.length === 0 ? (
<div className="pb-4"> <div className="pb-4">
<EmptyStateText className="text-center">No bundled plugins found.</EmptyStateText> <EmptyStateText className="text-center">No bundled plugins found.</EmptyStateText>

View File

@@ -7,6 +7,7 @@ export interface AppInfo {
name: string; name: string;
appDataDir: string; appDataDir: string;
appLogDir: string; appLogDir: string;
vendoredPluginDir: string;
identifier: string; identifier: string;
featureLicense: boolean; featureLicense: boolean;
featureUpdater: boolean; featureUpdater: boolean;