Fix Android APK Issues Phase 2
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user