108 lines
5.0 KiB
Markdown
108 lines
5.0 KiB
Markdown
# Q-Edit v0.7.0 — Release Notes
|
||
|
||
Date: 2025-08-23
|
||
|
||
This release ships two user-facing improvements and several robustness fixes under the hood:
|
||
|
||
1. **Hide Deleted Content** (default ON)
|
||
2. **Copy Embed Link** icon for image-like services
|
||
|
||
---
|
||
|
||
## 1) Hide Deleted Content (default ON)
|
||
|
||
### Background
|
||
|
||
On QDN there is no true “delete”; content is typically removed by republishing the same identifier with an **empty** file. After recent Qortal Hub UI changes blocked 0-byte payloads, deletes are commonly represented by a **very small file** (e.g., a single newline) rather than exactly 0 bytes. These ghost entries clutter lists and inflate counts.
|
||
|
||
### What’s new
|
||
|
||
- A default-enabled **Hide Deleted Content** checkbox appears in the filter bar.
|
||
- When enabled, the app hides entries that are recognized as actual delete markers and **recomputes counts and totals** from the visible baseline so UI chips and summaries match what you see.
|
||
- The preference is **persisted** in `localStorage` and restored on reload.
|
||
|
||
### How detection works (technical)
|
||
|
||
We conservatively flag a row as deleted only if we’re confident it’s a delete marker, not legitimate tiny content.
|
||
|
||
1. **Legacy 0-byte** fast path: `size === 0` → deleted.
|
||
2. **Tiny-file verification:** for items with small sizes (threshold varies by service), we **fetch bytes** (and **decrypt** if private) and then check the payload after stripping:
|
||
- UTF-8 **BOM** (`EF BB BF`),
|
||
- standard whitespace bytes (`00`, `09`, `0A`, `0D`, `20`),
|
||
- and **NBSP** (`C2 A0`) pairs.
|
||
If nothing remains, we treat it as a delete marker.
|
||
3. **Service-specific thresholds:**
|
||
- **IMAGE / QCHAT_IMAGE / THUMBNAIL**: up to **8 KB** (allows for encoding/overhead while still catching “newline deletes” that present as ~32 B).
|
||
- All other services: **256 B**.
|
||
4. **Readiness guard:** we call `waitForResourceReady(...)` before fetch to avoid false negatives when the local node hasn’t finished building the resource.
|
||
5. **Explicit exclusions:** **CHAIN_DATA** and **CHAIN_COMMENT** are **never** treated as deleted (small legitimate posts/comments remain visible).
|
||
|
||
> Rationale: detection is **content-based**, not size-only, so legitimate small text like `1`, `ok`, or short JSON stays visible. The thresholds merely decide which items undergo byte-level verification.
|
||
|
||
### UI & state changes
|
||
|
||
- Checkbox: **Hide Deleted Content** (checked by default).
|
||
- Counts: service chips and “Total results / Total size” reflect the **filtered** (visible) set.
|
||
- Preference: stored under `hideDeleted` in `localStorage`.
|
||
|
||
### Known limitations
|
||
|
||
- If an environment produces other whitespace encodings, a rare delete marker might escape detection. We already handle BOM, ASCII whitespace, and NBSP; we can extend this list if a new pattern appears.
|
||
- Very large “delete” files (unlikely) won’t be scanned under current thresholds.
|
||
|
||
### Minimal code map
|
||
|
||
All changes are confined to **`script.js`**:
|
||
|
||
- `markDeletedEntries(...)` — detection logic + readiness + decrypt + byte checks
|
||
- `getBaselineResults()`, `recomputeServiceCounts()` — pipeline helpers
|
||
- `initHideDeletedUI()` — injects the checkbox and wires the toggle
|
||
- `loadAllResults()` — calls `markDeletedEntries(...)` and uses `recomputeServiceCounts()`
|
||
- `applyServiceFilter()` — uses baseline (respects the toggle)
|
||
|
||
### How to test
|
||
|
||
1. Load an account with known “newline delete” IMAGE items → ensure they **disappear** with the checkbox ON.
|
||
2. Toggle OFF → they **reappear**.
|
||
3. Verify service chip counts and “Total Size” change accordingly.
|
||
4. Confirm **CHAIN_DATA / CHAIN_COMMENT** small items remain visible regardless of the toggle.
|
||
|
||
---
|
||
|
||
## 2) Copy Embed Link (IMAGE / QCHAT_IMAGE / THUMBNAIL)
|
||
|
||
### What’s new
|
||
|
||
- An inline **link icon** appears **next to the identifier** for image-like services (same 15×15 scale as edit/delete icons) with a **white circular background** for contrast.
|
||
- Clicking the icon copies an embed-compatible URI and shows a brief inline toast: **“Embed link copied!”**
|
||
|
||
**Format:**
|
||
|
||
```
|
||
qortal://use-embed/IMAGE?name={NAME}&identifier={IDENTIFIER}&service={SERVICE}
|
||
```
|
||
|
||
### Implementation details
|
||
|
||
- The icon is inline SVG (white background circle + black glyph) injected by `buildContentTable(...)`.
|
||
- Clipboard: uses `navigator.clipboard.writeText` with a `<textarea>` fallback.
|
||
- A small inline toast appears for ~1.8s; prior toasts are removed to avoid stacking.
|
||
|
||
### How to test
|
||
|
||
1. Click the link icon for an IMAGE row → paste to confirm the URI matches the format above.
|
||
2. Observe the “Embed link copied!” toast; click again to verify de-duped toasts.
|
||
|
||
---
|
||
|
||
## Upgrade instructions
|
||
|
||
1. Replace your `script.js` with the new version from this release.
|
||
2. Hard refresh (Ctrl/Cmd+Shift+R) to bust cache.
|
||
3. Optional: clear localStorage key `hideDeleted` if you want to re-test default behavior.
|
||
|
||
## Compatibility / Safety
|
||
|
||
- No server/API changes required.
|
||
- All behavior degrades gracefully: if clipboard API isn’t available, fallback copy is used; if fetch/decrypt fails for a tiny item, we **do not** mark it deleted (safe default).
|