mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-05 01:39:08 +00:00
small UI changes
This commit is contained in:
parent
a877f5ac13
commit
f86e6256a7
8 changed files with 312 additions and 18 deletions
13
App.tsx
13
App.tsx
|
|
@ -29,6 +29,8 @@ import { ThemeProvider, useTheme } from './src/contexts/ThemeContext';
|
||||||
import { TrailerProvider } from './src/contexts/TrailerContext';
|
import { TrailerProvider } from './src/contexts/TrailerContext';
|
||||||
import SplashScreen from './src/components/SplashScreen';
|
import SplashScreen from './src/components/SplashScreen';
|
||||||
import UpdatePopup from './src/components/UpdatePopup';
|
import UpdatePopup from './src/components/UpdatePopup';
|
||||||
|
import MajorUpdateOverlay from './src/components/MajorUpdateOverlay';
|
||||||
|
import { useGithubMajorUpdate } from './src/hooks/useGithubMajorUpdate';
|
||||||
import { useUpdatePopup } from './src/hooks/useUpdatePopup';
|
import { useUpdatePopup } from './src/hooks/useUpdatePopup';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import * as Sentry from '@sentry/react-native';
|
import * as Sentry from '@sentry/react-native';
|
||||||
|
|
@ -85,6 +87,9 @@ const ThemedApp = () => {
|
||||||
handleDismiss,
|
handleDismiss,
|
||||||
} = useUpdatePopup();
|
} = useUpdatePopup();
|
||||||
|
|
||||||
|
// GitHub major/minor release overlay
|
||||||
|
const githubUpdate = useGithubMajorUpdate();
|
||||||
|
|
||||||
// Check onboarding status and initialize services
|
// Check onboarding status and initialize services
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializeApp = async () => {
|
const initializeApp = async () => {
|
||||||
|
|
@ -165,6 +170,14 @@ const ThemedApp = () => {
|
||||||
isInstalling={isInstalling}
|
isInstalling={isInstalling}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<MajorUpdateOverlay
|
||||||
|
visible={githubUpdate.visible}
|
||||||
|
latestTag={githubUpdate.latestTag}
|
||||||
|
releaseNotes={githubUpdate.releaseNotes}
|
||||||
|
releaseUrl={githubUpdate.releaseUrl}
|
||||||
|
onDismiss={githubUpdate.onDismiss}
|
||||||
|
onLater={githubUpdate.onLater}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
</PaperProvider>
|
</PaperProvider>
|
||||||
|
|
|
||||||
84
src/components/MajorUpdateOverlay.tsx
Normal file
84
src/components/MajorUpdateOverlay.tsx
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Modal, View, Text, StyleSheet, TouchableOpacity, Linking } from 'react-native';
|
||||||
|
import { MaterialIcons } from '@expo/vector-icons';
|
||||||
|
import { useTheme } from '../contexts/ThemeContext';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean;
|
||||||
|
latestTag?: string;
|
||||||
|
releaseNotes?: string;
|
||||||
|
releaseUrl?: string;
|
||||||
|
onDismiss: () => void;
|
||||||
|
onLater: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MajorUpdateOverlay: React.FC<Props> = ({ visible, latestTag, releaseNotes, releaseUrl, onDismiss, onLater }) => {
|
||||||
|
const { currentTheme } = useTheme();
|
||||||
|
|
||||||
|
if (!visible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal visible={visible} transparent animationType="fade" statusBarTranslucent presentationStyle="overFullScreen">
|
||||||
|
<View style={styles.backdrop}>
|
||||||
|
<View style={[styles.card, { backgroundColor: currentTheme.colors.darkBackground, borderColor: currentTheme.colors.elevation3 }]}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<View style={[styles.iconCircle, { backgroundColor: `${currentTheme.colors.primary}22` }]}>
|
||||||
|
<MaterialIcons name="new-releases" size={28} color={currentTheme.colors.primary} />
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.title, { color: currentTheme.colors.highEmphasis }]}>Major update available</Text>
|
||||||
|
{!!latestTag && (
|
||||||
|
<Text style={[styles.version, { color: currentTheme.colors.mediumEmphasis }]}>Latest: {latestTag}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{!!releaseNotes && (
|
||||||
|
<View style={styles.notesBox}>
|
||||||
|
<Text style={[styles.notes, { color: currentTheme.colors.mediumEmphasis }]} numberOfLines={10}>
|
||||||
|
{releaseNotes}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<View style={styles.actions}>
|
||||||
|
{releaseUrl ? (
|
||||||
|
<TouchableOpacity style={[styles.primaryBtn, { backgroundColor: currentTheme.colors.primary }]} onPress={() => Linking.openURL(releaseUrl)}>
|
||||||
|
<MaterialIcons name="open-in-new" size={18} color="#fff" />
|
||||||
|
<Text style={styles.primaryText}>View release</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<View style={styles.secondaryRow}>
|
||||||
|
<TouchableOpacity style={[styles.secondaryBtn, { borderColor: currentTheme.colors.elevation3 }]} onPress={onLater}>
|
||||||
|
<Text style={[styles.secondaryText, { color: currentTheme.colors.mediumEmphasis }]}>Later</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={[styles.secondaryBtn, { borderColor: currentTheme.colors.elevation3 }]} onPress={onDismiss}>
|
||||||
|
<Text style={[styles.secondaryText, { color: currentTheme.colors.mediumEmphasis }]}>Dismiss</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
backdrop: { flex: 1, backgroundColor: 'rgba(0,0,0,0.8)', alignItems: 'center', justifyContent: 'center', padding: 20 },
|
||||||
|
card: { width: 380, maxWidth: '100%', borderRadius: 20, borderWidth: 1, overflow: 'hidden' },
|
||||||
|
header: { alignItems: 'center', paddingTop: 28, paddingBottom: 16, paddingHorizontal: 20 },
|
||||||
|
iconCircle: { width: 56, height: 56, borderRadius: 28, alignItems: 'center', justifyContent: 'center', marginBottom: 12 },
|
||||||
|
title: { fontSize: 20, fontWeight: '700', marginBottom: 6 },
|
||||||
|
version: { fontSize: 14 },
|
||||||
|
notesBox: { marginHorizontal: 20, marginBottom: 16, padding: 12, borderRadius: 12, backgroundColor: 'rgba(255,255,255,0.08)' },
|
||||||
|
notes: { fontSize: 14, lineHeight: 20 },
|
||||||
|
actions: { paddingHorizontal: 20, paddingBottom: 20 },
|
||||||
|
primaryBtn: { flexDirection: 'row', alignItems: 'center', gap: 8, justifyContent: 'center', paddingVertical: 12, borderRadius: 12, marginBottom: 12 },
|
||||||
|
primaryText: { color: '#fff', fontSize: 16, fontWeight: '600' },
|
||||||
|
secondaryRow: { flexDirection: 'row', gap: 10 },
|
||||||
|
secondaryBtn: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingVertical: 12, borderRadius: 12, borderWidth: 1 },
|
||||||
|
secondaryText: { fontSize: 15, fontWeight: '500' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MajorUpdateOverlay;
|
||||||
|
|
||||||
|
|
||||||
65
src/hooks/useGithubMajorUpdate.ts
Normal file
65
src/hooks/useGithubMajorUpdate.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
import * as Updates from 'expo-updates';
|
||||||
|
import { getDisplayedAppVersion } from '../utils/version';
|
||||||
|
import { fetchLatestGithubRelease, isAnyUpgrade } from '../services/githubReleaseService';
|
||||||
|
|
||||||
|
const DISMISSED_KEY = '@github_major_update_dismissed_version';
|
||||||
|
|
||||||
|
export interface MajorUpdateData {
|
||||||
|
visible: boolean;
|
||||||
|
latestTag?: string;
|
||||||
|
releaseNotes?: string;
|
||||||
|
releaseUrl?: string;
|
||||||
|
onDismiss: () => void;
|
||||||
|
onLater: () => void;
|
||||||
|
refresh: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useGithubMajorUpdate(): MajorUpdateData {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [latestTag, setLatestTag] = useState<string | undefined>();
|
||||||
|
const [releaseNotes, setReleaseNotes] = useState<string | undefined>();
|
||||||
|
const [releaseUrl, setReleaseUrl] = useState<string | undefined>();
|
||||||
|
|
||||||
|
const check = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
// Always compare with Settings screen version
|
||||||
|
const current = getDisplayedAppVersion() || Updates.runtimeVersion || '0.0.0';
|
||||||
|
const info = await fetchLatestGithubRelease();
|
||||||
|
if (!info?.tag_name) return;
|
||||||
|
|
||||||
|
const dismissed = await AsyncStorage.getItem(DISMISSED_KEY);
|
||||||
|
if (dismissed === info.tag_name) return;
|
||||||
|
|
||||||
|
// "Later" is session-only now, no persisted snooze
|
||||||
|
|
||||||
|
const shouldShow = isAnyUpgrade(current, info.tag_name);
|
||||||
|
if (shouldShow) {
|
||||||
|
setLatestTag(info.tag_name);
|
||||||
|
setReleaseNotes(info.body);
|
||||||
|
setReleaseUrl(info.html_url);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
check();
|
||||||
|
}, [check]);
|
||||||
|
|
||||||
|
const onDismiss = useCallback(async () => {
|
||||||
|
if (latestTag) await AsyncStorage.setItem(DISMISSED_KEY, latestTag);
|
||||||
|
setVisible(false);
|
||||||
|
}, [latestTag]);
|
||||||
|
|
||||||
|
const onLater = useCallback(async () => {
|
||||||
|
setVisible(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { visible, latestTag, releaseNotes, releaseUrl, onDismiss, onLater, refresh: check };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,6 +30,7 @@ import { useAccount } from '../contexts/AccountContext';
|
||||||
import { catalogService } from '../services/catalogService';
|
import { catalogService } from '../services/catalogService';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import * as Sentry from '@sentry/react-native';
|
import * as Sentry from '@sentry/react-native';
|
||||||
|
import { getDisplayedAppVersion } from '../utils/version';
|
||||||
import CustomAlert from '../components/CustomAlert';
|
import CustomAlert from '../components/CustomAlert';
|
||||||
import ProfileIcon from '../components/icons/ProfileIcon';
|
import ProfileIcon from '../components/icons/ProfileIcon';
|
||||||
import PluginIcon from '../components/icons/PluginIcon';
|
import PluginIcon from '../components/icons/PluginIcon';
|
||||||
|
|
@ -643,7 +644,7 @@ const SettingsScreen: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
<SettingItem
|
<SettingItem
|
||||||
title="Version"
|
title="Version"
|
||||||
description="1.2.1"
|
description={getDisplayedAppVersion()}
|
||||||
icon="info-outline"
|
icon="info-outline"
|
||||||
isLast={true}
|
isLast={true}
|
||||||
isTablet={isTablet}
|
isTablet={isTablet}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ import {
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
StatusBar,
|
StatusBar,
|
||||||
Platform,
|
Platform,
|
||||||
Dimensions
|
Dimensions,
|
||||||
|
Linking
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { toast, ToastPosition } from '@backpackapp-io/react-native-toast';
|
import { toast, ToastPosition } from '@backpackapp-io/react-native-toast';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
|
@ -20,6 +21,9 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import UpdateService from '../services/updateService';
|
import UpdateService from '../services/updateService';
|
||||||
import CustomAlert from '../components/CustomAlert';
|
import CustomAlert from '../components/CustomAlert';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
import { useGithubMajorUpdate } from '../hooks/useGithubMajorUpdate';
|
||||||
|
import { getDisplayedAppVersion } from '../utils/version';
|
||||||
|
import { isAnyUpgrade } from '../services/githubReleaseService';
|
||||||
|
|
||||||
const { width, height } = Dimensions.get('window');
|
const { width, height } = Dimensions.get('window');
|
||||||
const isTablet = width >= 768;
|
const isTablet = width >= 768;
|
||||||
|
|
@ -65,6 +69,7 @@ const UpdateScreen: React.FC = () => {
|
||||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||||
const { currentTheme } = useTheme();
|
const { currentTheme } = useTheme();
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
|
const github = useGithubMajorUpdate();
|
||||||
|
|
||||||
// CustomAlert state
|
// CustomAlert state
|
||||||
const [alertVisible, setAlertVisible] = useState(false);
|
const [alertVisible, setAlertVisible] = useState(false);
|
||||||
|
|
@ -144,6 +149,8 @@ const UpdateScreen: React.FC = () => {
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
checkForUpdates();
|
checkForUpdates();
|
||||||
|
// Also refresh GitHub section on mount (works in dev and prod)
|
||||||
|
try { github.refresh(); } catch {}
|
||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
try {
|
try {
|
||||||
toast('Checking for updates…', { duration: 1200, position: ToastPosition.TOP });
|
toast('Checking for updates…', { duration: 1200, position: ToastPosition.TOP });
|
||||||
|
|
@ -517,6 +524,58 @@ const UpdateScreen: React.FC = () => {
|
||||||
{/* Developer Logs removed */}
|
{/* Developer Logs removed */}
|
||||||
</SettingsCard>
|
</SettingsCard>
|
||||||
|
|
||||||
|
{/* GitHub Release (compact) – only show when update is available */}
|
||||||
|
{github.latestTag && isAnyUpgrade(getDisplayedAppVersion(), github.latestTag) ? (
|
||||||
|
<SettingsCard title="GITHUB RELEASE" isTablet={isTablet}>
|
||||||
|
<View style={styles.infoSection}>
|
||||||
|
<View style={styles.infoItem}>
|
||||||
|
<View style={[styles.infoIcon, { backgroundColor: `${currentTheme.colors.primary}15` }]}>
|
||||||
|
<MaterialIcons name="new-releases" size={14} color={currentTheme.colors.primary} />
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Current:</Text>
|
||||||
|
<Text style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}>
|
||||||
|
{getDisplayedAppVersion()}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.infoItem}>
|
||||||
|
<View style={[styles.infoIcon, { backgroundColor: `${currentTheme.colors.primary}15` }]}>
|
||||||
|
<MaterialIcons name="tag" size={14} color={currentTheme.colors.primary} />
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Latest:</Text>
|
||||||
|
<Text style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}>
|
||||||
|
{github.latestTag}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{github.releaseNotes ? (
|
||||||
|
<View style={{ marginTop: 4 }}>
|
||||||
|
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Notes:</Text>
|
||||||
|
<Text
|
||||||
|
numberOfLines={3}
|
||||||
|
style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}
|
||||||
|
>
|
||||||
|
{github.releaseNotes}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<View style={[styles.actionSection, { marginTop: 8 }]}>
|
||||||
|
<View style={{ flexDirection: 'row', gap: 10 }}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.modernButton, { backgroundColor: currentTheme.colors.primary, flex: 1 }]}
|
||||||
|
onPress={() => github.releaseUrl ? Linking.openURL(github.releaseUrl as string) : null}
|
||||||
|
activeOpacity={0.8}
|
||||||
|
>
|
||||||
|
<MaterialIcons name="open-in-new" size={18} color="white" />
|
||||||
|
<Text style={styles.modernButtonText}>View Release</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</SettingsCard>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{false && (
|
{false && (
|
||||||
<SettingsCard title="UPDATE LOGS" isTablet={isTablet}>
|
<SettingsCard title="UPDATE LOGS" isTablet={isTablet}>
|
||||||
<View style={styles.logsContainer}>
|
<View style={styles.logsContainer}>
|
||||||
|
|
|
||||||
62
src/services/githubReleaseService.ts
Normal file
62
src/services/githubReleaseService.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
|
export interface GithubReleaseInfo {
|
||||||
|
tag_name: string;
|
||||||
|
name?: string;
|
||||||
|
body?: string;
|
||||||
|
html_url?: string;
|
||||||
|
published_at?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GITHUB_LATEST_RELEASE_URL = 'https://api.github.com/repos/tapframe/NuvioStreaming/releases/latest';
|
||||||
|
|
||||||
|
export async function fetchLatestGithubRelease(): Promise<GithubReleaseInfo | null> {
|
||||||
|
try {
|
||||||
|
const res = await fetch(GITHUB_LATEST_RELEASE_URL, {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/vnd.github+json',
|
||||||
|
// Identify app a bit; avoid user agent blocks
|
||||||
|
'User-Agent': `Nuvio/${Platform.OS}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!res.ok) return null;
|
||||||
|
const json = await res.json();
|
||||||
|
return {
|
||||||
|
tag_name: json.tag_name,
|
||||||
|
name: json.name,
|
||||||
|
body: json.body,
|
||||||
|
html_url: json.html_url,
|
||||||
|
published_at: json.published_at,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseSemver(version: string): [number, number, number] | null {
|
||||||
|
const m = version.trim().replace(/^v/, '').match(/^(\d+)\.(\d+)\.(\d+)/);
|
||||||
|
if (!m) return null;
|
||||||
|
return [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10)];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMajorOrMinorUpgrade(current: string, latest: string): boolean {
|
||||||
|
const a = parseSemver(current);
|
||||||
|
const b = parseSemver(latest);
|
||||||
|
if (!a || !b) return false;
|
||||||
|
// Major or minor bump when (b.major > a.major) or (same major and b.minor > a.minor)
|
||||||
|
if (b[0] > a[0]) return true;
|
||||||
|
if (b[0] === a[0] && b[1] > a[1]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if latest > current for semver including patch
|
||||||
|
export function isAnyUpgrade(current: string, latest: string): boolean {
|
||||||
|
const a = parseSemver(current);
|
||||||
|
const b = parseSemver(latest);
|
||||||
|
if (!a || !b) return false;
|
||||||
|
if (b[0] !== a[0]) return b[0] > a[0];
|
||||||
|
if (b[1] !== a[1]) return b[1] > a[1];
|
||||||
|
return b[2] > a[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
10
src/utils/version.ts
Normal file
10
src/utils/version.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Single source of truth for the app version displayed in Settings
|
||||||
|
// Update this when bumping app version
|
||||||
|
|
||||||
|
export const APP_VERSION = '1.2.1';
|
||||||
|
|
||||||
|
export function getDisplayedAppVersion(): string {
|
||||||
|
return APP_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Version Update Script for Nuvio App
|
# Version Update Script for Nuvio App
|
||||||
# Updates version across app.json, SettingsScreen.tsx, and iOS Info.plist
|
# Updates version across app.json, src/utils/version.ts, and iOS/Android build files
|
||||||
|
|
||||||
set -e # Exit on any error
|
set -e # Exit on any error
|
||||||
|
|
||||||
|
|
@ -56,12 +56,12 @@ fi
|
||||||
|
|
||||||
# File paths
|
# File paths
|
||||||
APP_JSON="./app.json"
|
APP_JSON="./app.json"
|
||||||
SETTINGS_SCREEN="./src/screens/SettingsScreen.tsx"
|
VERSION_TS="./src/utils/version.ts"
|
||||||
INFO_PLIST="./ios/Nuvio/Info.plist"
|
INFO_PLIST="./ios/Nuvio/Info.plist"
|
||||||
ANDROID_BUILD_GRADLE="./android/app/build.gradle"
|
ANDROID_BUILD_GRADLE="./android/app/build.gradle"
|
||||||
|
|
||||||
# Check if files exist
|
# Check if files exist
|
||||||
for file in "$APP_JSON" "$SETTINGS_SCREEN" "$INFO_PLIST" "$ANDROID_BUILD_GRADLE"; do
|
for file in "$APP_JSON" "$VERSION_TS" "$INFO_PLIST" "$ANDROID_BUILD_GRADLE"; do
|
||||||
if [ ! -f "$file" ]; then
|
if [ ! -f "$file" ]; then
|
||||||
print_error "File not found: $file"
|
print_error "File not found: $file"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -88,7 +88,7 @@ print_status "New build number: $NEW_BUILD_NUMBER"
|
||||||
# Backup files
|
# Backup files
|
||||||
print_status "Creating backups..."
|
print_status "Creating backups..."
|
||||||
cp "$APP_JSON" "${APP_JSON}.backup"
|
cp "$APP_JSON" "${APP_JSON}.backup"
|
||||||
cp "$SETTINGS_SCREEN" "${SETTINGS_SCREEN}.backup"
|
cp "$VERSION_TS" "${VERSION_TS}.backup"
|
||||||
cp "$INFO_PLIST" "${INFO_PLIST}.backup"
|
cp "$INFO_PLIST" "${INFO_PLIST}.backup"
|
||||||
cp "$ANDROID_BUILD_GRADLE" "${ANDROID_BUILD_GRADLE}.backup"
|
cp "$ANDROID_BUILD_GRADLE" "${ANDROID_BUILD_GRADLE}.backup"
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ cp "$ANDROID_BUILD_GRADLE" "${ANDROID_BUILD_GRADLE}.backup"
|
||||||
restore_backups() {
|
restore_backups() {
|
||||||
print_warning "Restoring backups due to error..."
|
print_warning "Restoring backups due to error..."
|
||||||
mv "${APP_JSON}.backup" "$APP_JSON"
|
mv "${APP_JSON}.backup" "$APP_JSON"
|
||||||
mv "${SETTINGS_SCREEN}.backup" "$SETTINGS_SCREEN"
|
mv "${VERSION_TS}.backup" "$VERSION_TS"
|
||||||
mv "${INFO_PLIST}.backup" "$INFO_PLIST"
|
mv "${INFO_PLIST}.backup" "$INFO_PLIST"
|
||||||
mv "${ANDROID_BUILD_GRADLE}.backup" "$ANDROID_BUILD_GRADLE"
|
mv "${ANDROID_BUILD_GRADLE}.backup" "$ANDROID_BUILD_GRADLE"
|
||||||
}
|
}
|
||||||
|
|
@ -116,11 +116,11 @@ sed -i '' "s/\"versionCode\": [0-9]*/\"versionCode\": $NEW_BUILD_NUMBER/g" "$APP
|
||||||
sed -i '' "s/\"buildNumber\": \"[^\"]*\"/\"buildNumber\": \"$NEW_BUILD_NUMBER\"/g" "$APP_JSON"
|
sed -i '' "s/\"buildNumber\": \"[^\"]*\"/\"buildNumber\": \"$NEW_BUILD_NUMBER\"/g" "$APP_JSON"
|
||||||
print_success "Updated app.json"
|
print_success "Updated app.json"
|
||||||
|
|
||||||
# Update SettingsScreen.tsx
|
# Update src/utils/version.ts
|
||||||
print_status "Updating SettingsScreen.tsx..."
|
print_status "Updating src/utils/version.ts..."
|
||||||
# Note: Use BSD sed compatible regex on macOS. Enable extended regex with -E.
|
# Replace the APP_VERSION constant value
|
||||||
sed -E -i '' "s/description=\"[0-9]+\.[0-9]+\.[0-9]+(-[^\"]*)?\"/description=\"$NEW_VERSION\"/g" "$SETTINGS_SCREEN"
|
sed -E -i '' "s/export const APP_VERSION = '\\S*';/export const APP_VERSION = '$NEW_VERSION';/g" "$VERSION_TS"
|
||||||
print_success "Updated SettingsScreen.tsx"
|
print_success "Updated src/utils/version.ts"
|
||||||
|
|
||||||
# Update Info.plist
|
# Update Info.plist
|
||||||
print_status "Updating Info.plist..."
|
print_status "Updating Info.plist..."
|
||||||
|
|
@ -152,11 +152,11 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check SettingsScreen.tsx
|
# Check src/utils/version.ts
|
||||||
if grep -q "description=\"$NEW_VERSION\"" "$SETTINGS_SCREEN"; then
|
if grep -q "export const APP_VERSION = '$NEW_VERSION';" "$VERSION_TS"; then
|
||||||
print_success "SettingsScreen.tsx updated correctly"
|
print_success "src/utils/version.ts updated correctly"
|
||||||
else
|
else
|
||||||
print_error "SettingsScreen.tsx update verification failed"
|
print_error "src/utils/version.ts update verification failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -180,14 +180,14 @@ fi
|
||||||
|
|
||||||
# Clean up backups
|
# Clean up backups
|
||||||
print_status "Cleaning up backups..."
|
print_status "Cleaning up backups..."
|
||||||
rm "${APP_JSON}.backup" "${SETTINGS_SCREEN}.backup" "${INFO_PLIST}.backup" "${ANDROID_BUILD_GRADLE}.backup"
|
rm "${APP_JSON}.backup" "${VERSION_TS}.backup" "${INFO_PLIST}.backup" "${ANDROID_BUILD_GRADLE}.backup"
|
||||||
|
|
||||||
print_success "Version update completed successfully!"
|
print_success "Version update completed successfully!"
|
||||||
print_status "Summary:"
|
print_status "Summary:"
|
||||||
echo " Version: $NEW_VERSION"
|
echo " Version: $NEW_VERSION"
|
||||||
echo " Runtime Version: $NEW_VERSION"
|
echo " Runtime Version: $NEW_VERSION"
|
||||||
echo " Build Number: $NEW_BUILD_NUMBER"
|
echo " Build Number: $NEW_BUILD_NUMBER"
|
||||||
echo " Files updated: app.json, SettingsScreen.tsx, Info.plist, Android build.gradle"
|
echo " Files updated: app.json, src/utils/version.ts, Info.plist, Android build.gradle"
|
||||||
echo ""
|
echo ""
|
||||||
print_status "Next steps:"
|
print_status "Next steps:"
|
||||||
echo " 1. Test the app to ensure everything works correctly"
|
echo " 1. Test the app to ensure everything works correctly"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue