Improve Save for browsers without File System Access API
- Save As prompts for filename via prompt() before downloading - Save reuses the filename from last Save As (no repeated prompts) - Banner in Safari/Firefox explaining the limitation with Chrome link - Banner is dismissible
This commit is contained in:
parent
c886daded2
commit
c8af1c35e7
1
components.d.ts
vendored
1
components.d.ts
vendored
|
|
@ -84,6 +84,7 @@ declare module 'vue' {
|
|||
PagesPanel: typeof import('./src/components/PagesPanel.vue')['default']
|
||||
PositionSection: typeof import('./src/components/properties/PositionSection.vue')['default']
|
||||
PropertiesPanel: typeof import('./src/components/PropertiesPanel.vue')['default']
|
||||
SafariBanner: typeof import('./src/components/SafariBanner.vue')['default']
|
||||
ScrubInput: typeof import('./src/components/ScrubInput.vue')['default']
|
||||
StrokeSection: typeof import('./src/components/properties/StrokeSection.vue')['default']
|
||||
Toolbar: typeof import('./src/components/Toolbar.vue')['default']
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { provideEditorStore } from './stores/editor'
|
|||
import EditorCanvas from './components/EditorCanvas.vue'
|
||||
import LayersPanel from './components/LayersPanel.vue'
|
||||
import PropertiesPanel from './components/PropertiesPanel.vue'
|
||||
import SafariBanner from './components/SafariBanner.vue'
|
||||
import Toolbar from './components/Toolbar.vue'
|
||||
|
||||
const store = provideEditorStore()
|
||||
|
|
@ -35,6 +36,7 @@ if (!('test' in params)) {
|
|||
|
||||
<template>
|
||||
<div class="flex h-screen w-screen flex-col">
|
||||
<SafariBanner />
|
||||
<SplitterGroup
|
||||
v-if="showChrome"
|
||||
direction="horizontal"
|
||||
|
|
|
|||
25
src/components/SafariBanner.vue
Normal file
25
src/components/SafariBanner.vue
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { IS_TAURI } from '@/constants'
|
||||
|
||||
const dismissed = ref(false)
|
||||
const show = !IS_TAURI && typeof window !== 'undefined' && !window.showSaveFilePicker
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="show && !dismissed"
|
||||
class="flex items-center gap-2 border-b border-amber-500/30 bg-amber-500/10 px-3 py-1.5 text-xs text-amber-200"
|
||||
>
|
||||
<span class="flex-1">
|
||||
Your browser doesn't support the local file API. Files will be downloaded instead of saved in place.
|
||||
<a href="https://www.google.com/chrome/" target="_blank" class="underline">Use Chrome</a> or Edge for full support.
|
||||
</span>
|
||||
<button
|
||||
class="shrink-0 rounded px-1.5 py-0.5 text-amber-300 transition-colors hover:bg-amber-500/20"
|
||||
@click="dismissed = true"
|
||||
>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -117,6 +117,7 @@ export function createEditorStore() {
|
|||
const pageViewports = new Map<string, PageViewport>()
|
||||
let fileHandle: FileSystemFileHandle | null = null
|
||||
let filePath: string | null = null
|
||||
let downloadName: string | null = null
|
||||
let savedVersion = 0
|
||||
let autosaveTimer: ReturnType<typeof setTimeout> | undefined
|
||||
let _ck: import('canvaskit-wasm').CanvasKit | null = null
|
||||
|
|
@ -586,6 +587,8 @@ export function createEditorStore() {
|
|||
async function saveFigFile() {
|
||||
if (filePath || fileHandle) {
|
||||
await writeFile(await buildFigFile())
|
||||
} else if (downloadName) {
|
||||
downloadBlob(new Uint8Array(await buildFigFile()), downloadName, 'application/octet-stream')
|
||||
} else {
|
||||
await saveFigFileAs()
|
||||
}
|
||||
|
|
@ -627,7 +630,10 @@ export function createEditorStore() {
|
|||
}
|
||||
}
|
||||
|
||||
downloadBlob(new Uint8Array(data), 'Untitled.fig', 'application/octet-stream')
|
||||
const filename = prompt('Save as:', downloadName ?? 'Untitled.fig')
|
||||
if (!filename) return
|
||||
downloadName = filename
|
||||
downloadBlob(new Uint8Array(data), filename, 'application/octet-stream')
|
||||
}
|
||||
|
||||
async function writeFile(data: Uint8Array) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue