mirror of
https://github.com/dergigi/boris.git
synced 2026-02-23 16:04:29 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a92a9ee3a3 | ||
|
|
f39e34c699 | ||
|
|
b58f34d587 | ||
|
|
76d1d4544e | ||
|
|
5e56176e2d | ||
|
|
a2a4e7e454 | ||
|
|
b266288b0f |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.3.4] - 2025-10-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Add p tag (author tag) to highlights of nostr-native content for proper attribution
|
||||||
|
|
||||||
|
## [0.3.3] - 2025-10-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Service Worker for robust offline image caching
|
||||||
|
- /explore route to discover blog posts from friends on Nostr
|
||||||
|
- Explore button (newspaper icon) in bookmarks header
|
||||||
|
- "Connecting" status indicator on page load (instead of immediately showing "Offline")
|
||||||
|
- Last fetch time display with relative timestamps in bookmarks list
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Simplify image caching to use Service Worker transparently
|
||||||
|
- Move refresh button from top bar to end of bookmarks list
|
||||||
|
- Make explore page article cards proper links (supports CMD+click to open in new tab)
|
||||||
|
- Reorganize bookmarks UI for better UX
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Improve image cache resilience for offline viewing and hard reloads
|
||||||
|
- Correct TypeScript types for cache stats state
|
||||||
|
- Resolve linter errors for unused parameters
|
||||||
|
- Import useEventModel from applesauce-react/hooks for proper type safety
|
||||||
|
- Import Models from applesauce-core instead of applesauce-react
|
||||||
|
- Use correct useEventModel hook for profile loading in BlogPostCard
|
||||||
|
|
||||||
## [0.3.0] - 2025-10-09
|
## [0.3.0] - 2025-10-09
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -472,6 +500,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Optimize relay usage following applesauce-relay best practices
|
- Optimize relay usage following applesauce-relay best practices
|
||||||
- Use applesauce-react event models for better profile handling
|
- Use applesauce-react event models for better profile handling
|
||||||
|
|
||||||
|
[0.3.4]: https://github.com/dergigi/boris/compare/v0.3.3...v0.3.4
|
||||||
|
[0.3.3]: https://github.com/dergigi/boris/compare/v0.3.2...v0.3.3
|
||||||
|
[0.3.2]: https://github.com/dergigi/boris/compare/v0.3.1...v0.3.2
|
||||||
|
[0.3.1]: https://github.com/dergigi/boris/compare/v0.3.0...v0.3.1
|
||||||
[0.3.0]: https://github.com/dergigi/boris/compare/v0.2.10...v0.3.0
|
[0.3.0]: https://github.com/dergigi/boris/compare/v0.2.10...v0.3.0
|
||||||
[0.2.10]: https://github.com/dergigi/boris/compare/v0.2.9...v0.2.10
|
[0.2.10]: https://github.com/dergigi/boris/compare/v0.2.9...v0.2.10
|
||||||
[0.2.9]: https://github.com/dergigi/boris/compare/v0.2.8...v0.2.9
|
[0.2.9]: https://github.com/dergigi/boris/compare/v0.2.8...v0.2.9
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "boris",
|
"name": "boris",
|
||||||
"version": "0.3.3",
|
"version": "0.3.5",
|
||||||
"description": "A minimal nostr client for bookmark management",
|
"description": "A minimal nostr client for bookmark management",
|
||||||
"homepage": "https://read.withboris.com/",
|
"homepage": "https://read.withboris.com/",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
6
public/_routes.json
Normal file
6
public/_routes.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"include": ["/*"],
|
||||||
|
"exclude": ["/assets/*", "/robots.txt", "/sw.js", "/_headers", "/_redirects"]
|
||||||
|
}
|
||||||
|
|
||||||
@@ -13,6 +13,7 @@ export const RelayStatusIndicator: React.FC<RelayStatusIndicatorProps> = ({ rela
|
|||||||
// Poll frequently for responsive offline indicator (5s instead of default 20s)
|
// Poll frequently for responsive offline indicator (5s instead of default 20s)
|
||||||
const relayStatuses = useRelayStatus({ relayPool, pollingInterval: 5000 })
|
const relayStatuses = useRelayStatus({ relayPool, pollingInterval: 5000 })
|
||||||
const [isConnecting, setIsConnecting] = useState(true)
|
const [isConnecting, setIsConnecting] = useState(true)
|
||||||
|
const [connectingStartTime] = useState(Date.now())
|
||||||
|
|
||||||
if (!relayPool) return null
|
if (!relayPool) return null
|
||||||
|
|
||||||
@@ -26,20 +27,27 @@ export const RelayStatusIndicator: React.FC<RelayStatusIndicatorProps> = ({ rela
|
|||||||
const localOnlyMode = hasLocalRelay && !hasRemoteRelay
|
const localOnlyMode = hasLocalRelay && !hasRemoteRelay
|
||||||
const offlineMode = connectedUrls.length === 0
|
const offlineMode = connectedUrls.length === 0
|
||||||
|
|
||||||
// Show "Connecting" for first few seconds or until relays connect
|
// Show "Connecting" for minimum duration (15s) to avoid flashing states
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (connectedUrls.length > 0) {
|
const MIN_CONNECTING_DURATION = 15000 // 15 seconds minimum
|
||||||
// Connected! Stop showing connecting state
|
const elapsedTime = Date.now() - connectingStartTime
|
||||||
|
|
||||||
|
if (connectedUrls.length > 0 && elapsedTime >= MIN_CONNECTING_DURATION) {
|
||||||
|
// Connected and minimum time passed - stop showing connecting state
|
||||||
setIsConnecting(false)
|
setIsConnecting(false)
|
||||||
} else {
|
} else if (connectedUrls.length > 0) {
|
||||||
// No connections yet - show connecting for 4 seconds
|
// Connected but haven't shown connecting long enough
|
||||||
setIsConnecting(true)
|
const remainingTime = MIN_CONNECTING_DURATION - elapsedTime
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setIsConnecting(false)
|
setIsConnecting(false)
|
||||||
}, 4000)
|
}, remainingTime)
|
||||||
return () => clearTimeout(timeout)
|
return () => clearTimeout(timeout)
|
||||||
|
} else if (elapsedTime >= MIN_CONNECTING_DURATION) {
|
||||||
|
// No connections and minimum time passed - show offline
|
||||||
|
setIsConnecting(false)
|
||||||
}
|
}
|
||||||
}, [connectedUrls.length])
|
// If no connections and time hasn't passed, keep showing connecting
|
||||||
|
}, [connectedUrls.length, connectingStartTime])
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -70,10 +78,7 @@ export const RelayStatusIndicator: React.FC<RelayStatusIndicatorProps> = ({ rela
|
|||||||
</div>
|
</div>
|
||||||
<div className="relay-status-text">
|
<div className="relay-status-text">
|
||||||
{isConnecting ? (
|
{isConnecting ? (
|
||||||
<>
|
<span className="relay-status-title">Connecting</span>
|
||||||
<span className="relay-status-title">Connecting</span>
|
|
||||||
<span className="relay-status-subtitle">Establishing connections...</span>
|
|
||||||
</>
|
|
||||||
) : offlineMode ? (
|
) : offlineMode ? (
|
||||||
<>
|
<>
|
||||||
<span className="relay-status-title">Offline</span>
|
<span className="relay-status-title">Offline</span>
|
||||||
|
|||||||
@@ -80,6 +80,16 @@ export async function createHighlight(
|
|||||||
highlightEvent.tags.push(['alt', 'Highlight created by Boris. readwithboris.com'])
|
highlightEvent.tags.push(['alt', 'Highlight created by Boris. readwithboris.com'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add p tag (author tag) for nostr-native content
|
||||||
|
// This tags the original author so they can see highlights of their work
|
||||||
|
if (typeof source === 'object' && 'kind' in source) {
|
||||||
|
// Only add p tag if it doesn't already exist
|
||||||
|
const hasPTag = highlightEvent.tags.some(tag => tag[0] === 'p' && tag[1] === source.pubkey)
|
||||||
|
if (!hasPTag) {
|
||||||
|
highlightEvent.tags.push(['p', source.pubkey])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add zap tags for nostr-native content (NIP-57 Appendix G)
|
// Add zap tags for nostr-native content (NIP-57 Appendix G)
|
||||||
if (typeof source === 'object' && 'kind' in source) {
|
if (typeof source === 'object' && 'kind' in source) {
|
||||||
// Migrate old settings format to new weight-based format if needed
|
// Migrate old settings format to new weight-based format if needed
|
||||||
|
|||||||
Reference in New Issue
Block a user