Fix RSS URLs treated as internal (#3156)
* Fix RSS URLs treated as internal * Add utils to patch relative RSS external links * modify router to support multiple paths --------- Co-authored-by: Hailey <me@haileyok.com>
This commit is contained in:
parent
aad8c080ed
commit
594958c6dc
4 changed files with 40 additions and 5 deletions
|
|
@ -2,9 +2,15 @@ import {RouteParams, Route} from './types'
|
||||||
|
|
||||||
export class Router {
|
export class Router {
|
||||||
routes: [string, Route][] = []
|
routes: [string, Route][] = []
|
||||||
constructor(description: Record<string, string>) {
|
constructor(description: Record<string, string | string[]>) {
|
||||||
for (const [screen, pattern] of Object.entries(description)) {
|
for (const [screen, pattern] of Object.entries(description)) {
|
||||||
|
if (typeof pattern === 'string') {
|
||||||
this.routes.push([screen, createRoute(pattern)])
|
this.routes.push([screen, createRoute(pattern)])
|
||||||
|
} else {
|
||||||
|
pattern.forEach(subPattern => {
|
||||||
|
this.routes.push([screen, createRoute(subPattern)])
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import {BSKY_SERVICE} from 'lib/constants'
|
||||||
import TLDs from 'tlds'
|
import TLDs from 'tlds'
|
||||||
import psl from 'psl'
|
import psl from 'psl'
|
||||||
|
|
||||||
|
export const BSKY_APP_HOST = 'https://bsky.app'
|
||||||
|
|
||||||
export function isValidDomain(str: string): boolean {
|
export function isValidDomain(str: string): boolean {
|
||||||
return !!TLDs.find(tld => {
|
return !!TLDs.find(tld => {
|
||||||
let i = str.lastIndexOf(tld)
|
let i = str.lastIndexOf(tld)
|
||||||
|
|
@ -67,8 +69,21 @@ export function isBskyAppUrl(url: string): boolean {
|
||||||
return url.startsWith('https://bsky.app/')
|
return url.startsWith('https://bsky.app/')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isRelativeUrl(url: string): boolean {
|
||||||
|
return /^\/[^/]/.test(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isBskyRSSUrl(url: string): boolean {
|
||||||
|
return (
|
||||||
|
(url.startsWith('https://bsky.app/') || isRelativeUrl(url)) &&
|
||||||
|
/\/rss\/?$/.test(url)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function isExternalUrl(url: string): boolean {
|
export function isExternalUrl(url: string): boolean {
|
||||||
return !isBskyAppUrl(url) && url.startsWith('http')
|
const external = !isBskyAppUrl(url) && url.startsWith('http')
|
||||||
|
const rss = isBskyRSSUrl(url)
|
||||||
|
return external || rss
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isBskyPostUrl(url: string): boolean {
|
export function isBskyPostUrl(url: string): boolean {
|
||||||
|
|
@ -149,7 +164,7 @@ export function linkRequiresWarning(uri: string, label: string) {
|
||||||
const labelDomain = labelToDomain(label)
|
const labelDomain = labelToDomain(label)
|
||||||
|
|
||||||
// If the uri started with a / we know it is internal.
|
// If the uri started with a / we know it is internal.
|
||||||
if (uri.startsWith('/')) {
|
if (isRelativeUrl(uri)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,3 +237,8 @@ export function splitApexDomain(hostname: string): [string, string] {
|
||||||
hostnamep.domain,
|
hostnamep.domain,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createBskyAppAbsoluteUrl(path: string): string {
|
||||||
|
const sanitizedPath = path.replace(BSKY_APP_HOST, '').replace(/^\/+/, '')
|
||||||
|
return `${BSKY_APP_HOST.replace(/\/$/, '')}/${sanitizedPath}`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export const router = new Router({
|
||||||
ModerationModlists: '/moderation/modlists',
|
ModerationModlists: '/moderation/modlists',
|
||||||
ModerationMutedAccounts: '/moderation/muted-accounts',
|
ModerationMutedAccounts: '/moderation/muted-accounts',
|
||||||
ModerationBlockedAccounts: '/moderation/blocked-accounts',
|
ModerationBlockedAccounts: '/moderation/blocked-accounts',
|
||||||
Profile: '/profile/:name',
|
Profile: ['/profile/:name', '/profile/:name/rss'],
|
||||||
ProfileFollowers: '/profile/:name/followers',
|
ProfileFollowers: '/profile/:name/followers',
|
||||||
ProfileFollows: '/profile/:name/follows',
|
ProfileFollows: '/profile/:name/follows',
|
||||||
ProfileList: '/profile/:name/lists/:rkey',
|
ProfileList: '/profile/:name/lists/:rkey',
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ import * as WebBrowser from 'expo-web-browser'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {useModalControls} from '../modals'
|
import {useModalControls} from '../modals'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {
|
||||||
|
isBskyRSSUrl,
|
||||||
|
isRelativeUrl,
|
||||||
|
createBskyAppAbsoluteUrl,
|
||||||
|
} from 'lib/strings/url-helpers'
|
||||||
|
|
||||||
type StateContext = persisted.Schema['useInAppBrowser']
|
type StateContext = persisted.Schema['useInAppBrowser']
|
||||||
type SetContext = (v: persisted.Schema['useInAppBrowser']) => void
|
type SetContext = (v: persisted.Schema['useInAppBrowser']) => void
|
||||||
|
|
@ -57,6 +62,10 @@ export function useOpenLink() {
|
||||||
|
|
||||||
const openLink = React.useCallback(
|
const openLink = React.useCallback(
|
||||||
(url: string, override?: boolean) => {
|
(url: string, override?: boolean) => {
|
||||||
|
if (isBskyRSSUrl(url) && isRelativeUrl(url)) {
|
||||||
|
url = createBskyAppAbsoluteUrl(url)
|
||||||
|
}
|
||||||
|
|
||||||
if (isNative && !url.startsWith('mailto:')) {
|
if (isNative && !url.startsWith('mailto:')) {
|
||||||
if (override === undefined && enabled === undefined) {
|
if (override === undefined && enabled === undefined) {
|
||||||
openModal({
|
openModal({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue