feat: new name and icon

This commit is contained in:
2026-01-04 17:05:40 -05:00
Unverified
parent 47970891ef
commit 05e423ea4e
10 changed files with 257 additions and 361 deletions

View File

@@ -1,4 +1,4 @@
# UpSnap Mobile # Jumpstart - Client for UpSnap
A React Native Expo app that connects to an UpSnap server and provides mobile access to all Wake-on-LAN features. A React Native Expo app that connects to an UpSnap server and provides mobile access to all Wake-on-LAN features.

View File

@@ -1,6 +1,6 @@
{ {
"expo": { "expo": {
"name": "Remote WoL", "name": "Jumpstart",
"slug": "remote-wol", "slug": "remote-wol",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",

View File

@@ -1,250 +1,231 @@
import React from "react"; import React from 'react';
import { import {
Alert, Alert,
ScrollView, ScrollView,
StyleSheet, StyleSheet,
Text, Text,
TouchableOpacity, TouchableOpacity,
View, View,
} from "react-native"; } from 'react-native';
import { useColorScheme } from "../../hooks/use-color-scheme"; import { useColorScheme } from '../../hooks/use-color-scheme';
import { useAuth } from "../../src/context/AuthContext"; import { useAuth } from '../../src/context/AuthContext';
import { useRouter } from "expo-router"; import { useRouter } from 'expo-router';
import Constants from 'expo-constants';
export default function SettingsScreen() { export default function SettingsScreen() {
const { user, serverAddress, logout } = useAuth(); const { user, serverAddress, logout } = useAuth();
const router = useRouter(); const router = useRouter();
const colorScheme = useColorScheme() ?? "light"; const colorScheme = useColorScheme() ?? 'light';
const isDark = colorScheme === "dark"; const isDark = colorScheme === 'dark';
const bgColor = isDark ? "#0b0b0d" : "#f5f5f5"; const bgColor = isDark ? '#0b0b0d' : '#f5f5f5';
const sectionBg = isDark ? "#1c1c1e" : "#fff"; const sectionBg = isDark ? '#1c1c1e' : '#fff';
const sectionTitleBg = isDark ? "#111111" : "#f9f9f9"; const sectionTitleBg = isDark ? '#111111' : '#f9f9f9';
const textColor = isDark ? "#fff" : "#333"; const textColor = isDark ? '#fff' : '#333';
const subTextColor = isDark ? "#c6c6c8" : "#666"; const subTextColor = isDark ? '#c6c6c8' : '#666';
const primary = isDark ? "#0A84FF" : "#007AFF"; const primary = isDark ? '#0A84FF' : '#007AFF';
const destructiveColor = "#f44336"; const destructiveColor = '#f44336';
const handleLogout = () => { const handleLogout = () => {
Alert.alert("Logout", "Are you sure you want to logout?", [ Alert.alert('Logout', 'Are you sure you want to logout?', [
{ text: "Cancel", style: "cancel" }, { text: 'Cancel', style: 'cancel' },
{ {
text: "Logout", text: 'Logout',
style: "destructive", style: 'destructive',
onPress: async () => { onPress: async () => {
router.replace("/login"); router.replace('/login');
await logout(); await logout();
}, },
}, },
]); ]);
}; };
const SettingItem = ({ const SettingItem = ({
label, label,
value, value,
onPress, onPress,
}: { }: {
label: string; label: string;
value?: string; value?: string;
onPress?: () => void; onPress?: () => void;
}) => ( }) => (
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.settingItem, styles.settingItem,
{ borderBottomColor: isDark ? "rgba(255,255,255,0.03)" : "#f0f0f0" }, { borderBottomColor: isDark ? 'rgba(255,255,255,0.03)' : '#f0f0f0' },
]} ]}
onPress={onPress} onPress={onPress}
disabled={!onPress} disabled={!onPress}
activeOpacity={onPress ? 0.7 : 1} activeOpacity={onPress ? 0.7 : 1}
> >
<Text style={[styles.settingLabel, { color: textColor }]}>{label}</Text> <Text style={[styles.settingLabel, { color: textColor }]}>{label}</Text>
<View style={styles.settingValueContainer}> <View style={styles.settingValueContainer}>
<Text <Text
style={[styles.settingValue, { color: subTextColor }]} style={[styles.settingValue, { color: subTextColor }]}
numberOfLines={1} numberOfLines={1}
> >
{value} {value}
</Text> </Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
); );
const ActionButton = ({ const ActionButton = ({
title, title,
onPress, onPress,
destructive = false, destructive = false,
}: { }: {
title: string; title: string;
onPress: () => void; onPress: () => void;
destructive?: boolean; destructive?: boolean;
}) => ( }) => (
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.actionButton, styles.actionButton,
{ backgroundColor: destructive ? destructiveColor : primary }, { backgroundColor: destructive ? destructiveColor : primary },
]} ]}
onPress={onPress} onPress={onPress}
> >
<Text style={styles.actionButtonText}>{title}</Text> <Text style={styles.actionButtonText}>{title}</Text>
</TouchableOpacity> </TouchableOpacity>
); );
return ( return (
<ScrollView style={[styles.container, { backgroundColor: bgColor }]}> <ScrollView style={[styles.container, { backgroundColor: bgColor }]}>
<View style={styles.content}> <View style={styles.content}>
<View <View
style={[ style={[
styles.section, styles.section,
{ {
backgroundColor: sectionBg, backgroundColor: sectionBg,
shadowColor: isDark ? "rgba(255,255,255,0.02)" : "#000", shadowColor: isDark ? 'rgba(255,255,255,0.02)' : '#000',
}, },
]} ]}
> >
<Text <Text
style={[ style={[
styles.sectionTitle, styles.sectionTitle,
{ color: subTextColor, backgroundColor: sectionTitleBg }, { color: subTextColor, backgroundColor: sectionTitleBg },
]} ]}
> >
User Information Information
</Text> </Text>
<SettingItem label="Username" value={user?.username || "Admin"} /> <SettingItem label="Username" value={user?.username || 'Admin'} />
<SettingItem label="Email" value={user?.email || "N/A"} /> <SettingItem label="Email" value={user?.email || 'N/A'} />
<SettingItem label="Server URL" value={serverAddress || "N/A"} /> <SettingItem label="Server URL" value={serverAddress || 'N/A'} />
</View> <SettingItem label="App Version" value={`${Constants.expoConfig?.version}`} />
</View>
<View <View
style={[ style={[
styles.section, styles.section,
{ {
backgroundColor: sectionBg, backgroundColor: sectionBg,
shadowColor: isDark ? "rgba(255,255,255,0.02)" : "#000", shadowColor: isDark ? 'rgba(255,255,255,0.02)' : '#000',
}, },
]} ]}
> >
<Text <Text
style={[ style={[
styles.sectionTitle, styles.sectionTitle,
{ color: subTextColor, backgroundColor: sectionTitleBg }, { color: subTextColor, backgroundColor: sectionTitleBg },
]} ]}
> >
App Info Actions
</Text> </Text>
<SettingItem label="Version" value="1.0.0" /> <ActionButton title="Logout" onPress={handleLogout} destructive />
<SettingItem label="Build" value="Expo" /> </View>
</View>
<View <View style={styles.footer}>
style={[ <Text style={[styles.footerText, { color: subTextColor }]}>
styles.section, UpSnap Mobile App
{ </Text>
backgroundColor: sectionBg, <Text style={[styles.footerText, { color: subTextColor }]}>
shadowColor: isDark ? "rgba(255,255,255,0.02)" : "#000", Connect to your UpSnap server
}, </Text>
]} </View>
> </View>
<Text </ScrollView>
style={[ );
styles.sectionTitle,
{ color: subTextColor, backgroundColor: sectionTitleBg },
]}
>
Actions
</Text>
<ActionButton title="Logout" onPress={handleLogout} destructive />
</View>
<View style={styles.footer}>
<Text style={[styles.footerText, { color: subTextColor }]}>
UpSnap Mobile App
</Text>
<Text style={[styles.footerText, { color: subTextColor }]}>
Connect to your UpSnap server
</Text>
</View>
</View>
</ScrollView>
);
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: "#f5f5f5", backgroundColor: '#f5f5f5',
}, },
content: { content: {
padding: 20, padding: 20,
}, },
section: { section: {
backgroundColor: "#fff", backgroundColor: '#fff',
borderRadius: 12, borderRadius: 12,
marginBottom: 20, marginBottom: 20,
overflow: "hidden", overflow: 'hidden',
shadowColor: "#000", shadowColor: '#000',
shadowOffset: { width: 0, height: 2 }, shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1, shadowOpacity: 0.1,
shadowRadius: 4, shadowRadius: 4,
elevation: 3, elevation: 3,
}, },
sectionTitle: { sectionTitle: {
fontSize: 14, fontSize: 14,
fontWeight: "bold", fontWeight: 'bold',
color: "#666", color: '#666',
paddingHorizontal: 15, paddingHorizontal: 15,
paddingTop: 15, paddingTop: 15,
paddingBottom: 10, paddingBottom: 10,
backgroundColor: "#f9f9f9", backgroundColor: '#f9f9f9',
borderTopLeftRadius: 12, borderTopLeftRadius: 12,
borderTopRightRadius: 12, borderTopRightRadius: 12,
}, },
settingItem: { settingItem: {
flexDirection: "row", flexDirection: 'row',
justifyContent: "space-between", justifyContent: 'space-between',
alignItems: "center", alignItems: 'center',
paddingHorizontal: 15, paddingHorizontal: 15,
paddingVertical: 15, paddingVertical: 15,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: "#f0f0f0", borderBottomColor: '#f0f0f0',
}, },
settingLabel: { settingLabel: {
fontSize: 16, fontSize: 16,
color: "#333", color: '#333',
flex: 1, flex: 1,
}, },
settingValueContainer: { settingValueContainer: {
flex: 1, flex: 1,
alignItems: "flex-end", alignItems: 'flex-end',
}, },
settingValue: { settingValue: {
fontSize: 14, fontSize: 14,
color: "#666", color: '#666',
maxWidth: 200, maxWidth: 200,
}, },
actionButton: { actionButton: {
backgroundColor: "#007AFF", backgroundColor: '#007AFF',
margin: 15, margin: 15,
padding: 15, padding: 15,
borderRadius: 8, borderRadius: 8,
alignItems: "center", alignItems: 'center',
}, },
actionButtonDestructive: { actionButtonDestructive: {
backgroundColor: "#f44336", backgroundColor: '#f44336',
}, },
actionButtonText: { actionButtonText: {
color: "#fff", color: '#fff',
fontSize: 16, fontSize: 16,
fontWeight: "bold", fontWeight: 'bold',
}, },
actionButtonTextDestructive: { actionButtonTextDestructive: {
color: "#fff", color: '#fff',
}, },
footer: { footer: {
alignItems: "center", alignItems: 'center',
paddingVertical: 30, paddingVertical: 30,
}, },
footerText: { footerText: {
fontSize: 14, fontSize: 14,
color: "#999", color: '#999',
marginBottom: 5, marginBottom: 5,
}, },
}); });

