Fix Android APK Issues Phase 2

This commit is contained in:
RoadtripDJ Dev
2026-05-17 23:36:26 +01:00
parent dedf25c51f
commit a0f11f73e8
14 changed files with 776 additions and 143 deletions

View File

@@ -4,6 +4,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import { X, MapPin, ArrowRight, Navigation } from 'lucide-react-native';
import { colors } from '../../utils/colors';
import { supabase } from '../../services/supabase';
import { getSpotifyAccessToken } from '../../auth/spotifyToken';
// @ts-ignore
export default function NewTripScreen({ navigation }) {
@@ -42,115 +43,128 @@ export default function NewTripScreen({ navigation }) {
setDistance(finalDistance);
setDuration(finalDuration);
let generatedPlaylistUrl = null;
try {
// A. Get provider token
const { data: sessionData, error: sessionError } = await supabase.auth.getSession();
if (sessionError || !sessionData?.session) throw new Error('Session not found.');
const providerToken = sessionData.session.provider_token;
if (!providerToken) throw new Error('Spotify provider token missing.');
const providerToken = await getSpotifyAccessToken();
if (!providerToken) {
throw new Error("Spotify token missing. Please log in with Spotify again.");
}
// B. Fetch Spotify User ID
const spotifyUserRes = await fetch('https://api.spotify.com/v1/me', {
headers: { 'Authorization': `Bearer ${providerToken}` }
});
const spotifyUserData = await spotifyUserRes.json();
if (!spotifyUserData.id) throw new Error('Could not fetch Spotify User ID');
const spotifyUserId = spotifyUserData.id;
// C. Call Ollama server
const ollamaRes = await fetch("http://89.114.196.110:11434/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: "qwen3-coder:30b",
messages: [{ "role": "user", "content": `I am taking a roadtrip from ${origin} to ${destination}. Reply ONLY with 3 Spotify genre seeds separated by commas (e.g., pop,rock,indie) that fit this journey. No other text.` }],
stream: false
})
});
const ollamaData = await ollamaRes.json();
const seed_genres = ollamaData.message.content.trim().replace(/\s+/g, '').toLowerCase();
// D. Create empty playlist
const createPlaylistRes = await fetch(`https://api.spotify.com/v1/users/${spotifyUserId}/playlists`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${providerToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: tripName,
description: `Roadtrip from ${origin} to ${destination}. Genres: ${seed_genres}`,
public: false
})
});
const playlistData = await createPlaylistRes.json();
if (!playlistData.id) throw new Error('Could not create playlist');
const playlistId = playlistData.id;
const generatedPlaylistUrl = playlistData.external_urls.spotify;
// E. Fetch Spotify track recommendations
let accumulatedDurationMs = 0;
let trackUris: string[] = [];
let attempts = 0;
while (accumulatedDurationMs < tripDurationMs && attempts < 10) {
const recommendationsRes = await fetch(`https://api.spotify.com/v1/recommendations?seed_genres=${encodeURIComponent(seed_genres)}&limit=50`, {
if (providerToken) {
// B. Fetch Spotify User ID
const spotifyUserRes = await fetch('https://api.spotify.com/v1/me', {
headers: { 'Authorization': `Bearer ${providerToken}` }
});
if (!recommendationsRes.ok) break;
const recommendationsData = await recommendationsRes.json();
if (!recommendationsData.tracks || recommendationsData.tracks.length === 0) break;
const spotifyUserData = await spotifyUserRes.json();
if (!spotifyUserData.id) throw new Error('Could not fetch Spotify User ID');
const spotifyUserId = spotifyUserData.id;
for (const track of recommendationsData.tracks) {
if (!trackUris.includes(track.uri)) {
trackUris.push(track.uri);
accumulatedDurationMs += track.duration_ms;
if (accumulatedDurationMs >= tripDurationMs) break;
// C. Call Ollama server
const ollamaRes = await fetch("http://89.114.196.110:11434/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: "qwen3-coder:30b",
messages: [{ "role": "user", "content": `I am taking a roadtrip from ${origin} to ${destination}. Reply ONLY with 3 Spotify genre seeds separated by commas (e.g., pop,rock,indie) that fit this journey. No other text.` }],
stream: false
})
});
const ollamaData = await ollamaRes.json();
const seed_genres = ollamaData.message.content.trim().replace(/\s+/g, '').toLowerCase();
// D. Create empty playlist
const createPlaylistRes = await fetch(`https://api.spotify.com/v1/users/${spotifyUserId}/playlists`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${providerToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: tripName,
description: `Roadtrip from ${origin} to ${destination}. Genres: ${seed_genres}`,
public: false
})
});
const playlistData = await createPlaylistRes.json();
if (!playlistData.id) throw new Error('Could not create playlist');
const playlistId = playlistData.id;
generatedPlaylistUrl = playlistData.external_urls.spotify;
// E. Fetch Spotify track recommendations
let accumulatedDurationMs = 0;
let trackUris: string[] = [];
let attempts = 0;
while (accumulatedDurationMs < tripDurationMs && attempts < 10) {
const recommendationsRes = await fetch(`https://api.spotify.com/v1/recommendations?seed_genres=${encodeURIComponent(seed_genres)}&limit=50`, {
headers: { 'Authorization': `Bearer ${providerToken}` }
});
if (!recommendationsRes.ok) break;
const recommendationsData = await recommendationsRes.json();
if (!recommendationsData.tracks || recommendationsData.tracks.length === 0) break;
for (const track of recommendationsData.tracks) {
if (!trackUris.includes(track.uri)) {
trackUris.push(track.uri);
accumulatedDurationMs += track.duration_ms;
if (accumulatedDurationMs >= tripDurationMs) break;
}
}
attempts++;
}
attempts++;
}
if (trackUris.length > 0) {
// F. Add tracks to playlist
const chunkSize = 100;
for (let i = 0; i < trackUris.length; i += chunkSize) {
const chunk = trackUris.slice(i, i + chunkSize);
await fetch(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${providerToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ uris: chunk })
});
if (trackUris.length > 0) {
// F. Add tracks to playlist
const chunkSize = 100;
for (let i = 0; i < trackUris.length; i += chunkSize) {
const chunk = trackUris.slice(i, i + chunkSize);
await fetch(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${providerToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ uris: chunk })
});
}
} else {
console.error("No tracks found for genres:", seed_genres);
}
} else {
console.log("No tracks found for genres:", seed_genres);
console.error("Spotify token missing, skipping playlist generation.");
Alert.alert('Aviso', 'Sessão Spotify não encontrada. A viagem será guardada sem playlist.');
}
// G. Save to Supabase
const { data: { user } } = await supabase.auth.getUser();
if (user) {
const { error: dbError } = await supabase.from('trips').insert({
user_id: user.id,
title: tripName,
origin,
destination,
distance: finalDistance,
duration: finalDuration,
playlist_url: generatedPlaylistUrl
});
if (dbError) {
console.log("DB Insert error:", dbError);
}
}
Alert.alert('Sucesso!', 'Viagem e Playlist Criadas!');
} catch (playlistError) {
console.log("Error generating playlist:", playlistError);
console.error("Error generating playlist:", playlistError);
Alert.alert('Erro Playlist', 'A viagem foi calculada, mas ocorreu um erro a criar a playlist.');
}
// G. Save to Supabase unconditionally if route is valid
try {
const { data: { session } } = await supabase.auth.getSession();
const userId = session?.user?.id || null;
const { error: dbError } = await supabase.from('trips').insert({
user_id: userId,
title: tripName,
origin,
destination,
distance: finalDistance,
duration: finalDuration,
playlist_url: generatedPlaylistUrl
});
if (dbError) {
console.error("DB Insert error:", dbError);
Alert.alert('Erro ao Guardar', 'Não foi possível guardar a viagem na base de dados: ' + dbError.message);
} else {
Alert.alert('Sucesso!', 'Viagem calculada e guardada!');
}
} catch (dbEx) {
console.error("Exception during DB save:", dbEx);
}
} else {
// O NOSSO DETETIVE ENTRA AQUI!
console.log("ERRO DA GOOGLE:", data);