Compare commits

...

4 Commits

Author SHA1 Message Date
7709634a9a Merge pull request 'Clear Nostr event cache from Settings' (#47) from feature/clear_nostr_cache into master
All checks were successful
CI / Lint (push) Successful in 31s
CI / Test (push) Successful in 57s
Reviewed-on: #47
2026-04-23 08:22:02 +00:00
3ddc85669f Clear nostr event cache from Settings
All checks were successful
CI / Lint (pull_request) Successful in 32s
CI / Test (pull_request) Successful in 57s
Release Drafter / Update release notes draft (pull_request) Successful in 7s
2026-04-23 09:19:25 +01:00
95961e680f Add rationale for kind numbers
All checks were successful
CI / Lint (push) Successful in 31s
CI / Test (push) Successful in 58s
2026-04-22 15:37:45 +04:00
9468a6a0cc Revise photos NIP draft
All checks were successful
CI / Lint (push) Successful in 32s
CI / Test (push) Successful in 58s
2026-04-22 15:31:24 +04:00
5 changed files with 51 additions and 7 deletions

View File

@@ -12,6 +12,7 @@ const stripProtocol = (url) => (url ? url.replace(/^wss?:\/\//, '') : '');
export default class AppMenuSettingsNostr extends Component { export default class AppMenuSettingsNostr extends Component {
@service settings; @service settings;
@service nostrData; @service nostrData;
@service toast;
@tracked newReadRelay = ''; @tracked newReadRelay = '';
@tracked newWriteRelay = ''; @tracked newWriteRelay = '';
@@ -90,6 +91,16 @@ export default class AppMenuSettingsNostr extends Component {
this.settings.update('nostrWriteRelays', null); this.settings.update('nostrWriteRelays', null);
} }
@action
async clearCache() {
try {
await this.nostrData.clearCache();
this.toast.show('Nostr cache cleared');
} catch (e) {
this.toast.show(`Failed to clear Nostr cache: ${e.message}`);
}
}
<template> <template>
{{! template-lint-disable no-nested-interactive }} {{! template-lint-disable no-nested-interactive }}
<details> <details>
@@ -213,6 +224,18 @@ export default class AppMenuSettingsNostr extends Component {
</button> </button>
{{/if}} {{/if}}
</div> </div>
<div class="form-group">
<label>Cached data</label>
<button
type="button"
class="btn btn-outline btn-full"
{{on "click" this.clearCache}}
>
<Icon @name="database" @size={{18}} @color="var(--danger-color)" />
Clear profiles, photos, and reviews
</button>
</div>
</div> </div>
</details> </details>
</template> </template>

View File

@@ -356,6 +356,13 @@ export default class NostrDataService extends Service {
return 'Not connected'; return 'Not connected';
} }
async clearCache() {
await this._cachePromise;
if (this.cache) {
await this.cache.deleteAllEvents();
}
}
_cleanupSubscriptions() { _cleanupSubscriptions() {
if (this._requestSub) { if (this._requestSub) {
this._requestSub.unsubscribe(); this._requestSub.unsubscribe();

View File

@@ -7,6 +7,7 @@ import checkSquare from 'feather-icons/dist/icons/check-square.svg?raw';
import chevronLeft from 'feather-icons/dist/icons/chevron-left.svg?raw'; import chevronLeft from 'feather-icons/dist/icons/chevron-left.svg?raw';
import chevronRight from 'feather-icons/dist/icons/chevron-right.svg?raw'; import chevronRight from 'feather-icons/dist/icons/chevron-right.svg?raw';
import clock from 'feather-icons/dist/icons/clock.svg?raw'; import clock from 'feather-icons/dist/icons/clock.svg?raw';
import database from 'feather-icons/dist/icons/database.svg?raw';
import edit from 'feather-icons/dist/icons/edit.svg?raw'; import edit from 'feather-icons/dist/icons/edit.svg?raw';
import facebook from 'feather-icons/dist/icons/facebook.svg?raw'; import facebook from 'feather-icons/dist/icons/facebook.svg?raw';
import gift from 'feather-icons/dist/icons/gift.svg?raw'; import gift from 'feather-icons/dist/icons/gift.svg?raw';
@@ -153,6 +154,7 @@ const ICONS = {
'comedy-mask-and-tragedy-mask': comedyMaskAndTragedyMask, 'comedy-mask-and-tragedy-mask': comedyMaskAndTragedyMask,
croissant, croissant,
'cup-and-saucer': cupAndSaucer, 'cup-and-saucer': cupAndSaucer,
database,
donut, donut,
edit, edit,
eyeglasses, eyeglasses,

View File

@@ -14,7 +14,7 @@ While NIP-68 (Picture-first feeds) caters to general visual feeds, this NIP spec
## Content ## Content
The `.content` of the event SHOULD generally be empty. If a user wishes to provide a detailed description, summary, or caption for a place, clients SHOULD encourage them to create a Place Review event (`kind: 30360`) instead. The `.content` of the event SHOULD generally be empty. If a user wishes to provide a detailed description for a place, clients SHOULD encourage them to create a Place Review event (`kind: 30360`) instead.
## Tags ## Tags
@@ -45,17 +45,19 @@ Used for spatial indexing and discovery. Events MUST include at least one high-p
#### 3. `imeta` — Inline Media Metadata #### 3. `imeta` — Inline Media Metadata
An event MUST contain exactly one `imeta` tag representing a single media item. The primary `url` SHOULD also be appended to the event's `.content` for backwards compatibility with clients that do not parse `imeta` tags. An event MUST contain exactly one `imeta` tag representing a single media item. The primary `url` MAY also be appended to the event's `.content` for backwards compatibility with clients that do not parse `imeta` tags.
Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `m` (MIME type), and `blurhash` where possible. Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `m` (MIME type), `thumb` (URL to a smaller thumbnail image), and `blurhash` where possible. Clients MAY also include `fallback` URLs if the media is hosted on multiple servers.
```json ```json
[ [
"imeta", "imeta",
"url https://example.com/photo.jpg", "url https://blossom.example.com/8e2e28a503fa37482de5b0959ee38b2bb4de4e0a752db24c568981c2ab410260.jpg",
"m image/jpeg", "m image/jpeg",
"dim 3024x4032", "dim 1440x1920",
"alt A steaming bowl of ramen on a wooden table at the restaurant.", "alt A steaming bowl of ramen on a wooden table at the restaurant.",
"fallback https://mirror.example.com/8e2e28a503fa37482de5b0959ee38b2bb4de4e0a752db24c568981c2ab410260.jpg",
"thumb https://example.com/7a1f592f6ea8e932b1de9568285b01851e4cf708466b0a03010b91e92c6c8135.jpg",
"blurhash eVF$^OI:${M{o#*0-nNFxakD-?xVM}WEWB%iNKxvR-oetmo#R-aen$" "blurhash eVF$^OI:${M{o#*0-nNFxakD-?xVM}WEWB%iNKxvR-oetmo#R-aen$"
] ]
``` ```
@@ -83,10 +85,12 @@ Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `
[ [
"imeta", "imeta",
"url https://example.com/ramen.jpg", "url https://blossom.example.com/a9c84e183789a74288b8e05d04cc61230e74f386925a953e6b29f957e8cc3a61.jpg",
"m image/jpeg", "m image/jpeg",
"dim 1080x1080", "dim 1920x1920",
"alt A close-up of spicy miso ramen with chashu pork, soft boiled egg, and scallions.", "alt A close-up of spicy miso ramen with chashu pork, soft boiled egg, and scallions.",
"fallback https://mirror.example.com/a9c84e183789a74288b8e05d04cc61230e74f386925a953e6b29f957e8cc3a61.jpg",
"thumb https://example.com/c5a528e20235e16cc1c18090b8f04179de76288ea4e410b0fcb8d1487e416a2d.jpg",
"blurhash UHI=0o~q4T-o~q%MozM{x]t7RjRPt7oKkCWB" "blurhash UHI=0o~q4T-o~q%MozM{x]t7RjRPt7oKkCWB"
], ],
@@ -98,6 +102,10 @@ Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `
## Rationale ## Rationale
### Kind 360
Easy to remember as a 360-degree view of places.
### Why not use NIP-68 (Picture-first feeds)? ### Why not use NIP-68 (Picture-first feeds)?
NIP-68 is designed for general-purpose social feeds (like Instagram). Place photos require strict guarantees about what entity is being depicted to be useful for map clients, directories, and review aggregators. By mandating the `i` tag for POI linking and the `g` tag for spatial querying, this kind ensures interoperability for geo-spatial applications without cluttering general picture feeds with mundane POI images (like photos of storefronts or menus). NIP-68 is designed for general-purpose social feeds (like Instagram). Place photos require strict guarantees about what entity is being depicted to be useful for map clients, directories, and review aggregators. By mandating the `i` tag for POI linking and the `g` tag for spatial querying, this kind ensures interoperability for geo-spatial applications without cluttering general picture feeds with mundane POI images (like photos of storefronts or menus).

View File

@@ -276,6 +276,10 @@ Content payloads SHOULD NOT include place identifiers.
## Rationale ## Rationale
### Kind 30360
Pairs with kind 360 (Place Photos). Easy to remember as a 360-degree review of all aspects of a place.
### No Place Field in Content ### No Place Field in Content
Avoids duplication and inconsistency with tags. Avoids duplication and inconsistency with tags.