openvibers/openvibe.network Commits
A go-live notice never links to a section of a live channel (#776)
Changes
@@@ -15,9 +15,20 @@ function channelUrl(username) {return `${LIVE_ORIGIN}/@${encodeURIComponent(String(username || '').replace(/^@+/, ''))}`;}function canonicalChannelUrl(url, username) {-- const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(String(url || ''));-- if (m) return channelUrl(m[1]);-- return url || channelUrl(username);++ const raw = String(url || '').trim();++ if (!raw) return channelUrl(username);++ // A section (or a query naming one) is not part of a channel: /@name#about, /@name?section=videos and the old++ // /name#about all hand over /@name, so a go-live notice never lands on About (ask 285). Other Live pages keep++ // their own address, including any fragment that means something there.++ try {++ const u = new URL(raw);++ if (u.origin === LIVE_ORIGIN) {++ const m = /^\/(?:@)?([A-Za-z0-9_]{3,24})\/?$/.exec(u.pathname);++ if (m) return channelUrl(m[1]);++ }++ } catch { /* not an absolute URL: the old-style check below */ }++ const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(raw);++ return m ? channelUrl(m[1]) : raw;}/** One fan-out per streamer per `stream_live_cooldown_min` (60) and at most `stream_live_daily_cap` (8) per 24h. */@@@ -257,7 +257,10 @@ const rows = async (userId) => await db.prepare('SELECT * FROM notifications WHEassert.strictEqual(channelUrl('@carol'), 'https://openvibe.live/@carol');assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol', 'carol'), 'https://openvibe.live/@carol', 'a channel link is kept');assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/', 'carol'), 'https://openvibe.live/@carol');-- assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5', 'carol'), 'https://openvibe.live/vod/5', 'other Live pages are kept');++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol#about', 'carol'), 'https://openvibe.live/@carol', 'a section is not part of a channel link');++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol?section=videos', 'carol'), 'https://openvibe.live/@carol', 'a section query is not either');++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/#clips', 'carol'), 'https://openvibe.live/@carol', 'nor on the old channel shape');++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5#t=10', 'carol'), 'https://openvibe.live/vod/5#t=10', 'other Live pages keep their own address');assert.strictEqual(canonicalChannelUrl(null, 'carol'), 'https://openvibe.live/@carol', 'no link: the channel page');}assert.strictEqual(n1.sender_id, 20, 'sender is the streamer\'s Network account (dedupe key)');
@@ -15,9 +15,20 @@ function channelUrl(username) {
@@ -15,9 +15,20 @@ function channelUrl(username) {
return `${LIVE_ORIGIN}/@${encodeURIComponent(String(username || '').replace(/^@+/, ''))}`;
return `${LIVE_ORIGIN}/@${encodeURIComponent(String(username || '').replace(/^@+/, ''))}`;
}
}
function canonicalChannelUrl(url, username) {
function canonicalChannelUrl(url, username) {
- const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(String(url || ''));
- if (m) return channelUrl(m[1]);
- return url || channelUrl(username);
+ const raw = String(url || '').trim();
+ if (!raw) return channelUrl(username);
+ // A section (or a query naming one) is not part of a channel: /@name#about, /@name?section=videos and the old
+ // /name#about all hand over /@name, so a go-live notice never lands on About (ask 285). Other Live pages keep
+ // their own address, including any fragment that means something there.
+ try {
+ const u = new URL(raw);
+ if (u.origin === LIVE_ORIGIN) {
+ const m = /^\/(?:@)?([A-Za-z0-9_]{3,24})\/?$/.exec(u.pathname);
+ if (m) return channelUrl(m[1]);
+ }
+ } catch { /* not an absolute URL: the old-style check below */ }
+ const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(raw);
+ return m ? channelUrl(m[1]) : raw;
}
}
/** One fan-out per streamer per `stream_live_cooldown_min` (60) and at most `stream_live_daily_cap` (8) per 24h. */
/** One fan-out per streamer per `stream_live_cooldown_min` (60) and at most `stream_live_daily_cap` (8) per 24h. */
@@ -257,7 +257,10 @@ const rows = async (userId) => await db.prepare('SELECT * FROM notifications WHE
@@ -257,7 +257,10 @@ const rows = async (userId) => await db.prepare('SELECT * FROM notifications WHE
assert.strictEqual(channelUrl('@carol'), 'https://openvibe.live/@carol');
assert.strictEqual(channelUrl('@carol'), 'https://openvibe.live/@carol');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol', 'carol'), 'https://openvibe.live/@carol', 'a channel link is kept');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol', 'carol'), 'https://openvibe.live/@carol', 'a channel link is kept');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/', 'carol'), 'https://openvibe.live/@carol');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/', 'carol'), 'https://openvibe.live/@carol');
- assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5', 'carol'), 'https://openvibe.live/vod/5', 'other Live pages are kept');
+ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol#about', 'carol'), 'https://openvibe.live/@carol', 'a section is not part of a channel link');
+ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol?section=videos', 'carol'), 'https://openvibe.live/@carol', 'a section query is not either');
+ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/#clips', 'carol'), 'https://openvibe.live/@carol', 'nor on the old channel shape');
+ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5#t=10', 'carol'), 'https://openvibe.live/vod/5#t=10', 'other Live pages keep their own address');
assert.strictEqual(canonicalChannelUrl(null, 'carol'), 'https://openvibe.live/@carol', 'no link: the channel page');
assert.strictEqual(canonicalChannelUrl(null, 'carol'), 'https://openvibe.live/@carol', 'no link: the channel page');
}
}
assert.strictEqual(n1.sender_id, 20, 'sender is the streamer\'s Network account (dedupe key)');
assert.strictEqual(n1.sender_id, 20, 'sender is the streamer\'s Network account (dedupe key)');