mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
changes
This commit is contained in:
parent
019f99c956
commit
b1494e8a1d
7 changed files with 153 additions and 95 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check if the correct number of arguments are provided
|
# Check if the correct number of arguments are provided
|
||||||
if [ "$#" -ne 2 ]; then
|
if [ "$#" -ne 1 ]; then
|
||||||
echo "Usage: $0 <runtimeVersion> <xavia-ota-url>"
|
echo "Usage: $0 <xavia-ota-url>"
|
||||||
|
echo "Example: $0 https://grim-reyna-tapframe-69970143.koyeb.app"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -10,52 +11,150 @@ fi
|
||||||
commitHash=$(git rev-parse HEAD)
|
commitHash=$(git rev-parse HEAD)
|
||||||
commitMessage=$(git log -1 --pretty=%B)
|
commitMessage=$(git log -1 --pretty=%B)
|
||||||
|
|
||||||
|
# Check if app.json exists
|
||||||
|
if [ ! -f "app.json" ]; then
|
||||||
|
echo "Error: app.json not found in current directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Auto-detect runtime version from app.json
|
||||||
|
runtimeVersion=$(jq -r '.expo.runtimeVersion' app.json)
|
||||||
|
if [ "$runtimeVersion" = "null" ] || [ -z "$runtimeVersion" ]; then
|
||||||
|
echo "Error: Could not find runtimeVersion in app.json"
|
||||||
|
echo "Please ensure app.json contains: \"runtimeVersion\": \"your-version\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Assign arguments to variables
|
# Assign arguments to variables
|
||||||
runtimeVersion=$1
|
serverHost=$1
|
||||||
serverHost=$2
|
|
||||||
|
# Validate server URL format
|
||||||
|
if [[ ! "$serverHost" =~ ^https?:// ]]; then
|
||||||
|
echo "Error: Server URL must start with http:// or https://"
|
||||||
|
echo "Example: https://grim-reyna-tapframe-69970143.koyeb.app"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Generate a timestamp for the output folder
|
# Generate a timestamp for the output folder
|
||||||
timestamp=$(date -u +%Y%m%d%H%M%S)
|
timestamp=$(date -u +%Y%m%d%H%M%S)
|
||||||
outputFolder="ota-builds/$timestamp"
|
outputFolder="ota-builds/$timestamp"
|
||||||
|
|
||||||
# Ask the user to confirm the hash, commit message, runtime version, and output folder
|
# Display build information
|
||||||
echo "Output Folder: $outputFolder"
|
echo "🚀 Nuvio OTA Build & Deploy Script"
|
||||||
echo "Runtime Version: $runtimeVersion"
|
echo "=================================="
|
||||||
echo "Commit Hash: $commitHash"
|
echo "📁 Output Folder: $outputFolder"
|
||||||
echo "Commit Message: $commitMessage"
|
echo "📱 Runtime Version: $runtimeVersion"
|
||||||
|
echo "🔗 Commit Hash: $commitHash"
|
||||||
|
echo "📝 Commit Message: $commitMessage"
|
||||||
|
echo "🌐 Server URL: $serverHost"
|
||||||
|
echo ""
|
||||||
|
|
||||||
read -p "Do you want to proceed with these values? (y/n): " confirm
|
read -p "Do you want to proceed with these values? (y/n): " confirm
|
||||||
|
|
||||||
if [ "$confirm" != "y" ]; then
|
if [ "$confirm" != "y" ]; then
|
||||||
echo "Operation cancelled by the user."
|
echo "❌ Operation cancelled by the user."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "🔨 Starting build process..."
|
||||||
|
|
||||||
|
# Clean up any existing output folder
|
||||||
rm -rf $outputFolder
|
rm -rf $outputFolder
|
||||||
mkdir -p $outputFolder
|
mkdir -p $outputFolder
|
||||||
|
|
||||||
# Run expo export with the specified output folder
|
# Run expo export with the specified output folder
|
||||||
npx expo export --output-dir $outputFolder
|
echo "📦 Exporting Expo bundle..."
|
||||||
|
if ! npx expo export --output-dir $outputFolder; then
|
||||||
|
echo "❌ Error: Expo export failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Extract expo config property from app.json and save to expoconfig.json
|
# Extract expo config property from app.json and save to expoconfig.json
|
||||||
|
echo "⚙️ Extracting Expo configuration..."
|
||||||
jq '.expo' app.json > $outputFolder/expoconfig.json
|
jq '.expo' app.json > $outputFolder/expoconfig.json
|
||||||
|
|
||||||
|
|
||||||
# Zip the output folder
|
# Zip the output folder
|
||||||
|
echo "📦 Creating deployment package..."
|
||||||
cd $outputFolder
|
cd $outputFolder
|
||||||
zip -q -r ${timestamp}.zip .
|
if ! zip -q -r ${timestamp}.zip .; then
|
||||||
|
echo "❌ Error: Failed to create zip file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Upload the zip file to the server
|
# Upload the zip file to the server
|
||||||
curl -X POST $serverHost/api/upload -F "file=@${timestamp}.zip" -F "runtimeVersion=$runtimeVersion" -F "commitHash=$commitHash" -F "commitMessage=$commitMessage"
|
echo "🚀 Uploading to server..."
|
||||||
|
echo "📊 File size: $(du -h ${timestamp}.zip | cut -f1)"
|
||||||
|
|
||||||
|
# Check server health before upload
|
||||||
|
echo "🔍 Checking server status..."
|
||||||
|
if ! curl --max-time 10 --connect-timeout 5 -s -o /dev/null "$serverHost/api/manifest"; then
|
||||||
|
echo "⚠️ Warning: Server may be slow or unresponsive"
|
||||||
|
echo "💡 Proceeding with upload anyway..."
|
||||||
|
else
|
||||||
|
echo "✅ Server is responding"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "Uploaded to $serverHost/api/upload"
|
# Try upload with extended timeout and retry logic
|
||||||
|
max_retries=3
|
||||||
|
retry_count=0
|
||||||
|
|
||||||
|
while [ $retry_count -lt $max_retries ]; do
|
||||||
|
echo "🔄 Upload attempt $((retry_count + 1))/$max_retries..."
|
||||||
|
|
||||||
|
response=$(curl --max-time 300 --connect-timeout 30 -X POST $serverHost/api/upload \
|
||||||
|
-F "file=@${timestamp}.zip" \
|
||||||
|
-F "runtimeVersion=$runtimeVersion" \
|
||||||
|
-F "commitHash=$commitHash" \
|
||||||
|
-F "commitMessage=$commitMessage" \
|
||||||
|
--write-out "HTTP_CODE:%{http_code}" \
|
||||||
|
--silent \
|
||||||
|
--show-error)
|
||||||
|
|
||||||
|
# Extract HTTP code from response
|
||||||
|
http_code=$(echo "$response" | grep -o "HTTP_CODE:[0-9]*" | cut -d: -f2)
|
||||||
|
|
||||||
|
# Check if we got a valid HTTP code
|
||||||
|
if [ -z "$http_code" ] || ! [[ "$http_code" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "❌ Failed to extract HTTP status code from response"
|
||||||
|
echo "Response: $response"
|
||||||
|
http_code="000"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "HTTP Status: $http_code"
|
||||||
|
|
||||||
|
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "✅ Successfully uploaded to $serverHost/api/upload"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
retry_count=$((retry_count + 1))
|
||||||
|
if [ $retry_count -lt $max_retries ]; then
|
||||||
|
echo "⚠️ Upload attempt $retry_count failed, retrying in 5 seconds..."
|
||||||
|
sleep 5
|
||||||
|
else
|
||||||
|
echo "❌ Error: Upload failed after $max_retries attempts"
|
||||||
|
echo "📊 Final HTTP Status: $http_code"
|
||||||
|
if [ "$http_code" = "524" ]; then
|
||||||
|
echo "💡 Error 524: Server timeout - try again later or check server capacity"
|
||||||
|
elif [ "$http_code" = "413" ]; then
|
||||||
|
echo "💡 Error 413: File too large - consider reducing bundle size"
|
||||||
|
elif [ "$http_code" = "500" ]; then
|
||||||
|
echo "💡 Error 500: Server error - check server logs"
|
||||||
|
else
|
||||||
|
echo "💡 Check server status and try again"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
# Remove the output folder and zip file
|
# Remove the output folder and zip file
|
||||||
|
echo "🧹 Cleaning up temporary files..."
|
||||||
rm -rf $outputFolder
|
rm -rf $outputFolder
|
||||||
|
|
||||||
echo "Removed $outputFolder"
|
echo "🎉 Build and deployment completed successfully!"
|
||||||
echo "Done"
|
echo "📱 Runtime Version: $runtimeVersion"
|
||||||
|
echo "🔗 Commit: $commitHash"
|
||||||
|
|
|
||||||
7
manifest_response.json
Normal file
7
manifest_response.json
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
----------------------------568300859475270590089014
|
||||||
|
Content-Disposition: form-data; name="directive"
|
||||||
|
Content-Type: application/json
|
||||||
|
content-type: application/json; charset=utf-8
|
||||||
|
|
||||||
|
{"type":"noUpdateAvailable"}
|
||||||
|
----------------------------568300859475270590089014--
|
||||||
7
manifest_response_old.json
Normal file
7
manifest_response_old.json
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
----------------------------694338510290346396309710
|
||||||
|
Content-Disposition: form-data; name="directive"
|
||||||
|
Content-Type: application/json
|
||||||
|
content-type: application/json; charset=utf-8
|
||||||
|
|
||||||
|
{"type":"noUpdateAvailable"}
|
||||||
|
----------------------------694338510290346396309710--
|
||||||
|
|
@ -72,7 +72,7 @@ const UpdatePopup: React.FC<UpdatePopupProps> = ({
|
||||||
<View style={[
|
<View style={[
|
||||||
styles.popup,
|
styles.popup,
|
||||||
{
|
{
|
||||||
backgroundColor: currentTheme.colors.elevation1 || '#1a1a1a',
|
backgroundColor: currentTheme.colors.darkBackground || '#1a1a1a',
|
||||||
borderColor: currentTheme.colors.elevation2 || '#333333',
|
borderColor: currentTheme.colors.elevation2 || '#333333',
|
||||||
marginTop: insets.top + 20,
|
marginTop: insets.top + 20,
|
||||||
marginBottom: insets.bottom + 20,
|
marginBottom: insets.bottom + 20,
|
||||||
|
|
@ -173,8 +173,8 @@ const UpdatePopup: React.FC<UpdatePopupProps> = ({
|
||||||
styles.button,
|
styles.button,
|
||||||
styles.secondaryButton,
|
styles.secondaryButton,
|
||||||
{
|
{
|
||||||
backgroundColor: currentTheme.colors.elevation2,
|
backgroundColor: currentTheme.colors.darkBackground || '#2a2a2a',
|
||||||
borderColor: currentTheme.colors.elevation3,
|
borderColor: currentTheme.colors.elevation3 || '#444444',
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onPress={handleUpdateLater}
|
onPress={handleUpdateLater}
|
||||||
|
|
@ -194,8 +194,8 @@ const UpdatePopup: React.FC<UpdatePopupProps> = ({
|
||||||
styles.button,
|
styles.button,
|
||||||
styles.secondaryButton,
|
styles.secondaryButton,
|
||||||
{
|
{
|
||||||
backgroundColor: currentTheme.colors.elevation2,
|
backgroundColor: currentTheme.colors.darkBackground || '#2a2a2a',
|
||||||
borderColor: currentTheme.colors.elevation3,
|
borderColor: currentTheme.colors.elevation3 || '#444444',
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onPress={handleDismiss}
|
onPress={handleDismiss}
|
||||||
|
|
@ -239,7 +239,7 @@ const styles = StyleSheet.create({
|
||||||
width: Math.min(width - 40, 400),
|
width: Math.min(width - 40, 400),
|
||||||
borderRadius: 20,
|
borderRadius: 20,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
backgroundColor: '#1a1a1a', // Fallback solid background
|
backgroundColor: '#1a1a1a', // Solid background - not transparent
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 10 },
|
shadowOffset: { width: 0, height: 10 },
|
||||||
shadowOpacity: 0.5,
|
shadowOpacity: 0.5,
|
||||||
|
|
@ -297,7 +297,7 @@ const styles = StyleSheet.create({
|
||||||
marginTop: 8,
|
marginTop: 8,
|
||||||
padding: 12,
|
padding: 12,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
backgroundColor: 'rgba(255, 255, 255, 0.15)',
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ const createStyles = (colors: any) => StyleSheet.create({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
section: {
|
section: {
|
||||||
backgroundColor: colors.elevation1,
|
backgroundColor: colors.darkBackground,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
|
|
@ -181,7 +181,7 @@ const createStyles = (colors: any) => StyleSheet.create({
|
||||||
lineHeight: 20,
|
lineHeight: 20,
|
||||||
},
|
},
|
||||||
textInput: {
|
textInput: {
|
||||||
backgroundColor: colors.elevation1,
|
backgroundColor: colors.darkBackground,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
padding: 12,
|
padding: 12,
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
|
|
@ -369,7 +369,7 @@ const createStyles = (colors: any) => StyleSheet.create({
|
||||||
},
|
},
|
||||||
// New styles for improved UX
|
// New styles for improved UX
|
||||||
collapsibleSection: {
|
collapsibleSection: {
|
||||||
backgroundColor: colors.elevation1,
|
backgroundColor: colors.darkBackground,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
|
|
@ -392,7 +392,7 @@ const createStyles = (colors: any) => StyleSheet.create({
|
||||||
searchContainer: {
|
searchContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: colors.elevation1,
|
backgroundColor: colors.darkBackground,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
paddingHorizontal: 12,
|
paddingHorizontal: 12,
|
||||||
|
|
@ -489,7 +489,7 @@ const createStyles = (colors: any) => StyleSheet.create({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
modalContent: {
|
modalContent: {
|
||||||
backgroundColor: colors.elevation1,
|
backgroundColor: colors.darkBackground,
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
padding: 24,
|
padding: 24,
|
||||||
margin: 20,
|
margin: 20,
|
||||||
|
|
@ -750,10 +750,7 @@ const PluginsScreen: React.FC = () => {
|
||||||
const [currentRepositoryId, setCurrentRepositoryId] = useState<string>('');
|
const [currentRepositoryId, setCurrentRepositoryId] = useState<string>('');
|
||||||
const [showAddRepositoryModal, setShowAddRepositoryModal] = useState(false);
|
const [showAddRepositoryModal, setShowAddRepositoryModal] = useState(false);
|
||||||
const [newRepositoryUrl, setNewRepositoryUrl] = useState('');
|
const [newRepositoryUrl, setNewRepositoryUrl] = useState('');
|
||||||
const [newRepositoryName, setNewRepositoryName] = useState('');
|
|
||||||
const [newRepositoryDescription, setNewRepositoryDescription] = useState('');
|
|
||||||
const [switchingRepository, setSwitchingRepository] = useState<string | null>(null);
|
const [switchingRepository, setSwitchingRepository] = useState<string | null>(null);
|
||||||
const [fetchingRepoName, setFetchingRepoName] = useState(false);
|
|
||||||
|
|
||||||
// New UX state
|
// New UX state
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
|
|
@ -837,29 +834,8 @@ const PluginsScreen: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUrlChange = async (url: string) => {
|
const handleUrlChange = (url: string) => {
|
||||||
setNewRepositoryUrl(url);
|
setNewRepositoryUrl(url);
|
||||||
// Auto-populate repository name if it's empty and URL is valid
|
|
||||||
if (!newRepositoryName.trim() && url.trim()) {
|
|
||||||
setFetchingRepoName(true);
|
|
||||||
try {
|
|
||||||
// Try to fetch name from manifest first
|
|
||||||
const manifestName = await localScraperService.fetchRepositoryNameFromManifest(url.trim());
|
|
||||||
setNewRepositoryName(manifestName);
|
|
||||||
} catch (error) {
|
|
||||||
// Fallback to URL extraction if manifest fetch fails
|
|
||||||
try {
|
|
||||||
const extractedName = localScraperService.extractRepositoryName(url.trim());
|
|
||||||
if (extractedName !== 'Unknown Repository') {
|
|
||||||
setNewRepositoryName(extractedName);
|
|
||||||
}
|
|
||||||
} catch (extractError) {
|
|
||||||
// Ignore errors, just don't auto-populate
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
setFetchingRepoName(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddRepository = async () => {
|
const handleAddRepository = async () => {
|
||||||
|
|
@ -873,7 +849,7 @@ const PluginsScreen: React.FC = () => {
|
||||||
if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) {
|
if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'Invalid URL Format',
|
'Invalid URL Format',
|
||||||
'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/branch/\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/main/'
|
'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/master'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -881,9 +857,9 @@ const PluginsScreen: React.FC = () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const repoId = await localScraperService.addRepository({
|
const repoId = await localScraperService.addRepository({
|
||||||
name: newRepositoryName.trim(), // Let the service fetch from manifest if empty
|
name: '', // Let the service fetch from manifest
|
||||||
url,
|
url,
|
||||||
description: newRepositoryDescription.trim(),
|
description: '',
|
||||||
enabled: true
|
enabled: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -895,9 +871,6 @@ const PluginsScreen: React.FC = () => {
|
||||||
await loadScrapers();
|
await loadScrapers();
|
||||||
|
|
||||||
setNewRepositoryUrl('');
|
setNewRepositoryUrl('');
|
||||||
setNewRepositoryName('');
|
|
||||||
setNewRepositoryDescription('');
|
|
||||||
setFetchingRepoName(false);
|
|
||||||
setShowAddRepositoryModal(false);
|
setShowAddRepositoryModal(false);
|
||||||
Alert.alert('Success', 'Repository added and refreshed successfully');
|
Alert.alert('Success', 'Repository added and refreshed successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -1016,7 +989,7 @@ const PluginsScreen: React.FC = () => {
|
||||||
if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) {
|
if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'Invalid URL Format',
|
'Invalid URL Format',
|
||||||
'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/branch/\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/main/'
|
'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/master'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1051,7 +1024,7 @@ const PluginsScreen: React.FC = () => {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'Repository Error',
|
'Repository Error',
|
||||||
`Failed to refresh repository: ${errorMessage}\n\nPlease ensure your URL is correct and follows this format:\nhttps://raw.githubusercontent.com/username/repo/branch/`
|
`Failed to refresh repository: ${errorMessage}\n\nPlease ensure your URL is correct and follows this format:\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch`
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
|
|
@ -1135,7 +1108,7 @@ const PluginsScreen: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUseDefaultRepo = () => {
|
const handleUseDefaultRepo = () => {
|
||||||
const defaultUrl = 'https://raw.githubusercontent.com/tapframe/nuvio-providers/main';
|
const defaultUrl = 'https://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/master';
|
||||||
setRepositoryUrl(defaultUrl);
|
setRepositoryUrl(defaultUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1731,53 +1704,24 @@ const PluginsScreen: React.FC = () => {
|
||||||
<View style={styles.modalContent}>
|
<View style={styles.modalContent}>
|
||||||
<Text style={styles.modalTitle}>Add New Repository</Text>
|
<Text style={styles.modalTitle}>Add New Repository</Text>
|
||||||
|
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 8 }}>
|
|
||||||
<Text style={styles.settingTitle}>Repository Name</Text>
|
|
||||||
{fetchingRepoName && (
|
|
||||||
<ActivityIndicator size="small" color={colors.primary} style={{ marginLeft: 8 }} />
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<TextInput
|
|
||||||
style={styles.textInput}
|
|
||||||
value={newRepositoryName}
|
|
||||||
onChangeText={setNewRepositoryName}
|
|
||||||
placeholder="Enter repository name"
|
|
||||||
placeholderTextColor={colors.mediumGray}
|
|
||||||
autoCapitalize="words"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Text style={[styles.settingTitle, { marginBottom: 8 }]}>Repository URL</Text>
|
<Text style={[styles.settingTitle, { marginBottom: 8 }]}>Repository URL</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.textInput}
|
style={styles.textInput}
|
||||||
value={newRepositoryUrl}
|
value={newRepositoryUrl}
|
||||||
onChangeText={handleUrlChange}
|
onChangeText={handleUrlChange}
|
||||||
placeholder="https://raw.githubusercontent.com/username/repo/branch/"
|
placeholder="https://raw.githubusercontent.com/username/repo/refs/heads/branch"
|
||||||
placeholderTextColor={colors.mediumGray}
|
placeholderTextColor={colors.mediumGray}
|
||||||
autoCapitalize="none"
|
autoCapitalize="none"
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
keyboardType="url"
|
keyboardType="url"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text style={[styles.settingTitle, { marginBottom: 8 }]}>Description (Optional)</Text>
|
|
||||||
<TextInput
|
|
||||||
style={[styles.textInput, { height: 80 }]}
|
|
||||||
value={newRepositoryDescription}
|
|
||||||
onChangeText={setNewRepositoryDescription}
|
|
||||||
placeholder="Enter repository description"
|
|
||||||
placeholderTextColor={colors.mediumGray}
|
|
||||||
multiline={true}
|
|
||||||
numberOfLines={3}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<View style={styles.buttonRow}>
|
<View style={styles.buttonRow}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.button, styles.secondaryButton, { flex: 1 }]}
|
style={[styles.button, styles.secondaryButton, { flex: 1 }]}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setShowAddRepositoryModal(false);
|
setShowAddRepositoryModal(false);
|
||||||
setNewRepositoryUrl('');
|
setNewRepositoryUrl('');
|
||||||
setNewRepositoryName('');
|
|
||||||
setNewRepositoryDescription('');
|
|
||||||
setFetchingRepoName(false);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text style={styles.secondaryButtonText}>Cancel</Text>
|
<Text style={styles.secondaryButtonText}>Cancel</Text>
|
||||||
|
|
|
||||||
|
|
@ -410,6 +410,7 @@ const UpdateScreen: React.FC = () => {
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit ba2fe779d75a8ed285c5d37f05532c3ff4acce22
|
Subproject commit ef5455acaa04404d816a6bffc25a259e28189918
|
||||||
Loading…
Reference in a new issue