feat(ui): Bilder aus der Zwischenablage ins interaktive Terminal einfuegen
Ctrl+V mit einem Bild in der Zwischenablage schreibt es als temporaeres PNG unter ~/.claudeDo/tmp/ und fuegt den Pfad in den Composer ein, genau wie ein Datei-Drop -- Claude liest die Datei selbst. Text-Paste laeuft unveraendert ueber den bestehenden bracketed-paste-Pfad. Avalonia 12.0.4 liest Clipboard-Bitmaps bereits selbst (IClipboard. TryGetDataAsync + AsyncDataTransferExtensions.TryGetBitmapAsync), kein Win32-P/Invoke noetig. Alte Tmp-Dateien (>24h) werden beim App-Start aufgeraeumt (ClaudeDo.App/Program.cs), keine eigene Aufraeum-Infrastruktur.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using ClaudeDo.Data;
|
||||
|
||||
namespace ClaudeDo.Ui.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Temp PNGs written for clipboard-image paste into the interactive terminal (see
|
||||
/// <see cref="ClaudeDo.Ui.Views.InteractiveTerminalView"/>) — dropped into the composer as a path,
|
||||
/// the same way a file drop is, then read by Claude like any other file.
|
||||
/// </summary>
|
||||
public static class ClipboardImageTempStore
|
||||
{
|
||||
public static string Directory => Path.Combine(Paths.AppDataRoot(), "tmp");
|
||||
|
||||
/// <summary>A fresh, collision-free path for one pasted image.</summary>
|
||||
public static string NewPngPath(DateTime utcNow) => NewPngPath(Directory, utcNow);
|
||||
|
||||
/// <summary>Deletes files older than <paramref name="maxAge"/> under the tmp dir — called once at
|
||||
/// app startup, not a running cleanup service.</summary>
|
||||
public static void DeleteOlderThan(TimeSpan maxAge, DateTime utcNow) => DeleteOlderThan(Directory, maxAge, utcNow);
|
||||
|
||||
/// <summary>Test seam for <see cref="NewPngPath(DateTime)"/> — takes the target dir explicitly
|
||||
/// instead of the real app data root.</summary>
|
||||
internal static string NewPngPath(string dir, DateTime utcNow) =>
|
||||
Path.Combine(dir, $"paste-{utcNow:yyyyMMdd-HHmmssfff}-{Guid.NewGuid():N}.png");
|
||||
|
||||
/// <summary>Test seam for <see cref="DeleteOlderThan(TimeSpan,DateTime)"/> — takes the target dir
|
||||
/// explicitly instead of the real app data root.</summary>
|
||||
internal static void DeleteOlderThan(string dir, TimeSpan maxAge, DateTime utcNow)
|
||||
{
|
||||
if (!System.IO.Directory.Exists(dir)) return;
|
||||
|
||||
foreach (var file in System.IO.Directory.EnumerateFiles(dir))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (utcNow - File.GetLastWriteTimeUtc(file) > maxAge)
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (IOException) { /* best effort */ }
|
||||
catch (UnauthorizedAccessException) { /* best effort */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user