View File

@@ -55,7 +55,7 @@ export default function LoginScreen() {
> >
<ScrollView contentContainerStyle={styles.scrollContent}> <ScrollView contentContainerStyle={styles.scrollContent}>
<View style={styles.header}> <View style={styles.header}>
<Text style={[styles.title, { color: textColor }]}>Remote WoL</Text> <Text style={[styles.title, { color: textColor }]}>Jumpstart</Text>
<Text style={[styles.subtitle, { color: subText }]}> <Text style={[styles.subtitle, { color: subText }]}>
Mobile Frontend for UpSnap Mobile Frontend for UpSnap
</Text> </Text>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -1,19 +1,48 @@
{ {
"fill" : { "fill" : {
"automatic-gradient" : "extended-srgb:0.00000,0.53333,1.00000,1.00000" "automatic-gradient" : "extended-gray:1.00000,1.00000"
}, },
"groups" : [ "groups" : [
{ {
"layers" : [ "layers" : [
{ {
"glass" : true, "hidden" : false,
"image-name" : "gopher.svg", "image-name" : "Image.png",
"name" : "gopher", "name" : "Image",
"position" : { "position" : {
"scale" : 0.45, "scale" : 0.65,
"translation-in-points" : [ "translation-in-points" : [
-6.017952794793246, 0,
-0.4600234584925147 -52.942187500000045
]
}
},
{
"fill-specializations" : [
{
"appearance" : "dark",
"value" : "none"
}
],
"image-name-specializations" : [
{
"value" : "display 2.png"
},
{
"appearance" : "dark",
"value" : "display.png"
},
{
"appearance" : "tinted",
"value" : "display 3.png"
}
],
"name" : "display 3",
"position" : {
"scale" : 1.25,
"translation-in-points" : [
0,
-10.625
] ]
} }
} }