Add allowed services
This commit is contained in:
@@ -18,7 +18,6 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
|||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import * as TextField from '#/components/forms/TextField'
|
import * as TextField from '#/components/forms/TextField'
|
||||||
import {Clock_Stroke2_Corner0_Rounded as ClockIcon} from '#/components/icons/Clock'
|
import {Clock_Stroke2_Corner0_Rounded as ClockIcon} from '#/components/icons/Clock'
|
||||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {LinkPreview} from './LinkPreview'
|
import {LinkPreview} from './LinkPreview'
|
||||||
@@ -172,26 +171,13 @@ function DialogInner({
|
|||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
</View>
|
</View>
|
||||||
{(liveLinkError || linkMetaError) && (
|
{(liveLinkError || linkMetaError) && (
|
||||||
<View style={[a.flex_row, a.gap_xs, a.align_center]}>
|
<Admonition type="error">
|
||||||
<WarningIcon
|
{liveLinkError ? (
|
||||||
style={[{color: t.palette.negative_500}]}
|
<Trans>This is not a valid link</Trans>
|
||||||
size="sm"
|
) : (
|
||||||
/>
|
cleanError(linkMetaError)
|
||||||
<Text
|
)}
|
||||||
style={[
|
</Admonition>
|
||||||
a.text_sm,
|
|
||||||
a.leading_snug,
|
|
||||||
a.flex_1,
|
|
||||||
a.font_semi_bold,
|
|
||||||
{color: t.palette.negative_500},
|
|
||||||
]}>
|
|
||||||
{liveLinkError ? (
|
|
||||||
<Trans>This is not a valid link</Trans>
|
|
||||||
) : (
|
|
||||||
cleanError(linkMetaError)
|
|
||||||
)}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<LinkPreview linkMeta={linkMeta} loading={linkMetaLoading} />
|
<LinkPreview linkMeta={linkMeta} loading={linkMetaLoading} />
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {definitelyUrl} from '#/lib/strings/url-helpers'
|
import {definitelyUrl} from '#/lib/strings/url-helpers'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
|
import {useLiveNowConfig} from '#/state/service-config'
|
||||||
import {useTickEveryMinute} from '#/state/shell'
|
import {useTickEveryMinute} from '#/state/shell'
|
||||||
import {atoms as a, ios, native, platform, useTheme, web} from '#/alf'
|
import {atoms as a, ios, native, platform, useTheme, web} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
import {Admonition} from '#/components/Admonition'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import * as TextField from '#/components/forms/TextField'
|
import * as TextField from '#/components/forms/TextField'
|
||||||
|
import {getLiveServiceNames} from '#/components/live/utils'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
import * as Select from '#/components/Select'
|
import * as Select from '#/components/Select'
|
||||||
@@ -48,6 +50,10 @@ function DialogInner({profile}: {profile: bsky.profile.AnyProfileView}) {
|
|||||||
const [duration, setDuration] = useState(60)
|
const [duration, setDuration] = useState(60)
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const tick = useTickEveryMinute()
|
const tick = useTickEveryMinute()
|
||||||
|
const liveNowConfig = useLiveNowConfig()
|
||||||
|
const {formatted: allowedServices} = getLiveServiceNames(
|
||||||
|
liveNowConfig.allowedDomains,
|
||||||
|
)
|
||||||
|
|
||||||
const time = useCallback(
|
const time = useCallback(
|
||||||
(offset: number) => {
|
(offset: number) => {
|
||||||
@@ -138,7 +144,7 @@ function DialogInner({profile}: {profile: bsky.profile.AnyProfileView}) {
|
|||||||
/>
|
/>
|
||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
</View>
|
</View>
|
||||||
{(liveLinkError || linkMetaError) && (
|
{liveLinkError || linkMetaError ? (
|
||||||
<Admonition type="error">
|
<Admonition type="error">
|
||||||
{liveLinkError ? (
|
{liveLinkError ? (
|
||||||
<Trans>This is not a valid link</Trans>
|
<Trans>This is not a valid link</Trans>
|
||||||
@@ -146,6 +152,13 @@ function DialogInner({profile}: {profile: bsky.profile.AnyProfileView}) {
|
|||||||
cleanError(linkMetaError)
|
cleanError(linkMetaError)
|
||||||
)}
|
)}
|
||||||
</Admonition>
|
</Admonition>
|
||||||
|
) : (
|
||||||
|
<Admonition type="tip">
|
||||||
|
<Trans>
|
||||||
|
The following services are enabled for your account:{' '}
|
||||||
|
{allowedServices}
|
||||||
|
</Trans>
|
||||||
|
</Admonition>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<LinkPreview linkMeta={linkMeta} loading={linkMetaLoading} />
|
<LinkPreview linkMeta={linkMeta} loading={linkMetaLoading} />
|
||||||
|
|||||||
@@ -18,21 +18,7 @@ import {useLiveNowConfig} from '#/state/service-config'
|
|||||||
import {useAgent, useSession} from '#/state/session'
|
import {useAgent, useSession} from '#/state/session'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {useDialogContext} from '#/components/Dialog'
|
import {useDialogContext} from '#/components/Dialog'
|
||||||
|
import {getLiveServiceNames} from '#/components/live/utils'
|
||||||
const serviceUrlToNameMap: Record<string, string> = {
|
|
||||||
'twitch.tv': 'Twitch',
|
|
||||||
'www.twitch.tv': 'Twitch',
|
|
||||||
'youtube.com': 'YouTube',
|
|
||||||
'www.youtube.com': 'YouTube',
|
|
||||||
'youtu.be': 'YouTube',
|
|
||||||
'nba.com': 'NBA',
|
|
||||||
'www.nba.com': 'NBA',
|
|
||||||
'nba.smart.link': 'nba.smart.link',
|
|
||||||
'espn.com': 'ESPN',
|
|
||||||
'www.espn.com': 'ESPN',
|
|
||||||
'stream.place': 'Streamplace',
|
|
||||||
'skylight.social': 'Skylight',
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useLiveLinkMetaQuery(url: string | null) {
|
export function useLiveLinkMetaQuery(url: string | null) {
|
||||||
const liveNowConfig = useLiveNowConfig()
|
const liveNowConfig = useLiveNowConfig()
|
||||||
@@ -46,14 +32,10 @@ export function useLiveLinkMetaQuery(url: string | null) {
|
|||||||
if (!url) return undefined
|
if (!url) return undefined
|
||||||
const urlp = new URL(url)
|
const urlp = new URL(url)
|
||||||
if (!liveNowConfig.allowedDomains.includes(urlp.hostname)) {
|
if (!liveNowConfig.allowedDomains.includes(urlp.hostname)) {
|
||||||
const services = Array.from(
|
const {formatted} = getLiveServiceNames(liveNowConfig.allowedDomains)
|
||||||
new Set(
|
|
||||||
liveNowConfig.allowedDomains.map(d => serviceUrlToNameMap[d] || d),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
_(
|
_(
|
||||||
msg`This service is not supported while the Live feature is in beta. Allowed services: ${services.join(', ')}.`,
|
msg`This service is not supported while the Live feature is in beta. Allowed services: ${formatted}.`,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,3 +35,28 @@ export function useDebouncedValue<T>(val: T, delayMs: number): T {
|
|||||||
|
|
||||||
return prev
|
return prev
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const serviceUrlToNameMap: Record<string, string> = {
|
||||||
|
'twitch.tv': 'Twitch',
|
||||||
|
'www.twitch.tv': 'Twitch',
|
||||||
|
'youtube.com': 'YouTube',
|
||||||
|
'www.youtube.com': 'YouTube',
|
||||||
|
'youtu.be': 'YouTube',
|
||||||
|
'nba.com': 'NBA',
|
||||||
|
'www.nba.com': 'NBA',
|
||||||
|
'nba.smart.link': 'nba.smart.link',
|
||||||
|
'espn.com': 'ESPN',
|
||||||
|
'www.espn.com': 'ESPN',
|
||||||
|
'stream.place': 'Streamplace',
|
||||||
|
'skylight.social': 'Skylight',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLiveServiceNames(domains: string[]) {
|
||||||
|
const names = Array.from(
|
||||||
|
new Set(domains.map(d => serviceUrlToNameMap[d] || d)),
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
names,
|
||||||
|
formatted: names.join(', '),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user