main → zio/dev

zio/stable
Ducky 2024-09-10 21:11:58 +01:00
commit 219a10eca9
31 changed files with 242 additions and 157 deletions

View File

@ -80,6 +80,13 @@ func run(args []string) {
Value: "",
EnvVars: []string{"BASIC_AUTH_PASSWORD"},
},
&cli.StringSliceFlag{
Name: "cors-allowed-origins",
Usage: "list of allowed origins for CORS requests",
Required: false,
Value: cli.NewStringSlice("https://bsky.app", "https://main.bsky.dev", "https://app.staging.bsky.dev"),
EnvVars: []string{"CORS_ALLOWED_ORIGINS"},
},
},
},
}

View File

@ -57,6 +57,7 @@ func serve(cctx *cli.Context) error {
linkHost := cctx.String("link-host")
ipccHost := cctx.String("ipcc-host")
basicAuthPassword := cctx.String("basic-auth-password")
corsOrigins := cctx.StringSlice("cors-allowed-origins")
// Echo
e := echo.New()
@ -168,6 +169,12 @@ func serve(cctx *cli.Context) error {
RedirectCode: http.StatusFound,
}))
// CORS middleware
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: corsOrigins,
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodOptions},
}))
//
// configure routes
//

View File

@ -10,7 +10,7 @@ import {
import {Trans} from '@lingui/macro'
import {parseTenorGif} from '#/lib/strings/embed-player'
import {atoms as a} from '#/alf'
import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography'
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
@ -43,10 +43,10 @@ export function Embed({
))}
</Outer>
)
} else if (AppBskyEmbedExternal.isView(embed) && embed.external.thumb) {
} else if (AppBskyEmbedExternal.isView(media) && media.external.thumb) {
let url: URL | undefined
try {
url = new URL(embed.external.uri)
url = new URL(media.external.uri)
} catch {}
if (url) {
const {success} = parseTenorGif(url)
@ -54,17 +54,17 @@ export function Embed({
return (
<Outer style={style}>
<GifItem
thumbnail={embed.external.thumb}
alt={embed.external.title}
thumbnail={media.external.thumb}
alt={media.external.title}
/>
</Outer>
)
}
}
} else if (AppBskyEmbedVideo.isView(embed)) {
} else if (AppBskyEmbedVideo.isView(media)) {
return (
<Outer style={style}>
<VideoItem thumbnail={embed.thumbnail} alt={embed.alt} />
<VideoItem thumbnail={media.thumbnail} alt={media.alt} />
</Outer>
)
}
@ -91,12 +91,13 @@ export function ImageItem({
alt?: string
children?: React.ReactNode
}) {
const t = useTheme()
return (
<View style={[a.relative, a.flex_1, {aspectRatio: 1, maxWidth: 100}]}>
<Image
key={thumbnail}
source={{uri: thumbnail}}
style={[a.flex_1, a.rounded_xs]}
style={[a.flex_1, a.rounded_xs, t.atoms.bg_contrast_25]}
contentFit="cover"
accessible={true}
accessibilityIgnoresInvertColors

View File

@ -0,0 +1,53 @@
import {
useCallback,
useEffect,
useRef,
useState,
useSyncExternalStore,
} from 'react'
import {isFirefox, isSafari} from '#/lib/browser'
import {isWeb} from '#/platform/detection'
function fullscreenSubscribe(onChange: () => void) {
document.addEventListener('fullscreenchange', onChange)
return () => document.removeEventListener('fullscreenchange', onChange)
}
export function useFullscreen(ref?: React.RefObject<HTMLElement>) {
if (!isWeb) throw new Error("'useFullscreen' is a web-only hook")
const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () =>
Boolean(document.fullscreenElement),
)
const scrollYRef = useRef<null | number>(null)
const [prevIsFullscreen, setPrevIsFullscreen] = useState(isFullscreen)
const toggleFullscreen = useCallback(() => {
if (isFullscreen) {
document.exitFullscreen()
} else {
if (!ref) throw new Error('No ref provided')
if (!ref.current) return
scrollYRef.current = window.scrollY
ref.current.requestFullscreen()
}
}, [isFullscreen, ref])
useEffect(() => {
if (prevIsFullscreen === isFullscreen) return
setPrevIsFullscreen(isFullscreen)
// Chrome has an issue where it doesn't scroll back to the top after exiting fullscreen
// Let's play it safe and do it if not FF or Safari, since anything else will probably be chromium
if (prevIsFullscreen && !isFirefox && !isSafari) {
setTimeout(() => {
if (scrollYRef.current !== null) {
window.scrollTo(0, scrollYRef.current)
scrollYRef.current = null
}
}, 100)
}
}, [isFullscreen, prevIsFullscreen])
return [isFullscreen, toggleFullscreen] as const
}

View File

@ -3,9 +3,9 @@ import {ImagePickerAsset} from 'expo-image-picker'
import {VideoTooLargeError} from 'lib/media/video/errors'
import {CompressedVideo} from './types'
const MAX_VIDEO_SIZE = 1024 * 1024 * 100 // 100MB
const MAX_VIDEO_SIZE = 1024 * 1024 * 50 // 50mb
// doesn't actually compress, but throws if >100MB
// doesn't actually compress, converts to ArrayBuffer
export async function compressVideo(
asset: ImagePickerAsset,
_opts?: {

View File

@ -1,6 +1,6 @@
export class VideoTooLargeError extends Error {
constructor() {
super('Videos cannot be larger than 100MB')
super('Videos cannot be larger than 50mb')
this.name = 'VideoTooLargeError'
}
}

View File

@ -1,6 +1,3 @@
export type Gate =
// Keep this alphabetic please.
| 'debug_show_feedcontext'
| 'suggested_feeds_interstitial'
| 'video_upload' // upload videos
| 'video_view_on_posts' // see posted videos
'debug_show_feedcontext' | 'suggested_feeds_interstitial' | 'video_upload' // upload videos

View File

@ -7664,8 +7664,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "La política de privacitat ha estat traslladada a <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "El vídeo triat és més gran de 100MB."
msgid "The selected video is larger than 50MB."
msgstr "El vídeo triat és més gran de 50MB."
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."
@ -8605,8 +8605,8 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgstr "Els vídeos no poder ser de més de 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr "Els vídeos no poder ser de més de 50MB"
#: src/screens/Profile/Header/Shell.tsx:113
msgid "View {0}'s avatar"

View File

@ -6965,7 +6965,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Die Datenschutzerklärung wurde nach <0/> verschoben"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7871,7 +7871,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -644,7 +644,7 @@ msgstr ""
msgid "An error occurred"
msgstr ""
#: src/state/queries/video/video.ts:227
#: src/state/queries/video/video.ts:232
msgid "An error occurred while compressing the video."
msgstr ""
@ -682,7 +682,7 @@ msgstr ""
msgid "An error occurred while trying to follow all"
msgstr ""
#: src/state/queries/video/video.ts:194
#: src/state/queries/video/video.ts:199
msgid "An error occurred while uploading the video."
msgstr ""
@ -1096,8 +1096,8 @@ msgstr ""
#: src/components/Prompt.tsx:124
#: src/components/TagMenu/index.tsx:282
#: src/screens/Deactivated.tsx:161
#: src/view/com/composer/Composer.tsx:590
#: src/view/com/composer/Composer.tsx:605
#: src/view/com/composer/Composer.tsx:591
#: src/view/com/composer/Composer.tsx:606
#: src/view/com/modals/ChangeEmail.tsx:213
#: src/view/com/modals/ChangeEmail.tsx:215
#: src/view/com/modals/ChangeHandle.tsx:148
@ -1457,7 +1457,7 @@ msgstr ""
msgid "Closes password update alert"
msgstr ""
#: src/view/com/composer/Composer.tsx:602
#: src/view/com/composer/Composer.tsx:603
msgid "Closes post composer and discards post draft"
msgstr ""
@ -1496,7 +1496,7 @@ msgstr ""
msgid "Complete the challenge"
msgstr ""
#: src/view/com/composer/Composer.tsx:710
#: src/view/com/composer/Composer.tsx:711
msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length"
msgstr ""
@ -2005,7 +2005,7 @@ msgstr ""
msgid "Dialog: adjust who can interact with this post"
msgstr ""
#: src/view/com/composer/Composer.tsx:351
#: src/view/com/composer/Composer.tsx:352
msgid "Did you want to say anything?"
msgstr ""
@ -3086,7 +3086,7 @@ msgstr ""
msgid "Getting started"
msgstr ""
#: src/components/MediaPreview.tsx:119
#: src/components/MediaPreview.tsx:120
msgid "GIF"
msgstr ""
@ -4046,8 +4046,12 @@ msgstr ""
msgid "Music"
msgstr ""
#: src/components/TagMenu/index.tsx:263
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:345
msgctxt "video"
msgid "Mute"
msgstr ""
#: src/components/TagMenu/index.tsx:263
msgid "Mute"
msgstr ""
@ -4579,7 +4583,7 @@ msgstr ""
#~ msgid "Onboarding tour step {0}: {1}"
#~ msgstr ""
#: src/view/com/composer/Composer.tsx:667
#: src/view/com/composer/Composer.tsx:668
msgid "One or more images is missing alt text."
msgstr ""
@ -5053,7 +5057,7 @@ msgstr ""
msgid "Please Verify Your Email"
msgstr ""
#: src/view/com/composer/Composer.tsx:355
#: src/view/com/composer/Composer.tsx:356
msgid "Please wait for your link card to finish loading"
msgstr ""
@ -5066,8 +5070,8 @@ msgstr ""
msgid "Porn"
msgstr ""
#: src/view/com/composer/Composer.tsx:642
#: src/view/com/composer/Composer.tsx:649
#: src/view/com/composer/Composer.tsx:643
#: src/view/com/composer/Composer.tsx:650
msgctxt "action"
msgid "Post"
msgstr ""
@ -5246,11 +5250,11 @@ msgstr ""
msgid "Public, shareable lists which can drive feeds."
msgstr ""
#: src/view/com/composer/Composer.tsx:627
#: src/view/com/composer/Composer.tsx:628
msgid "Publish post"
msgstr ""
#: src/view/com/composer/Composer.tsx:627
#: src/view/com/composer/Composer.tsx:628
msgid "Publish reply"
msgstr ""
@ -5555,7 +5559,7 @@ msgstr ""
#~ msgid "Replies to this thread are disabled"
#~ msgstr ""
#: src/view/com/composer/Composer.tsx:640
#: src/view/com/composer/Composer.tsx:641
msgctxt "action"
msgid "Reply"
msgstr ""
@ -7034,8 +7038,8 @@ msgstr ""
msgid "The Privacy Policy has been moved to <0/>"
msgstr ""
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
#: src/state/queries/video/video.ts:227
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7568,8 +7572,12 @@ msgstr ""
msgid "Unlike this feed"
msgstr ""
#: src/components/TagMenu/index.tsx:263
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:344
msgctxt "video"
msgid "Unmute"
msgstr ""
#: src/components/TagMenu/index.tsx:263
#: src/view/screens/ProfileList.tsx:689
msgid "Unmute"
msgstr ""
@ -7642,7 +7650,7 @@ msgstr ""
msgid "Unsubscribed from list"
msgstr ""
#: src/state/queries/video/video.ts:240
#: src/state/queries/video/video.ts:245
msgid "Unsupported video type: {mimeType}"
msgstr ""
@ -7909,7 +7917,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113
@ -8085,7 +8093,7 @@ msgstr ""
msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
msgstr ""
#: src/view/com/composer/Composer.tsx:417
#: src/view/com/composer/Composer.tsx:418
msgid "We're sorry! The post you are replying to has been deleted."
msgstr ""
@ -8124,7 +8132,7 @@ msgstr ""
#: src/view/com/auth/SplashScreen.tsx:40
#: src/view/com/auth/SplashScreen.web.tsx:86
#: src/view/com/composer/Composer.tsx:512
#: src/view/com/composer/Composer.tsx:513
msgid "What's up?"
msgstr ""
@ -8199,11 +8207,11 @@ msgstr ""
msgid "Write a message"
msgstr ""
#: src/view/com/composer/Composer.tsx:708
#: src/view/com/composer/Composer.tsx:709
msgid "Write post"
msgstr ""
#: src/view/com/composer/Composer.tsx:511
#: src/view/com/composer/Composer.tsx:512
#: src/view/com/post-thread/PostThreadComposePrompt.tsx:42
msgid "Write your reply"
msgstr ""
@ -8551,6 +8559,10 @@ msgstr ""
msgid "Your account has been deleted"
msgstr ""
#: src/state/queries/video/video.ts:185
msgid "Your account is not yet old enough to upload videos. Please try again later."
msgstr ""
#: src/view/screens/Settings/ExportCarDialog.tsx:65
msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately."
msgstr ""
@ -8614,7 +8626,7 @@ msgstr ""
msgid "Your password has been changed successfully!"
msgstr ""
#: src/view/com/composer/Composer.tsx:463
#: src/view/com/composer/Composer.tsx:464
msgid "Your post has been published"
msgstr ""
@ -8630,7 +8642,7 @@ msgstr ""
msgid "Your profile, posts, feeds, and lists will no longer be visible to other Bluesky users. You can reactivate your account at any time by logging in."
msgstr ""
#: src/view/com/composer/Composer.tsx:462
#: src/view/com/composer/Composer.tsx:463
msgid "Your reply has been published"
msgstr ""

View File

@ -6893,7 +6893,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "La Política de privacidad se ha trasladado a <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7763,7 +7763,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -6989,7 +6989,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Tietosuojakäytäntö on siirretty kohtaan <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7863,7 +7863,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -6486,7 +6486,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Notre politique de confidentialité a été déplacée vers <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7302,7 +7302,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr "Les vidéos ne peuvent pas dépasser 100 Mo"
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -7035,7 +7035,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Bogadh Polasaí na Príobháideachta go dtí <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7912,7 +7912,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -7609,7 +7609,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "गोपनीयता नीति को <0/> पर स्थानांतरित किया गया है"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -8535,7 +8535,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -7040,7 +7040,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Kebijakan Privasi telah dipindahkan ke <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7914,8 +7914,8 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgstr "Video tidak boleh lebih besar dari 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr "Video tidak boleh lebih besar dari 50MB"
#: src/screens/Profile/Header/Shell.tsx:113
msgid "View {0}'s avatar"

View File

@ -7321,8 +7321,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "La politica sulla privacy è stata spostata a <0/><0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "Questo video è più grande di 100MB."
msgid "The selected video is larger than 50MB."
msgstr "Questo video è più grande di 50MB."
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."
@ -8222,8 +8222,8 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgstr "I video non possono essere più grandi di 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr "I video non possono essere più grandi di 50MB"
#: src/screens/Profile/Header/Shell.tsx:113
msgid "View {0}'s avatar"

View File

@ -6272,8 +6272,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "プライバシーポリシーは<0/>に移動しました"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "選択したビデオのサイズが100MBを超えています。"
msgid "The selected video is larger than 50MB."
msgstr "選択したビデオのサイズが50MBを超えています。"
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."

View File

@ -6272,8 +6272,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "개인정보 처리방침을 <0/>(으)로 이동했습니다"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "선택한 동영상이 100MB를 초과합니다."
msgid "The selected video is larger than 50MB."
msgstr "선택한 동영상이 50MB를 초과합니다."
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."

View File

@ -644,7 +644,7 @@ msgstr "Ocorreu um erro"
msgid "An error occurred"
msgstr "Ocorreu um erro"
#: src/state/queries/video/video.ts:227
#: src/state/queries/video/video.ts:232
msgid "An error occurred while compressing the video."
msgstr "Ocorreu um erro ao compactar o vídeo."
@ -682,7 +682,7 @@ msgstr "Ocorreu um erro ao selecionar o vídeo"
msgid "An error occurred while trying to follow all"
msgstr "Ocorreu um erro ao tentar seguir todos"
#: src/state/queries/video/video.ts:194
#: src/state/queries/video/video.ts:199
msgid "An error occurred while uploading the video."
msgstr "Ocorreu um erro ao enviar o vídeo."
@ -1096,8 +1096,8 @@ msgstr "Só pode conter letras, números, espaços, riscas e subtraços. Deve te
#: src/components/Prompt.tsx:124
#: src/components/TagMenu/index.tsx:282
#: src/screens/Deactivated.tsx:161
#: src/view/com/composer/Composer.tsx:590
#: src/view/com/composer/Composer.tsx:605
#: src/view/com/composer/Composer.tsx:591
#: src/view/com/composer/Composer.tsx:606
#: src/view/com/modals/ChangeEmail.tsx:213
#: src/view/com/modals/ChangeEmail.tsx:215
#: src/view/com/modals/ChangeHandle.tsx:148
@ -1457,7 +1457,7 @@ msgstr "Fecha barra de navegação inferior"
msgid "Closes password update alert"
msgstr "Fecha alerta de troca de senha"
#: src/view/com/composer/Composer.tsx:602
#: src/view/com/composer/Composer.tsx:603
msgid "Closes post composer and discards post draft"
msgstr "Fecha o editor de post e descarta o rascunho"
@ -1496,7 +1496,7 @@ msgstr "Completar e começar a usar sua conta"
msgid "Complete the challenge"
msgstr "Complete o captcha"
#: src/view/com/composer/Composer.tsx:710
#: src/view/com/composer/Composer.tsx:711
msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length"
msgstr "Escreva posts de até {MAX_GRAPHEME_LENGTH} caracteres"
@ -2005,7 +2005,7 @@ msgstr "Desanexar postagem de citação?"
msgid "Dialog: adjust who can interact with this post"
msgstr "Diálogo: ajuste quem pode interagir com esta postagem"
#: src/view/com/composer/Composer.tsx:351
#: src/view/com/composer/Composer.tsx:352
msgid "Did you want to say anything?"
msgstr "Você gostaria de dizer alguma coisa?"
@ -3086,7 +3086,7 @@ msgstr "Vamos começar"
msgid "Getting started"
msgstr "Começando"
#: src/components/MediaPreview.tsx:119
#: src/components/MediaPreview.tsx:120
msgid "GIF"
msgstr ""
@ -4046,8 +4046,12 @@ msgstr "Filmes"
msgid "Music"
msgstr "Música"
#: src/components/TagMenu/index.tsx:263
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:345
msgctxt "video"
msgid "Mute"
msgstr ""
#: src/components/TagMenu/index.tsx:263
msgid "Mute"
msgstr "Silenciar"
@ -4579,7 +4583,7 @@ msgstr "Resetar tutoriais"
#~ msgid "Onboarding tour step {0}: {1}"
#~ msgstr "Etapa do tour de integração {0}: {1}"
#: src/view/com/composer/Composer.tsx:667
#: src/view/com/composer/Composer.tsx:668
msgid "One or more images is missing alt text."
msgstr "Uma ou mais imagens estão sem texto alternativo."
@ -5053,7 +5057,7 @@ msgstr "Por favor entre como @{0}"
msgid "Please Verify Your Email"
msgstr "Por favor, verifique seu e-mail"
#: src/view/com/composer/Composer.tsx:355
#: src/view/com/composer/Composer.tsx:356
msgid "Please wait for your link card to finish loading"
msgstr "Aguarde até que a prévia de link termine de carregar"
@ -5066,8 +5070,8 @@ msgstr "Política"
msgid "Porn"
msgstr "Pornografia"
#: src/view/com/composer/Composer.tsx:642
#: src/view/com/composer/Composer.tsx:649
#: src/view/com/composer/Composer.tsx:643
#: src/view/com/composer/Composer.tsx:650
msgctxt "action"
msgid "Post"
msgstr "Postar"
@ -5246,11 +5250,11 @@ msgstr "Listas públicas e compartilháveis para silenciar ou bloquear usuários
msgid "Public, shareable lists which can drive feeds."
msgstr "Listas públicas e compartilháveis que geram feeds."
#: src/view/com/composer/Composer.tsx:627
#: src/view/com/composer/Composer.tsx:628
msgid "Publish post"
msgstr "Publicar post"
#: src/view/com/composer/Composer.tsx:627
#: src/view/com/composer/Composer.tsx:628
msgid "Publish reply"
msgstr "Publicar resposta"
@ -5555,7 +5559,7 @@ msgstr "Respostas para esta postagem estão desativadas."
#~ msgid "Replies to this thread are disabled"
#~ msgstr "Respostas para esta thread estão desativadas"
#: src/view/com/composer/Composer.tsx:640
#: src/view/com/composer/Composer.tsx:641
msgctxt "action"
msgid "Reply"
msgstr "Responder"
@ -7034,9 +7038,9 @@ msgstr "O post pode ter sido excluído."
msgid "The Privacy Policy has been moved to <0/>"
msgstr "A Política de Privacidade foi movida para <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "Vídeo selecionado é maior que 100 MB."
#: src/state/queries/video/video.ts:227
msgid "The selected video is larger than 50MB."
msgstr "Vídeo selecionado é maior que 50 MB."
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."
@ -7568,8 +7572,12 @@ msgstr "Deixar de seguir"
msgid "Unlike this feed"
msgstr "Descurtir este feed"
#: src/components/TagMenu/index.tsx:263
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:344
msgctxt "video"
msgid "Unmute"
msgstr ""
#: src/components/TagMenu/index.tsx:263
#: src/view/screens/ProfileList.tsx:689
msgid "Unmute"
msgstr "Dessilenciar"
@ -7642,7 +7650,7 @@ msgstr "Desinscrever-se deste rotulador"
msgid "Unsubscribed from list"
msgstr "Cancelada inscrição na lista"
#: src/state/queries/video/video.ts:240
#: src/state/queries/video/video.ts:245
msgid "Unsupported video type: {mimeType}"
msgstr "Tipo de vídeo não suportado: {mimeType}"
@ -7909,7 +7917,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr "Vídeos não podem ter mais de 100 MB"
#: src/screens/Profile/Header/Shell.tsx:113
@ -8085,7 +8093,7 @@ msgstr "Não foi possível carregar sua lista de palavras silenciadas. Por favor
msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
msgstr "Lamentamos, mas sua busca não pôde ser concluída. Por favor, tente novamente em alguns minutos."
#: src/view/com/composer/Composer.tsx:417
#: src/view/com/composer/Composer.tsx:418
msgid "We're sorry! The post you are replying to has been deleted."
msgstr "Sentimos muito! A postagem que você está respondendo foi excluída."
@ -8124,7 +8132,7 @@ msgstr "Como você quer chamar seu pacote inicial?"
#: src/view/com/auth/SplashScreen.tsx:40
#: src/view/com/auth/SplashScreen.web.tsx:86
#: src/view/com/composer/Composer.tsx:512
#: src/view/com/composer/Composer.tsx:513
msgid "What's up?"
msgstr "E aí?"
@ -8199,11 +8207,11 @@ msgstr "Largo"
msgid "Write a message"
msgstr "Escreva uma mensagem"
#: src/view/com/composer/Composer.tsx:708
#: src/view/com/composer/Composer.tsx:709
msgid "Write post"
msgstr "Escrever post"
#: src/view/com/composer/Composer.tsx:511
#: src/view/com/composer/Composer.tsx:512
#: src/view/com/post-thread/PostThreadComposePrompt.tsx:42
msgid "Write your reply"
msgstr "Escreva sua resposta"
@ -8551,6 +8559,10 @@ msgstr "Sua conta"
msgid "Your account has been deleted"
msgstr "Sua conta foi excluída"
#: src/state/queries/video/video.ts:185
msgid "Your account is not yet old enough to upload videos. Please try again later."
msgstr "Sua conta ainda não tem idade suficiente para enviar vídeos. Por favor, tente novamente mais tarde."
#: src/view/screens/Settings/ExportCarDialog.tsx:65
msgid "Your account repository, containing all public data records, can be downloaded as a \"CAR\" file. This file does not include media embeds, such as images, or your private data, which must be fetched separately."
msgstr "O repositório da sua conta, contendo todos os seus dados públicos, pode ser baixado como um arquivo \"CAR\". Este arquivo não inclui imagens ou dados privados, estes devem ser exportados separadamente."
@ -8614,7 +8626,7 @@ msgstr "Suas palavras silenciadas"
msgid "Your password has been changed successfully!"
msgstr "Sua senha foi alterada com sucesso!"
#: src/view/com/composer/Composer.tsx:463
#: src/view/com/composer/Composer.tsx:464
msgid "Your post has been published"
msgstr "Seu post foi publicado"
@ -8630,7 +8642,7 @@ msgstr "Seu perfil"
msgid "Your profile, posts, feeds, and lists will no longer be visible to other Bluesky users. You can reactivate your account at any time by logging in."
msgstr "Seu perfil, postagens, feeds e listas não serão mais visíveis para outros usuários do Bluesky. Você pode reativar sua conta a qualquer momento fazendo login."
#: src/view/com/composer/Composer.tsx:462
#: src/view/com/composer/Composer.tsx:463
msgid "Your reply has been published"
msgstr "Sua resposta foi publicada"

View File

@ -6237,8 +6237,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Политика конфиденциальности была перемещена в <0/>"
#: src/state/queries/video/video.ts:188
msgid "The selected video is larger than 100MB."
msgstr "Размер выбранного видео превышает 100МБ."
msgid "The selected video is larger than 50MB."
msgstr "Размер выбранного видео превышает 50МБ."
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."

View File

@ -7498,7 +7498,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Gizlilik Politikası <0/> konumuna taşındı"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -8412,7 +8412,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -7040,7 +7040,7 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "Політика конфіденційності була переміщена до <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgid "The selected video is larger than 50MB."
msgstr ""
#: src/screens/StarterPack/StarterPackScreen.tsx:713
@ -7914,7 +7914,7 @@ msgid "Video: {0}"
msgstr ""
#: src/view/com/composer/videos/state.ts:27
#~ msgid "Videos cannot be larger than 100MB"
#~ msgid "Videos cannot be larger than 50MB"
#~ msgstr ""
#: src/screens/Profile/Header/Shell.tsx:113

View File

@ -6272,8 +6272,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "隐私政策已迁移至 <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "选择的视频大小超过 100MB。"
msgid "The selected video is larger than 50MB."
msgstr "选择的视频大小超过 50MB。"
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."

View File

@ -6272,8 +6272,8 @@ msgid "The Privacy Policy has been moved to <0/>"
msgstr "隱私政策已移動到 <0/>"
#: src/state/queries/video/video.ts:222
msgid "The selected video is larger than 100MB."
msgstr "選擇的影片檔案大小超過 100MB。"
msgid "The selected video is larger than 50MB."
msgstr "選擇的影片檔案大小超過 50MB。"
#: src/screens/StarterPack/StarterPackScreen.tsx:713
msgid "The starter pack that you are trying to view is invalid. You may delete this starter pack instead."

View File

@ -180,6 +180,11 @@ export function useUploadVideo({
msg`You've reached your daily limit for video uploads (too many videos)`,
)
break
case 'Account is not old enough to upload videos':
message = _(
msg`Your account is not yet old enough to upload videos. Please try again later.`,
)
break
default:
message = e.message
break
@ -219,7 +224,7 @@ export function useUploadVideo({
} else if (e instanceof VideoTooLargeError) {
dispatch({
type: 'SetError',
error: _(msg`The selected video is larger than 100MB.`),
error: _(msg`The selected video is larger than 50MB.`),
})
} else {
dispatch({

View File

@ -303,9 +303,13 @@ export const ComposePost = observer(function ComposePost({
const onPhotoPasted = useCallback(
async (uri: string) => {
track('Composer:PastedPhotos')
await gallery.paste(uri)
if (uri.startsWith('data:video/')) {
selectVideo({uri, type: 'video', height: 0, width: 0})
} else {
await gallery.paste(uri)
}
},
[gallery, track],
[gallery, track, selectVideo],
)
const isAltTextRequiredAndMissing = useMemo(() => {

View File

@ -93,9 +93,9 @@ export const TextInput = React.forwardRef(function TextInputImpl(
}
}, [onPressPublish])
React.useEffect(() => {
textInputWebEmitter.addListener('photo-pasted', onPhotoPasted)
textInputWebEmitter.addListener('media-pasted', onPhotoPasted)
return () => {
textInputWebEmitter.removeListener('photo-pasted', onPhotoPasted)
textInputWebEmitter.removeListener('media-pasted', onPhotoPasted)
}
}, [onPhotoPasted])
@ -105,8 +105,8 @@ export const TextInput = React.forwardRef(function TextInputImpl(
if (transfer) {
const items = transfer.items
getImageFromUri(items, (uri: string) => {
textInputWebEmitter.emit('photo-pasted', uri)
getImageOrVideoFromUri(items, (uri: string) => {
textInputWebEmitter.emit('media-pasted', uri)
})
}
@ -160,8 +160,8 @@ export const TextInput = React.forwardRef(function TextInputImpl(
view.pasteText(text)
preventDefault = true
}
getImageFromUri(clipboardData.items, (uri: string) => {
textInputWebEmitter.emit('photo-pasted', uri)
getImageOrVideoFromUri(clipboardData.items, (uri: string) => {
textInputWebEmitter.emit('media-pasted', uri)
})
if (preventDefault) {
// Return `true` to prevent ProseMirror's default paste behavior.
@ -346,7 +346,7 @@ const styles = StyleSheet.create({
},
})
function getImageFromUri(
function getImageOrVideoFromUri(
items: DataTransferItemList,
callback: (uri: string) => void,
) {
@ -363,11 +363,21 @@ function getImageFromUri(
if (blob.type.startsWith('image/')) {
blobToDataUri(blob).then(callback, err => console.error(err))
}
if (blob.type.startsWith('video/')) {
blobToDataUri(blob).then(callback, err => console.error(err))
}
}
})
} else if (type.startsWith('image/')) {
const file = item.getAsFile()
if (file) {
blobToDataUri(file).then(callback, err => console.error(err))
}
} else if (type.startsWith('video/')) {
const file = item.getAsFile()
if (file) {
blobToDataUri(file).then(callback, err => console.error(err))
}

View File

@ -20,6 +20,8 @@ import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons
import {Text} from '#/components/Typography'
import {SubtitleFilePicker} from './SubtitleFilePicker'
const MAX_NUM_CAPTIONS = 1
interface Props {
defaultAltText: string
captions: {lang: string; file: File}[]
@ -134,7 +136,9 @@ function SubtitleDialogInner({
</Text>
<SubtitleFilePicker
onSelectFile={handleSelectFile}
disabled={subtitleMissingLanguage || captions.length >= 4}
disabled={
subtitleMissingLanguage || captions.length >= MAX_NUM_CAPTIONS
}
/>
<View>
{captions.map((subtitle, i) => (

View File

@ -4,27 +4,29 @@ import {AppBskyEmbedVideo} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {isFirefox} from '#/lib/browser'
import {clamp} from '#/lib/numbers'
import {useGate} from '#/lib/statsig/statsig'
import {
HLSUnsupportedError,
VideoEmbedInnerWeb,
VideoNotFoundError,
} from '#/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb'
import {atoms as a} from '#/alf'
import {useFullscreen} from '#/components/hooks/useFullscreen'
import {ErrorBoundary} from '../ErrorBoundary'
import {useActiveVideoWeb} from './ActiveVideoWebContext'
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
const ref = useRef<HTMLDivElement>(null)
const gate = useGate()
const {active, setActive, sendPosition, currentActiveView} =
useActiveVideoWeb()
const [onScreen, setOnScreen] = useState(false)
const [isFullscreen] = useFullscreen()
useEffect(() => {
if (!ref.current) return
if (isFullscreen && !isFirefox) return
const observer = new IntersectionObserver(
entries => {
const entry = entries[0]
@ -38,7 +40,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
)
observer.observe(ref.current)
return () => observer.disconnect()
}, [sendPosition])
}, [sendPosition, isFullscreen])
const [key, setKey] = useState(0)
const renderError = useCallback(
@ -48,10 +50,6 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
[key],
)
if (!gate('video_view_on_posts')) {
return null
}
let aspectRatio = 16 / 9
if (embed.aspectRatio) {
@ -106,11 +104,13 @@ function ViewportObserver({
}) {
const ref = useRef<HTMLDivElement>(null)
const [nearScreen, setNearScreen] = useState(false)
const [isFullscreen] = useFullscreen()
// Send position when scrolling. This is done with an IntersectionObserver
// observing a div of 100vh height
useEffect(() => {
if (!ref.current) return
if (isFullscreen && !isFirefox) return
const observer = new IntersectionObserver(
entries => {
const entry = entries[0]
@ -124,7 +124,7 @@ function ViewportObserver({
)
observer.observe(ref.current)
return () => observer.disconnect()
}, [sendPosition])
}, [sendPosition, isFullscreen])
// In case scrolling hasn't started yet, send up the position
useEffect(() => {

View File

@ -1,10 +1,4 @@
import React, {
useCallback,
useEffect,
useRef,
useState,
useSyncExternalStore,
} from 'react'
import React, {useCallback, useEffect, useRef, useState} from 'react'
import {Pressable, View} from 'react-native'
import {SvgProps} from 'react-native-svg'
import {msg, Trans} from '@lingui/macro'
@ -21,6 +15,7 @@ import {
} from '#/state/preferences'
import {atoms as a, useTheme, web} from '#/alf'
import {Button} from '#/components/Button'
import {useFullscreen} from '#/components/hooks/useFullscreen'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {
ArrowsDiagonalIn_Stroke2_Corner0_Rounded as ArrowsInIcon,
@ -341,8 +336,8 @@ export function Controls({
)}
<ControlButton
active={muted}
activeLabel={_(msg`Unmute`)}
inactiveLabel={_(msg`Mute`)}
activeLabel={_(msg({message: `Unmute`, context: 'video'}))}
inactiveLabel={_(msg({message: `Mute`, context: 'video'}))}
activeIcon={MuteIcon}
inactiveIcon={UnmuteIcon}
onPress={onPressMute}
@ -850,25 +845,3 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
canPlay,
}
}
function fullscreenSubscribe(onChange: () => void) {
document.addEventListener('fullscreenchange', onChange)
return () => document.removeEventListener('fullscreenchange', onChange)
}
function useFullscreen(ref: React.RefObject<HTMLElement>) {
const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () =>
Boolean(document.fullscreenElement),
)
const toggleFullscreen = useCallback(() => {
if (isFullscreen) {
document.exitFullscreen()
} else {
if (!ref.current) return
ref.current.requestFullscreen()
}
}, [isFullscreen, ref])
return [isFullscreen, toggleFullscreen] as const
}