Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ export default function VideoPlaybackControlsScreen() {
const [playbackRateIndex, setPlaybackRateIndex] = React.useState(2);
const [preservePitch, setPreservePitch] = React.useState(true);
const [volume, setVolume] = React.useState(1);
const [requiresLinearPlayback, setRequiresLinearPlayback] = React.useState(false);

const [useDefaultControls, setUseDefaultControls] = React.useState(true);
const [showNext, setShowNext] = React.useState(true);
const [showPrevious, setShowPrevious] = React.useState(true);
const [showSeekForward, setShowSeekForward] = React.useState(true);
const [showSeekBackward, setShowSeekBackward] = React.useState(true);
const [showSubtitles, setShowSubtitles] = React.useState<boolean | null>(null);
const [showSettings, setShowSettings] = React.useState(true);
const [showPlayPause, setShowPlayPause] = React.useState(true);
const [showFullscreen, setShowFullscreen] = React.useState(true);
const [showBottomBar, setShowBottomBar] = React.useState(true);

const player = useVideoPlayer(bigBuckBunnySource, (player) => {
player.volume = volume;
Expand Down Expand Up @@ -56,7 +68,29 @@ export default function VideoPlaybackControlsScreen() {

return (
<View style={styles.contentContainer}>
<VideoView style={styles.video} player={player} nativeControls={false} />
<VideoView
style={styles.video}
player={player}
nativeControls
requiresLinearPlayback={requiresLinearPlayback}
fullscreenOptions={{
enable: showFullscreen,
}}
buttonOptions={
useDefaultControls
? undefined
: {
showNext,
showPrevious,
showSeekForward,
showSeekBackward,
showSubtitles,
showSettings,
showPlayPause,
showBottomBar,
}
}
/>
<ScrollView style={styles.controlsContainer}>
<Button style={styles.button} title="Toggle" onPress={togglePlayer} />
<Button style={styles.button} title="Seek by 10 seconds" onPress={seekBy} />
Expand Down Expand Up @@ -99,6 +133,114 @@ export default function VideoPlaybackControlsScreen() {
titleStyle={styles.switchTitle}
/>
</View>
<View style={styles.row}>
<TitledSwitch
title="Show Fullscreen"
value={showFullscreen}
setValue={setShowFullscreen}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
<TitledSwitch
title="Linear Playback"
value={requiresLinearPlayback}
setValue={setRequiresLinearPlayback}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
{Platform.OS === 'android' && (
<>
<Text style={{ marginTop: 16, marginBottom: 8, fontWeight: 'bold' }}>
Button Options (Android only):
</Text>
<View style={styles.row}>
<TitledSwitch
title="Use Default Controls"
value={useDefaultControls}
setValue={setUseDefaultControls}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
{!useDefaultControls && (
<>
<View style={styles.row}>
<TitledSwitch
title="Show Next"
value={showNext}
setValue={setShowNext}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
<TitledSwitch
title="Show Previous"
value={showPrevious}
setValue={setShowPrevious}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
<View style={styles.row}>
<TitledSwitch
title="Show Seek Forward"
value={showSeekForward}
setValue={setShowSeekForward}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
<TitledSwitch
title="Show Seek Backward"
value={showSeekBackward}
setValue={setShowSeekBackward}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
<View style={styles.row}>
<TitledSwitch
title="Show Settings"
value={showSettings}
setValue={setShowSettings}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
<TitledSwitch
title="Show Play/Pause"
value={showPlayPause}
setValue={setShowPlayPause}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
<View style={styles.row}>
<TitledSwitch
title="Show Bottom Bar"
value={showBottomBar}
setValue={setShowBottomBar}
style={styles.switch}
titleStyle={styles.switchTitle}
/>
</View>
<View style={styles.row}>
<Button
style={styles.button}
title={`Subtitle Button: ${showSubtitles === null ? 'Auto (when available)' : showSubtitles ? 'Always Visible' : 'Never Visible'}`}
onPress={() => {
if (showSubtitles === null) {
setShowSubtitles(true);
} else if (showSubtitles) {
setShowSubtitles(false);
} else {
setShowSubtitles(null);
}
}}
/>
</View>
</>
)}
</>
)}
{Platform.OS === 'ios' && (
<View style={[styles.row, { alignItems: 'center', justifyContent: 'center' }]}>
<Text style={styles.mediumText}>Share video screen:</Text>
Expand Down
2 changes: 1 addition & 1 deletion docs/public/static/data/unversioned/expo-video.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/public/static/data/v52.0.0/expo-video.json

Large diffs are not rendered by default.

29 changes: 0 additions & 29 deletions docs/scripts/generate-llms/compileTalks.js

This file was deleted.

19 changes: 3 additions & 16 deletions docs/scripts/generate-llms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,13 @@ import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';

import { compileTalksFile } from './compileTalks.js';
import { generateLlmsEasTxt } from './llms-eas-txt.js';
import { generateLlmsFullTxt } from './llms-full-txt.js';
import { generateLlmsSdkTxt } from './llms-sdk.js';
import { generateLlmsTxt } from './llms-txt.js';
import {
OUTPUT_DIRECTORY_NAME,
OUTPUT_FILENAME_EAS_DOCS,
OUTPUT_FILENAME_EXPO_DOCS,
OUTPUT_FILENAME_LLMS_TXT,
} from './utils.js';

const GENERATED_LLMS_FILES = [
OUTPUT_FILENAME_LLMS_TXT,
OUTPUT_FILENAME_EXPO_DOCS,
OUTPUT_FILENAME_EAS_DOCS,
'llms-sdk.txt',
];
import { OUTPUT_DIRECTORY_NAME } from './shared.js';

const GENERATED_LLMS_FILES = ['llms.txt', 'llms-full.txt', 'llms-eas.txt', 'llms-sdk.txt'];

async function syncGeneratedLlmsToOut() {
const outDir = path.join(process.cwd(), 'out');
Expand All @@ -42,8 +31,6 @@ async function syncGeneratedLlmsToOut() {
);
}

await compileTalksFile();

const results = await Promise.allSettled([
generateLlmsSdkTxt(),
generateLlmsEasTxt(),
Expand Down
93 changes: 21 additions & 72 deletions docs/scripts/generate-llms/llms-eas-txt.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,39 @@
import fs from 'node:fs';
import { createRequire } from 'node:module';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import {
OUTPUT_DIRECTORY_NAME,
OUTPUT_FILENAME_EAS_DOCS,
TITLE_EAS,
DESCRIPTION_EAS,
generateSectionMarkdown,
processSection,
} from './utils.js';
collectPageHrefs,
composeMarkdownDocument,
ensureBuildOutputDir,
getMarkdownPathFromHref,
readUniqueMarkdownContent,
uniqueInternalHrefs,
} from './shared.js';
import { eas } from '../../constants/navigation.js';

const __filename = fileURLToPath(import.meta.url);
const require = createRequire(__filename);
const easCliData = require('../../ui/components/EASCLIReference/data/eas-cli-commands.json');
const OUTPUT_FILENAME_EAS_DOCS = 'llms-eas.txt';
const TITLE_EAS = 'Expo Application Services (EAS) Documentation';
const DESCRIPTION_EAS =
'Expo Application Services (EAS) are deeply integrated cloud services for Expo and React Native apps, from the team behind Expo.';

function generateFullMarkdown({ title, description, sections }) {
return `# ${title}\n\n${description}\n\n` + sections.map(generateSectionMarkdown).join('');
}

function formatEasCliDescription(description) {
if (!description) {
return '';
}
const normalized = description.trim();
if (!normalized) {
return '';
}
const prefixed = /^[A-Z]/.test(normalized)
? normalized
: normalized[0].toUpperCase() + normalized.slice(1);
return prefixed.endsWith('.') ? prefixed : `${prefixed}.`;
}

function generateEasCliCommandsMarkdown(data) {
if (!data?.commands?.length) {
return '';
}
function generateFullMarkdown({ title, description }) {
const buildDir = ensureBuildOutputDir();
const allHrefs = uniqueInternalHrefs(collectPageHrefs(eas));
const markdownPaths = allHrefs.map(href => getMarkdownPathFromHref(buildDir, href));
const contentChunks = readUniqueMarkdownContent(markdownPaths, { warnOnMissing: true });

const cliVersion = data?.source?.cliVersion;
const header = cliVersion ? `# EAS CLI commands (v${cliVersion})` : '# EAS CLI commands';

const commands = data.commands
.map(command => {
const description = formatEasCliDescription(command.description);
const usage = command.usage?.trim();

let content = `## ${command.command}\n\n`;
if (description) {
content += `${description}\n\n`;
}
if (usage) {
content += '```\n' + usage + '\n```\n\n';
}
return content;
})
.join('');

return `${header}\n\n${commands}`.trimEnd();
return composeMarkdownDocument({ title, description, contentChunks });
}

export async function generateLlmsEasTxt() {
try {
const sections = eas.map(section => ({ ...processSection(section), category: 'Eas' }));

const easCliMarkdown = generateEasCliCommandsMarkdown(easCliData);
const baseContent = generateFullMarkdown({
title: TITLE_EAS,
description: DESCRIPTION_EAS,
sections,
});

const placeholderRegex = /<EASCLIReference\s*\/>/g;
let finalContent = easCliMarkdown
? baseContent.replace(placeholderRegex, `\n${easCliMarkdown}\n`)
: baseContent.replace(placeholderRegex, '');

if (easCliMarkdown && finalContent === baseContent) {
finalContent = `${baseContent.replace(placeholderRegex, '')}\n\n${easCliMarkdown}`;
}

await fs.promises.writeFile(
path.join(process.cwd(), OUTPUT_DIRECTORY_NAME, OUTPUT_FILENAME_EAS_DOCS),
finalContent
generateFullMarkdown({
title: TITLE_EAS,
description: DESCRIPTION_EAS,
})
);

console.log(` \x1b[1m\x1b[32m✓\x1b[0m Successfully generated ${OUTPUT_FILENAME_EAS_DOCS}`);
Expand Down
Loading
Loading