mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
updates UI now support release notes
This commit is contained in:
parent
837e3735a2
commit
754dec3946
6 changed files with 133 additions and 15 deletions
|
|
@ -1,9 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if the correct number of arguments are provided
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <xavia-ota-url>"
|
||||
echo "Example: $0 https://grim-reyna-tapframe-69970143.koyeb.app"
|
||||
# Usage: build-and-publish-app-release.sh <xavia-ota-url> [--yes] [--release-notes "text here"]
|
||||
# --yes Skip interactive confirmation
|
||||
# --release-notes Provide release notes to attach to this upload
|
||||
|
||||
# Parse arguments
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Usage: $0 <xavia-ota-url> [--yes] [--release-notes \"text here\"]"
|
||||
echo "Example: $0 https://grim-reyna-tapframe-69970143.koyeb.app --yes --release-notes \"Bug fixes and improvements\""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
@ -27,6 +31,29 @@ fi
|
|||
|
||||
# Assign arguments to variables
|
||||
serverHost=$1
|
||||
shift
|
||||
|
||||
SKIP_CONFIRM=false
|
||||
RELEASE_NOTES=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
key="$1"
|
||||
case $key in
|
||||
--yes)
|
||||
SKIP_CONFIRM=true
|
||||
shift
|
||||
;;
|
||||
--release-notes)
|
||||
RELEASE_NOTES="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate server URL format
|
||||
if [[ ! "$serverHost" =~ ^https?:// ]]; then
|
||||
|
|
@ -47,13 +74,15 @@ echo "📱 Runtime Version: $runtimeVersion"
|
|||
echo "🔗 Commit Hash: $commitHash"
|
||||
echo "📝 Commit Message: $commitMessage"
|
||||
echo "🌐 Server URL: $serverHost"
|
||||
echo "📝 Release Notes: ${RELEASE_NOTES:-<none provided>}"
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to proceed with these values? (y/n): " confirm
|
||||
|
||||
if [ "$confirm" != "y" ]; then
|
||||
echo "❌ Operation cancelled by the user."
|
||||
exit 1
|
||||
if [ "$SKIP_CONFIRM" = false ]; then
|
||||
read -p "Do you want to proceed with these values? (y/n): " confirm
|
||||
if [ "$confirm" != "y" ]; then
|
||||
echo "❌ Operation cancelled by the user."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🔨 Starting build process..."
|
||||
|
|
@ -107,6 +136,7 @@ while [ $retry_count -lt $max_retries ]; do
|
|||
-F "runtimeVersion=$runtimeVersion" \
|
||||
-F "commitHash=$commitHash" \
|
||||
-F "commitMessage=$commitMessage" \
|
||||
${RELEASE_NOTES:+-F "releaseNotes=$RELEASE_NOTES"} \
|
||||
--write-out "HTTP_CODE:%{http_code}" \
|
||||
--silent \
|
||||
--show-error)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,17 @@ const UpdatePopup: React.FC<UpdatePopupProps> = ({
|
|||
const { currentTheme } = useTheme();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const getReleaseNotes = () => {
|
||||
const manifest: any = updateInfo?.manifest || {};
|
||||
return (
|
||||
manifest.description ||
|
||||
manifest.releaseNotes ||
|
||||
manifest.extra?.releaseNotes ||
|
||||
manifest.metadata?.releaseNotes ||
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
const handleUpdateNow = () => {
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
|
||||
onUpdateNow();
|
||||
|
|
@ -129,13 +140,13 @@ const UpdatePopup: React.FC<UpdatePopupProps> = ({
|
|||
</Text>
|
||||
</View>
|
||||
|
||||
{updateInfo.manifest?.description && (
|
||||
{!!getReleaseNotes() && (
|
||||
<View style={styles.descriptionContainer}>
|
||||
<Text style={[
|
||||
styles.description,
|
||||
{ color: currentTheme.colors.mediumEmphasis }
|
||||
]}>
|
||||
{updateInfo.manifest.description}
|
||||
{getReleaseNotes()}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import Animated, {
|
|||
useAnimatedStyle,
|
||||
interpolate,
|
||||
Extrapolate,
|
||||
useAnimatedReaction,
|
||||
runOnJS,
|
||||
} from 'react-native-reanimated';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
|
@ -46,6 +48,7 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
setLogoLoadError,
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
const [isHeaderInteractive, setIsHeaderInteractive] = React.useState(false);
|
||||
|
||||
// Animated styles for the header
|
||||
const headerAnimatedStyle = useAnimatedStyle(() => ({
|
||||
|
|
@ -55,6 +58,15 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
]
|
||||
}));
|
||||
|
||||
// Disable touches when header is transparent (Android can still register touches at opacity 0)
|
||||
useAnimatedReaction(
|
||||
() => headerOpacity.value,
|
||||
(opacity) => {
|
||||
const interactive = opacity > 0.05;
|
||||
runOnJS(setIsHeaderInteractive)(interactive);
|
||||
}
|
||||
);
|
||||
|
||||
// Animated style for header elements
|
||||
const headerElementsStyle = useAnimatedStyle(() => ({
|
||||
opacity: headerElementsOpacity.value,
|
||||
|
|
@ -62,7 +74,7 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
}));
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.floatingHeader, headerAnimatedStyle]}>
|
||||
<Animated.View style={[styles.floatingHeader, headerAnimatedStyle]} pointerEvents={isHeaderInteractive ? 'auto' : 'none'}>
|
||||
{Platform.OS === 'ios' ? (
|
||||
<ExpoBlurView
|
||||
intensity={50}
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ const TrailerPlayer = React.forwardRef<any, TrailerPlayerProps>(({
|
|||
onLoad={handleLoad}
|
||||
onError={(error: any) => handleError(error)}
|
||||
onProgress={handleProgress}
|
||||
controls={false}
|
||||
controls={Platform.OS === 'android' ? isFullscreen : false}
|
||||
onEnd={() => {
|
||||
// Only loop if still considered playing and component is mounted
|
||||
if (isPlaying && isComponentMounted) {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ const UpdateScreen: React.FC = () => {
|
|||
const insets = useSafeAreaInsets();
|
||||
|
||||
const [updateInfo, setUpdateInfo] = useState<any>(null);
|
||||
const [currentInfo, setCurrentInfo] = useState<any>(null);
|
||||
const [isChecking, setIsChecking] = useState(false);
|
||||
const [isInstalling, setIsInstalling] = useState(false);
|
||||
const [lastChecked, setLastChecked] = useState<Date | null>(null);
|
||||
|
|
@ -154,11 +155,35 @@ const UpdateScreen: React.FC = () => {
|
|||
|
||||
const getCurrentUpdateInfo = async () => {
|
||||
const info = await UpdateService.getCurrentUpdateInfo();
|
||||
setUpdateInfo(info);
|
||||
setCurrentInfo(info);
|
||||
const logs = UpdateService.getLogs();
|
||||
setLogs(logs);
|
||||
};
|
||||
|
||||
// Extract release notes from various possible manifest fields
|
||||
const getReleaseNotes = () => {
|
||||
const manifest: any = updateInfo?.manifest || {};
|
||||
return (
|
||||
manifest.description ||
|
||||
manifest.releaseNotes ||
|
||||
manifest.extra?.releaseNotes ||
|
||||
manifest.metadata?.releaseNotes ||
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
// Extract release notes for the currently running version
|
||||
const getCurrentReleaseNotes = () => {
|
||||
const manifest: any = currentInfo?.manifest || {};
|
||||
return (
|
||||
manifest.description ||
|
||||
manifest.releaseNotes ||
|
||||
manifest.extra?.releaseNotes ||
|
||||
manifest.metadata?.releaseNotes ||
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
const refreshLogs = () => {
|
||||
const logs = UpdateService.getLogs();
|
||||
setLogs(logs);
|
||||
|
|
@ -414,6 +439,19 @@ const UpdateScreen: React.FC = () => {
|
|||
</View>
|
||||
</View>
|
||||
|
||||
{/* Release Notes */}
|
||||
{updateInfo?.isAvailable && !!getReleaseNotes() && (
|
||||
<View style={styles.infoSection}>
|
||||
<View style={styles.infoItem}>
|
||||
<View style={[styles.infoIcon, { backgroundColor: `${currentTheme.colors.primary}15` }]}>
|
||||
<MaterialIcons name="notes" size={14} color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Release notes:</Text>
|
||||
</View>
|
||||
<Text style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}>{getReleaseNotes()}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Info Section */}
|
||||
<View style={styles.infoSection}>
|
||||
<View style={styles.infoItem}>
|
||||
|
|
@ -439,6 +477,33 @@ const UpdateScreen: React.FC = () => {
|
|||
)}
|
||||
</View>
|
||||
|
||||
{/* Current Version Section */}
|
||||
<View style={styles.infoSection}>
|
||||
<View style={styles.infoItem}>
|
||||
<View style={[styles.infoIcon, { backgroundColor: `${currentTheme.colors.primary}15` }]}>
|
||||
<MaterialIcons name="verified" size={14} color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Current version:</Text>
|
||||
<Text style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}>
|
||||
{currentInfo?.manifest?.id ? `${currentInfo.manifest.id.substring(0, 8)}...` : (currentInfo?.isEmbeddedLaunch === false ? 'Unknown' : 'Embedded')}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{!!getCurrentReleaseNotes() && (
|
||||
<View style={{ marginTop: 8 }}>
|
||||
<View style={[styles.infoItem, { alignItems: 'flex-start' }]}>
|
||||
<View style={[styles.infoIcon, { backgroundColor: `${currentTheme.colors.primary}15` }]}>
|
||||
<MaterialIcons name="notes" size={14} color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
<Text style={[styles.infoLabel, { color: currentTheme.colors.mediumEmphasis }]}>Current release notes:</Text>
|
||||
</View>
|
||||
<Text style={[styles.infoValue, { color: currentTheme.colors.highEmphasis }]}>
|
||||
{getCurrentReleaseNotes()}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Advanced Toggle */}
|
||||
<TouchableOpacity
|
||||
style={[styles.modernAdvancedToggle, { backgroundColor: `${currentTheme.colors.primary}08` }]}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit ef5455acaa04404d816a6bffc25a259e28189918
|
||||
Subproject commit 90fd3dd10d6ccbef30e9ce68d81c483a5552c378
|
||||
Loading…
Reference in a new issue