feat(notes): billeder og bilag følger med ind — og ud
Release / Build and publish image (push) Failing after 9m58s
Release / Build and publish image (push) Failing after 9m58s
Du spurgte, hvad der sker med bilag og indsatte billeder. Svaret var: de forsvandt stille. Scriptet konverterede til ren tekst, og en note fra Apple Noter, der kommer over som ord alene, er ikke den note — den er et referat af den. En note kan nu bære filer, i samme tabel som opgaver og grupper allerede bruger. Filerne er indholdsadresserede og deduplikeres på disken, upload-vejen er skrevet og afprøvet, og oprydningen af forældreløse filer går allerede den tabel igennem. En tabel mere ville være et alt-sammen mere. Importen læser arkivet i to omgange. Alt, der ikke er Markdown, gemmes først, så en note, der bliver læst, allerede har adresser at få sine links rettet til — noter og billeder ligger i den rækkefølge, arkivet nu har dem, og ét gennemløb ville efterlade halvdelen af henvisningerne pegende på ingenting. Kun de filer, noten faktisk nævner. Et arkiv er én mappe til mange noter, og at hænge hvert billede på hver note ville gøre hundrede noter til ti tusind bilag. Hentningen af en note-fil gav 404, fordi adgangskontrollen ikke kendte noter som forælder. Et billede midt i den tekst, der navngav det, svarede altså "findes ikke". Den følger nu noten, som følger sit projekt — samme kæde som alt andet. AppleScriptet gemmer nu hver vedhæftning og skriver en henvisning til den i noten. Vedhæftninger uden fil bag sig — links til websider, kort — springes over frem for at vælte kørslen. Migration 0021. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
11fdbefe1b
commit
414a35eaba
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
|
||||
/** Import, export and project templates. */
|
||||
import { api, humanMessage } from '$lib/api.js';
|
||||
import { app } from '$lib/stores.svelte.js';
|
||||
@@ -57,6 +58,34 @@
|
||||
// --- Todoist import ------------------------------------------------------------
|
||||
|
||||
let importing = $state(false);
|
||||
let importingNotes = $state(false);
|
||||
|
||||
/**
|
||||
* A zip of Markdown files becomes notes.
|
||||
*
|
||||
* The whole archive in one request rather than a file at a time: the pictures
|
||||
* have to be in the same request as the notes that name them, or the links
|
||||
* cannot be rewritten.
|
||||
*/
|
||||
async function importNotes(event) {
|
||||
const file = event.currentTarget.files?.[0];
|
||||
if (!file) return;
|
||||
importingNotes = true;
|
||||
try {
|
||||
const result = await api.importNotes(file);
|
||||
app.toast(
|
||||
t('data.notesImported', {
|
||||
n: result.created ?? 0,
|
||||
files: result.files ?? 0
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
app.toast(humanMessage(e));
|
||||
} finally {
|
||||
importingNotes = false;
|
||||
event.target.value = '';
|
||||
}
|
||||
}
|
||||
let result = $state(null);
|
||||
|
||||
async function importTodoist(event) {
|
||||
@@ -344,6 +373,21 @@
|
||||
<a class="link" href={api.exportNotesURL()} download>{t('data.exportNotes')}</a>
|
||||
</div>
|
||||
|
||||
<!-- The way back in, and from anywhere else: a folder of Markdown is what
|
||||
Obsidian, Bear and iA Writer all produce, and what the Apple Notes script in
|
||||
tools/ writes. Pictures beside the files come with them. -->
|
||||
<div class="field">
|
||||
<label for="import-notes">{t('data.importNotes')}</label>
|
||||
<input
|
||||
id="import-notes"
|
||||
type="file"
|
||||
accept=".zip,application/zip"
|
||||
onchange={importNotes}
|
||||
disabled={importingNotes}
|
||||
/>
|
||||
<p class="hint">{t('data.importNotesHint')}</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="export-project">{t('data.exportOne')}</label>
|
||||
<select id="export-project" bind:value={exportProject}>
|
||||
|
||||
Reference in New Issue
Block a user