added some changes, mkey

This commit is contained in:
StarAppeal
2025-09-13 12:12:23 +02:00
parent a5b64db556
commit 67db408230
9 changed files with 62 additions and 42 deletions
+4 -2
View File
@@ -13,8 +13,10 @@ export default function HomeScreen() {
const {theme} = useTheme(); const {theme} = useTheme();
useEffect(() => { useEffect(() => {
setIdle(authenticatedUser!.lastState?.global.mode === "idle") if (authenticatedUser) {
}, []) setIdle(authenticatedUser.lastState?.global.mode === "idle")
}
}, [authenticatedUser]);
return ( return (
<ThemedBackground> <ThemedBackground>
+5 -4
View File
@@ -9,8 +9,9 @@ import {View} from "react-native";
export default function TextScreen() { export default function TextScreen() {
const {authenticatedUser} = useAuth(); const {authenticatedUser} = useAuth();
const [textProps, setTextProps] = useState(authenticatedUser!.lastState?.text); const [textProps, setTextProps] = useState(
authenticatedUser?.lastState?.text! || { text: '', color: [255, 255, 255] }
);
return ( return (
<ThemedBackground> <ThemedBackground>
<View style={{ padding: 20, gap: 10 }}> <View style={{ padding: 20, gap: 10 }}>
@@ -20,7 +21,7 @@ export default function TextScreen() {
value={textProps?.text} value={textProps?.text}
onChangeText={(value: string) => { onChangeText={(value: string) => {
setTextProps(prev => ({ setTextProps(prev => ({
...prev!, ...prev,
text: value text: value
})); }));
}} }}
@@ -29,7 +30,7 @@ export default function TextScreen() {
<CustomColorPicker <CustomColorPicker
onSelect={rgb => setTextProps(prev => ({ ...prev!, color: rgb }))} onSelect={rgb => setTextProps(prev => ({ ...prev!, color: rgb }))}
defaultColor={textProps?.color} defaultColor={textProps.color}
/> />
</View> </View>
+6 -5
View File
@@ -14,6 +14,7 @@ import {useRouter} from "expo-router";
export default function SettingsScreen() { export default function SettingsScreen() {
const {token: jwtToken, authenticatedUser, logout, refreshUser} = useAuth(); const {token: jwtToken, authenticatedUser, logout, refreshUser} = useAuth();
const router = useRouter(); const router = useRouter();
console.log("Mashallah", jwtToken);
const handleAuthSuccess = (token: Token) => { const handleAuthSuccess = (token: Token) => {
const spotifyConfig = { const spotifyConfig = {
@@ -37,11 +38,11 @@ export default function SettingsScreen() {
<ThemedHeader>Einen wunderschönen guten Tag, {authenticatedUser?.name}</ThemedHeader> <ThemedHeader>Einen wunderschönen guten Tag, {authenticatedUser?.name}</ThemedHeader>
<ChangePasswordModal/> <ChangePasswordModal/>
<ThemeToggleButton/> <ThemeToggleButton/>
<SpotifyAuthButton <SpotifyAuthButton
onAuthSuccess={handleAuthSuccess} onAuthSuccess={handleAuthSuccess}
jwtToken={jwtToken!} jwtToken={jwtToken}
disabled={!!authenticatedUser?.spotifyConfig} disabled={!!authenticatedUser?.spotifyConfig}
/> />
{!!authenticatedUser?.spotifyConfig && ( <ThemedButton mode={"outlined"} title={"Remove Spotify"} onPress={() => { {!!authenticatedUser?.spotifyConfig && ( <ThemedButton mode={"outlined"} title={"Remove Spotify"} onPress={() => {
const rest = new RestService(jwtToken); const rest = new RestService(jwtToken);
rest.removeSpotifyConfig().then((result) => { rest.removeSpotifyConfig().then((result) => {
+4 -5
View File
@@ -13,7 +13,6 @@ import {useRouter} from "expo-router";
import ThemeToggleButton from "@/src/components/ThemeToggleButton"; import ThemeToggleButton from "@/src/components/ThemeToggleButton";
import PasswordInput from "@/src/components/PasswordInput"; import PasswordInput from "@/src/components/PasswordInput";
export default function LoginScreen() { export default function LoginScreen() {
const {isAuthenticated, login, logout, error} = useAuth(); const {isAuthenticated, login, logout, error} = useAuth();
const router = useRouter(); const router = useRouter();
@@ -55,8 +54,8 @@ export default function LoginScreen() {
returnKeyType="next" returnKeyType="next"
value={username} value={username}
onChangeText={setUsername} onChangeText={setUsername}
error={!!error && error?.toLowerCase().includes("user") } error={!!error && error?.field === "username" }
errorText={error!} errorText={error?.message}
autoCapitalize="none" autoCapitalize="none"
/> />
@@ -65,8 +64,8 @@ export default function LoginScreen() {
returnKeyType="done" returnKeyType="done"
value={password} value={password}
onChangeText={setPassword} onChangeText={setPassword}
error={!!error && error?.toLowerCase().includes("pass") } error={!!error && error?.field === "password" }
errorText={error!} errorText={error?.message}
autoComplete="password" autoComplete="password"
/> />
<ThemedButton mode="outlined" onPress={onLoginPressed} title={"Login"} /> <ThemedButton mode="outlined" onPress={onLoginPressed} title={"Login"} />
+17 -13
View File
@@ -15,25 +15,29 @@ export default function CustomImagePicker({onSuccess, onFailure, onCanceled}: Pr
const [image, setImage] = useState<string | null>(null); const [image, setImage] = useState<string | null>(null);
const pickImage = async () => { const pickImage = async () => {
// No permissions request is necessary for launching the image library try {
let result = ImagePicker.launchImageLibraryAsync({ const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images', 'videos'], mediaTypes: ['images', 'videos'],
allowsEditing: true, allowsEditing: true,
aspect: [4, 3], aspect: [4, 3],
quality: 1, quality: 1,
base64: true, base64: true,
}).then((result) => { });
if (result.canceled) { if (result.canceled) {
onCanceled(); onCanceled();
} else { } else {
setImage(result.assets[0].uri); setImage(result.assets[0].uri);
onSuccess(result); onSuccess(result);
} }
}).catch((error) => { } catch (error) {
onFailure(error); if (error instanceof Error) {
}); onFailure(error);
console.log(result); } else {
} onFailure(new Error('An unknown error occurred during image picking.'));
}
}
};
return ( return (
<View style={styles.container}> <View style={styles.container}>
+1 -1
View File
@@ -5,7 +5,7 @@ import ThemedButton from "@/src/components/themed/ThemedButton";
interface SpotifyAuthButtonProps { interface SpotifyAuthButtonProps {
onAuthSuccess: (token: Token) => void; onAuthSuccess: (token: Token) => void;
jwtToken: string; jwtToken: string | null;
disabled: boolean; disabled: boolean;
} }
+6 -5
View File
@@ -11,7 +11,7 @@ type AuthContextType = {
login: (username: string, password: string) => Promise<void>; login: (username: string, password: string) => Promise<void>;
logout: () => Promise<void>; logout: () => Promise<void>;
authenticatedUser: User | null; authenticatedUser: User | null;
error: string | null; error: { field: string, message: string } | null;
loading: boolean; loading: boolean;
refreshUser: () => Promise<void>; refreshUser: () => Promise<void>;
}; };
@@ -22,7 +22,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null); const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);
const [authenticatedUser, setAuthenticatedUser] = useState<User | null>(null); const [authenticatedUser, setAuthenticatedUser] = useState<User | null>(null);
const [token, setToken] = useState<string | null>(null); const [token, setToken] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<{ field: string, message: string } | null>(null);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
useEffect(() => { useEffect(() => {
@@ -53,7 +53,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
setToken(null); setToken(null);
setIsAuthenticated(false); setIsAuthenticated(false);
setAuthenticatedUser(null); setAuthenticatedUser(null);
setError("Token invalid"); setError({field: "general", message:"Token is invalid."});
return null; return null;
} }
const user = response.data; const user = response.data;
@@ -71,8 +71,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
const response = await new RestService(null).login(username, password); const response = await new RestService(null).login(username, password);
if (!response.ok) { if (!response.ok) {
console.error("Login failed:", response.data.message); console.error("Login failed:", response.data);
setError(response.data.message!); const message = response.data.message!;
setError({field: response.data.details?.field!, message});
setIsAuthenticated(false); setIsAuthenticated(false);
setLoading(false); setLoading(false);
return; return;
+1 -1
View File
@@ -15,7 +15,7 @@ interface UseSpotifyAuthResult {
export const useSpotifyAuth = ( export const useSpotifyAuth = (
onAuthSuccess: (token: Token) => void, onAuthSuccess: (token: Token) => void,
jwtToken: string, jwtToken: string | null,
): UseSpotifyAuthResult => { ): UseSpotifyAuthResult => {
const [request, response, promptAsync] = useAuthRequest( const [request, response, promptAsync] = useAuthRequest(
{ {
+18 -6
View File
@@ -82,8 +82,10 @@ class RestService {
return this.request<ApiResponse<User>>('GET', '/user/me'); return this.request<ApiResponse<User>>('GET', '/user/me');
} }
async changeSelfPassword(password: string, passwordConfirmation: string): Promise<ApiResponse<{ message: string }>> { async changeSelfPassword(password: string, passwordConfirmation: string): Promise<ApiResponse<{
return this.request<ApiResponse<{message: string}>>( message: string
}>> {
return this.request<ApiResponse<{ message: string }>>(
'PUT', 'PUT',
'/user/me/password', '/user/me/password',
{password, passwordConfirmation}, {password, passwordConfirmation},
@@ -109,9 +111,9 @@ class RestService {
); );
} }
async updateSelfSpotifyConfig(spotifyConfig?: SpotifyConfig): Promise<ApiResponse<{message: string}>> { async updateSelfSpotifyConfig(spotifyConfig?: SpotifyConfig): Promise<ApiResponse<{ message: string }>> {
const payload = spotifyConfig ?? {}; const payload = spotifyConfig ?? {};
return this.request<ApiResponse<{message: string}>>( return this.request<ApiResponse<{ message: string }>>(
'PUT', 'PUT',
'/user/me/spotify', '/user/me/spotify',
payload, payload,
@@ -123,8 +125,18 @@ class RestService {
return this.request<ApiResponse<User>>('DELETE', '/user/me/spotify'); return this.request<ApiResponse<User>>('DELETE', '/user/me/spotify');
} }
async login(username: string, password: string): Promise<ApiResponse<{ message?: string, token?: string }>> { async login(username: string, password: string): Promise<ApiResponse<{
return this.request<ApiResponse<{message?: string, token?: string}>>( message?: string, token?: string, details?: {
field: string;
code: string;
}
}>> {
return this.request<ApiResponse<{
message?: string, token?: string, details?: {
field: string;
code: string;
}
}>>(
"POST", "POST",
'/auth/login', '/auth/login',
{username, password}, {username, password},