162 lines
3.5 KiB
TypeScript
162 lines
3.5 KiB
TypeScript
import {AtUri} from '@atproto/api'
|
|
import {PROD_SERVICE} from 'state/index'
|
|
import TLDs from 'tlds'
|
|
|
|
export function isValidDomain(str: string): boolean {
|
|
return !!TLDs.find(tld => {
|
|
let i = str.lastIndexOf(tld)
|
|
if (i === -1) {
|
|
return false
|
|
}
|
|
return str.charAt(i - 1) === '.' && i === str.length - tld.length
|
|
})
|
|
}
|
|
|
|
export function makeRecordUri(
|
|
didOrName: string,
|
|
collection: string,
|
|
rkey: string,
|
|
) {
|
|
const urip = new AtUri('at://host/')
|
|
urip.host = didOrName
|
|
urip.collection = collection
|
|
urip.rkey = rkey
|
|
return urip.toString()
|
|
}
|
|
|
|
export function toNiceDomain(url: string): string {
|
|
try {
|
|
const urlp = new URL(url)
|
|
if (`https://${urlp.host}` === PROD_SERVICE) {
|
|
return 'Bluesky Social'
|
|
}
|
|
return urlp.host ? urlp.host : url
|
|
} catch (e) {
|
|
return url
|
|
}
|
|
}
|
|
|
|
export function toShortUrl(url: string): string {
|
|
try {
|
|
const urlp = new URL(url)
|
|
if (urlp.protocol !== 'http:' && urlp.protocol !== 'https:') {
|
|
return url
|
|
}
|
|
const shortened =
|
|
urlp.host +
|
|
(urlp.pathname === '/' ? '' : urlp.pathname) +
|
|
urlp.search +
|
|
urlp.hash
|
|
if (shortened.length > 30) {
|
|
return shortened.slice(0, 27) + '...'
|
|
}
|
|
return shortened ? shortened : url
|
|
} catch (e) {
|
|
return url
|
|
}
|
|
}
|
|
|
|
export function toShareUrl(url: string): string {
|
|
if (!url.startsWith('https')) {
|
|
const urlp = new URL('https://bsky.app')
|
|
urlp.pathname = url
|
|
url = urlp.toString()
|
|
}
|
|
return url
|
|
}
|
|
|
|
export function isBskyAppUrl(url: string): boolean {
|
|
return url.startsWith('https://bsky.app/')
|
|
}
|
|
|
|
export function isExternalUrl(url: string): boolean {
|
|
return !isBskyAppUrl(url) && url.startsWith('http')
|
|
}
|
|
|
|
export function isBskyPostUrl(url: string): boolean {
|
|
if (isBskyAppUrl(url)) {
|
|
try {
|
|
const urlp = new URL(url)
|
|
return /profile\/(?<name>[^/]+)\/post\/(?<rkey>[^/]+)/i.test(
|
|
urlp.pathname,
|
|
)
|
|
} catch {}
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function isBskyCustomFeedUrl(url: string): boolean {
|
|
if (isBskyAppUrl(url)) {
|
|
try {
|
|
const urlp = new URL(url)
|
|
return /profile\/(?<name>[^/]+)\/feed\/(?<rkey>[^/]+)/i.test(
|
|
urlp.pathname,
|
|
)
|
|
} catch {}
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function isBskyListUrl(url: string): boolean {
|
|
if (isBskyAppUrl(url)) {
|
|
try {
|
|
const urlp = new URL(url)
|
|
return /profile\/(?<name>[^/]+)\/lists\/(?<rkey>[^/]+)/i.test(
|
|
urlp.pathname,
|
|
)
|
|
} catch {
|
|
console.error('Unexpected error in isBskyListUrl()', url)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function convertBskyAppUrlIfNeeded(url: string): string {
|
|
if (isBskyAppUrl(url)) {
|
|
try {
|
|
const urlp = new URL(url)
|
|
return urlp.pathname
|
|
} catch (e) {
|
|
console.error('Unexpected error in convertBskyAppUrlIfNeeded()', e)
|
|
}
|
|
}
|
|
return url
|
|
}
|
|
|
|
export function listUriToHref(url: string): string {
|
|
try {
|
|
const {hostname, rkey} = new AtUri(url)
|
|
return `/profile/${hostname}/lists/${rkey}`
|
|
} catch {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
export function getYoutubeVideoId(link: string): string | undefined {
|
|
let url
|
|
try {
|
|
url = new URL(link)
|
|
} catch (e) {
|
|
return undefined
|
|
}
|
|
|
|
if (
|
|
url.hostname !== 'www.youtube.com' &&
|
|
url.hostname !== 'youtube.com' &&
|
|
url.hostname !== 'youtu.be'
|
|
) {
|
|
return undefined
|
|
}
|
|
if (url.hostname === 'youtu.be') {
|
|
const videoId = url.pathname.split('/')[1]
|
|
if (!videoId) {
|
|
return undefined
|
|
}
|
|
return videoId
|
|
}
|
|
const videoId = url.searchParams.get('v') as string
|
|
if (!videoId) {
|
|
return undefined
|
|
}
|
|
return videoId
|
|
}
|