fix: persist settings (API key) via main-thread RPC — clientStorage is unavailable in UI iframe, so direct save/load silently failed; bump 0.1.19
This commit is contained in:
1 parent
2fe3132e03
commit
79e9ec1128
4 files changed
+50
-23
No files matched your search
+12
@@ -572,6 +572,18 @@ export default function () {
|
||||
}
|
||||
})
|
||||
|
||||
// Settings persistence RPC: clientStorage is only available here (main thread), not in the UI iframe.
|
||||
on('LOAD_SETTINGS', async function (payload: { key: string }) {
|
||||
let stored: any = null
|
||||
try { stored = await figma.clientStorage.getAsync(payload.key) } catch (e) { stored = null }
|
||||
emit('SETTINGS_LOADED', { settings: stored })
|
||||
})
|
||||
|
||||
on('SAVE_SETTINGS', async function (payload: { key: string, settings: any }) {
|
||||
try { await figma.clientStorage.setAsync(payload.key, payload.settings) } catch (e) { /* ignore */ }
|
||||
emit('SAVE_SETTINGS_DONE', {})
|
||||
})
|
||||
|
||||
showUI({ width: 380, height: 480, themeColors: true, title: 'AI assistant (MVP)' })
|
||||
|
||||
// On open, proactively probe connectivity so the user sees network status without clicking Fetch.
|
||||
|
||||
+34
-20
@@ -1,8 +1,11 @@
|
||||
// Local settings model + persistence (figma.clientStorage).
|
||||
//
|
||||
// No server auth yet — everything lives on the Figma file locally. Backup/restore
|
||||
// is just a JSON export/import of this same document. (Server auth comes later.)
|
||||
// IMPORTANT: figma.clientStorage is ONLY available in the plugin MAIN thread (main.ts),
|
||||
// NOT in the UI iframe. So load/save must round-trip through main via emit/on.
|
||||
// These helpers only build/parse the data; the actual storage calls live in main.ts
|
||||
// (SAVE_SETTINGS / LOAD_SETTINGS RPC). Backup/restore is a JSON export/import of this same model.
|
||||
|
||||
import { emit, on } from '@create-figma-plugin/utilities'
|
||||
import { APINEX_MODELS } from './apinex-models'
|
||||
|
||||
export type ProviderType = 'apinex'
|
||||
@@ -53,26 +56,37 @@ export function createApinexProvider (): ProviderConfig {
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadSettings (): Promise<Settings> {
|
||||
const defaults = defaultSettings()
|
||||
try {
|
||||
const stored = await figma.clientStorage.getAsync(SETTINGS_KEY)
|
||||
if (stored == null || stored.version !== 1) return defaults
|
||||
const merged: Settings = { ...defaults, ...(stored as Settings) }
|
||||
if (!Array.isArray(merged.providers) || merged.providers.length === 0) {
|
||||
merged.providers = defaults.providers
|
||||
merged.activeProviderId = defaults.providers[0].id
|
||||
}
|
||||
return merged
|
||||
} catch (e) {
|
||||
return defaults
|
||||
}
|
||||
// Request main thread to load persisted settings; resolves with merged Settings.
|
||||
export function loadSettings (): Promise<Settings> {
|
||||
return new Promise(function (resolve) {
|
||||
const dispose = on('SETTINGS_LOADED', function (payload: { settings: Settings | null }) {
|
||||
dispose()
|
||||
const stored = payload.settings
|
||||
if (stored == null || stored.version !== 1) {
|
||||
resolve(defaultSettings())
|
||||
return
|
||||
}
|
||||
const defaults = defaultSettings()
|
||||
const merged: Settings = { ...defaults, ...stored }
|
||||
if (!Array.isArray(merged.providers) || merged.providers.length === 0) {
|
||||
merged.providers = defaults.providers
|
||||
merged.activeProviderId = defaults.providers[0].id
|
||||
}
|
||||
resolve(merged)
|
||||
})
|
||||
emit('LOAD_SETTINGS', { key: SETTINGS_KEY })
|
||||
})
|
||||
}
|
||||
|
||||
export async function saveSettings (settings: Settings): Promise<void> {
|
||||
try {
|
||||
await figma.clientStorage.setAsync(SETTINGS_KEY, settings)
|
||||
} catch (e) { /* storage unavailable — ignore */ }
|
||||
// Request main thread to persist settings.
|
||||
export function saveSettings (settings: Settings): Promise<void> {
|
||||
return new Promise(function (resolve) {
|
||||
const dispose = on('SAVE_SETTINGS_DONE', function () {
|
||||
dispose()
|
||||
resolve()
|
||||
})
|
||||
emit('SAVE_SETTINGS', { key: SETTINGS_KEY, settings: settings })
|
||||
})
|
||||
}
|
||||
|
||||
export function settingsToJSON (settings: Settings): string {
|
||||
|
||||
+3
-2
@@ -30,7 +30,7 @@ const MIN_WINDOW_SIZE = { width: 320, height: 200 }
|
||||
// very high — actual clamp is done by main via clampWindowSize (bounds*zoom).
|
||||
|
||||
// Full plugin version shown in the footer status bar. Keep in sync with package.json "version".
|
||||
const PLUGIN_VERSION = '0.1.18'
|
||||
const PLUGIN_VERSION = '0.1.19'
|
||||
|
||||
const fieldStyle = {
|
||||
display: 'flex',
|
||||
@@ -164,6 +164,7 @@ function SettingsPanel (props: { settings: Settings, setSettings: (s: Settings)
|
||||
function save () {
|
||||
saveSettings(settings).then(function () {
|
||||
setSavedNote(true)
|
||||
logEvent('Settings saved (manual)')
|
||||
setTimeout(function () { setSavedNote(false) }, 1500)
|
||||
})
|
||||
}
|
||||
@@ -286,7 +287,7 @@ function Plugin () {
|
||||
// Gated on `loaded` so we don't overwrite stored settings with defaults before load completes.
|
||||
useEffect(function () {
|
||||
if (!loaded) return
|
||||
const t = setTimeout(function () { saveSettings(settings) }, 400)
|
||||
const t = setTimeout(function () { saveSettings(settings).then(function () { logEvent('Settings saved') }) }, 400)
|
||||
return function () { clearTimeout(t) }
|
||||
}, [settings, loaded])
|
||||
useEffect(function () { try { logEvent('Plugin loaded') } catch (e) {} }, [])
|
||||
|
||||
Reference in new issue
Block a user