Skip to content

Commit cbea499

Browse files
authored
Update Settings.tsx
1 parent 5419a22 commit cbea499

File tree

1 file changed

+52
-41
lines changed

1 file changed

+52
-41
lines changed

source-code/components/Settings.tsx

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState, useEffect } from 'react';
2-
import { Smartphone, Github, ShieldCheck, Bell, ChevronRight, Palette, Layers, Info, ExternalLink, Globe, MessageSquare, Youtube, Languages, RefreshCcw, CheckCircle, AlertTriangle, Download, HardDriveDownload } from 'lucide-react';
2+
import { Smartphone, Github, ShieldCheck, Bell, ChevronRight, Palette, Layers, Info, ExternalLink, Globe, MessageSquare, Youtube, Languages, RefreshCcw, CheckCircle, AlertTriangle, HardDriveDownload } from 'lucide-react';
33
import { ThemeId, Theme, Language } from '../types';
44
import { THEMES } from '../utils/theme';
55
import { TRANSLATIONS } from '../utils/translations';
@@ -58,16 +58,19 @@ export const Settings: React.FC<SettingsProps> = ({ currentTheme, setTheme, lang
5858
if (!response.ok) throw new Error("Failed to fetch version");
5959

6060
const text = await response.text();
61-
// Parse format: [ 0.2 ]
62-
// Regex looks for brackets and captures content inside
63-
const match = text.match(/\[\s*([\d.]+)\s*\]/);
61+
62+
// Robust regex to find version number.
63+
// Matches: "0.3", "v0.3", "[ 0.3 ]", "ver: 0.3"
64+
// It captures the digits and dots.
65+
const match = text.match(/(?:v|ver|version|\[)?\s*([\d.]+)\s*(?:\])?/i);
6466

6567
if (match && match[1]) {
6668
const remoteVer = match[1];
6769
setRemoteVersion(remoteVer);
6870

69-
// Simple string comparison for versions (assuming simplified standard numbering)
70-
if (parseFloat(remoteVer) > parseFloat(APP_VERSION)) {
71+
// Simple comparison: if remote string is different and "larger" (lexicographically for now)
72+
// Ideally use semver comparison, but for simple app versions this suffices
73+
if (remoteVer !== APP_VERSION && parseFloat(remoteVer) > parseFloat(APP_VERSION)) {
7174
setCheckStatus('update_available');
7275
} else {
7376
setCheckStatus('uptodate');
@@ -87,14 +90,11 @@ export const Settings: React.FC<SettingsProps> = ({ currentTheme, setTheme, lang
8790
const apkUrl = `https://github.com/HackerOS-Linux-System/HackerOS-App/releases/download/v${remoteVersion}/HackerOS-App-${remoteVersion}.apk`;
8891

8992
await Toast.show({
90-
text: 'Starting download... Check your notifications.',
93+
text: 'Starting download... Check notifications.',
9194
duration: 'long'
9295
});
9396

94-
// We use window.open to trigger the system's download manager.
95-
// On Android, downloading an APK via the system browser/manager allows the "Install" prompt
96-
// to appear when the user clicks the notification. This handles the "Install" step
97-
// by delegating it to the OS Package Installer.
97+
// Open system browser to handle download and installation prompt
9898
window.open(apkUrl, '_system');
9999
};
100100

@@ -269,7 +269,7 @@ export const Settings: React.FC<SettingsProps> = ({ currentTheme, setTheme, lang
269269
</div>
270270
</section>
271271

272-
{/* About Section */}
272+
{/* About & Updates Section */}
273273
<section className="px-4">
274274
<div className="bg-card/50 backdrop-blur-md border border-white/5 rounded-2xl overflow-hidden shadow-xl">
275275
<div className="p-4 border-b border-white/5 flex items-center gap-3">
@@ -296,50 +296,61 @@ export const Settings: React.FC<SettingsProps> = ({ currentTheme, setTheme, lang
296296
<ChevronRight size={16} className="text-muted" />
297297
</a>
298298

299-
<div className="p-4 flex items-center justify-between flex-wrap gap-3">
300-
<div className="flex items-center gap-3">
301-
<div className="p-2 rounded-lg bg-background text-muted">
302-
<ShieldCheck size={18} />
303-
</div>
304-
<div>
305-
<p className="text-sm font-medium text-text">App Version</p>
306-
<p className="text-xs text-muted">
307-
{checkStatus === 'update_available'
308-
? `${t.settings_version_latest}: v${remoteVersion}`
309-
: `v${APP_VERSION}`}
310-
</p>
299+
<div className="p-4 flex flex-col gap-4">
300+
<div className="flex items-center justify-between">
301+
<div className="flex items-center gap-3">
302+
<div className="p-2 rounded-lg bg-background text-muted">
303+
<ShieldCheck size={18} />
304+
</div>
305+
<div>
306+
<p className="text-sm font-medium text-text">System Version</p>
307+
<p className="text-xs text-muted font-mono">
308+
v{APP_VERSION}
309+
</p>
310+
</div>
311311
</div>
312+
313+
{/* Status Badge */}
314+
{checkStatus !== 'idle' && (
315+
<div className={`px-2 py-0.5 rounded text-[10px] font-bold border uppercase tracking-wider
316+
${checkStatus === 'checking' ? 'border-primary/50 text-primary' : ''}
317+
${checkStatus === 'uptodate' ? 'border-green-500/50 text-green-500' : ''}
318+
${checkStatus === 'update_available' ? 'border-amber-500/50 text-amber-500' : ''}
319+
${checkStatus === 'error' ? 'border-red-500/50 text-red-500' : ''}
320+
`}>
321+
{checkStatus === 'checking' && 'SCANNING...'}
322+
{checkStatus === 'uptodate' && 'LATEST'}
323+
{checkStatus === 'update_available' && 'OUTDATED'}
324+
{checkStatus === 'error' && 'ERROR'}
325+
</div>
326+
)}
312327
</div>
313-
314-
{checkStatus === 'update_available' ? (
328+
329+
{/* Action Button */}
330+
{checkStatus === 'update_available' ? (
315331
<button
316332
onClick={performUpdate}
317-
className="ml-auto px-4 py-2 rounded-lg text-xs font-bold bg-primary text-background border border-primary/50 shadow-[0_0_15px_-5px_rgb(var(--color-primary))] flex items-center gap-2 animate-pulse hover:animate-none hover:bg-primary/90 transition-all"
333+
className="w-full py-3 rounded-lg text-xs font-bold bg-primary text-background border border-primary/50 shadow-[0_0_15px_-5px_rgb(var(--color-primary))] flex items-center justify-center gap-2 animate-pulse hover:animate-none hover:bg-primary/90 transition-all"
318334
>
319-
<HardDriveDownload size={14} />
335+
<HardDriveDownload size={16} />
320336
<span>UPDATE TO v{remoteVersion}</span>
321337
</button>
322338
) : (
323339
<button
324340
onClick={checkForUpdates}
325341
disabled={checkStatus === 'checking'}
326342
className={`
327-
ml-auto px-3 py-1.5 rounded-lg text-xs font-bold border transition-all flex items-center gap-2
328-
${checkStatus === 'checking' ? 'bg-white/5 border-white/10 text-muted cursor-wait' : ''}
329-
${checkStatus === 'idle' ? 'bg-white/5 border-white/10 text-primary hover:bg-white/10' : ''}
330-
${checkStatus === 'uptodate' ? 'bg-green-500/10 border-green-500/20 text-green-500' : ''}
331-
${checkStatus === 'error' ? 'bg-red-500/10 border-red-500/20 text-red-500' : ''}
343+
w-full py-2.5 rounded-lg text-xs font-bold border transition-all flex items-center justify-center gap-2
344+
${checkStatus === 'checking' ? 'bg-white/5 border-white/10 text-muted cursor-wait' : 'bg-white/5 border-white/10 text-primary hover:bg-white/10'}
332345
`}
333346
>
334-
{checkStatus === 'checking' && <RefreshCcw size={12} className="animate-spin" />}
335-
{checkStatus === 'uptodate' && <CheckCircle size={12} />}
336-
{checkStatus === 'error' && <AlertTriangle size={12} />}
337-
347+
{checkStatus === 'checking' ? (
348+
<RefreshCcw size={14} className="animate-spin" />
349+
) : (
350+
<RefreshCcw size={14} />
351+
)}
338352
<span>
339-
{checkStatus === 'idle' && t.settings_check_update}
340-
{checkStatus === 'checking' && t.settings_checking}
341-
{checkStatus === 'uptodate' && t.settings_up_to_date}
342-
{checkStatus === 'error' && t.settings_update_error}
353+
{checkStatus === 'checking' ? t.settings_checking : t.settings_check_update}
343354
</span>
344355
</button>
345356
)}

0 commit comments

Comments
 (0)