Fix VOD loading by reconnecting Twitch auth on demand
Refresh Twitch authentication automatically when selecting streamers and retry Helix calls after 401 responses so valid streamers no longer show empty VOD states due to stale connection state.
This commit is contained in:
parent
fb29ee77d3
commit
f3bfed9b56
@ -1628,8 +1628,11 @@
|
|||||||
document.getElementById('pageTitle').textContent = name;
|
document.getElementById('pageTitle').textContent = name;
|
||||||
|
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
updateStatus('Nicht verbunden', false);
|
await connect();
|
||||||
return;
|
if (!isConnected) {
|
||||||
|
document.getElementById('vodGrid').innerHTML = '<div class="empty-state"><h3>Nicht verbunden</h3><p>Bitte Twitch API Daten in den Einstellungen prufen.</p></div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('vodGrid').innerHTML = '<div class="empty-state"><p>Lade VODs...</p></div>';
|
document.getElementById('vodGrid').innerHTML = '<div class="empty-state"><p>Lade VODs...</p></div>';
|
||||||
@ -1887,8 +1890,8 @@
|
|||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
async function saveSettings() {
|
async function saveSettings() {
|
||||||
const clientId = document.getElementById('clientId').value;
|
const clientId = document.getElementById('clientId').value.trim();
|
||||||
const clientSecret = document.getElementById('clientSecret').value;
|
const clientSecret = document.getElementById('clientSecret').value.trim();
|
||||||
const downloadPath = document.getElementById('downloadPath').value;
|
const downloadPath = document.getElementById('downloadPath').value;
|
||||||
const downloadMode = document.getElementById('downloadMode').value;
|
const downloadMode = document.getElementById('downloadMode').value;
|
||||||
const partMinutes = parseInt(document.getElementById('partMinutes').value);
|
const partMinutes = parseInt(document.getElementById('partMinutes').value);
|
||||||
|
|||||||
@ -291,11 +291,19 @@ async function twitchLogin(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getUserId(username: string): Promise<string | null> {
|
async function ensureTwitchAuth(forceRefresh = false): Promise<boolean> {
|
||||||
if (!accessToken) return null;
|
if (!forceRefresh && accessToken) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
return await twitchLogin();
|
||||||
const response = await axios.get('https://api.twitch.tv/helix/users', {
|
}
|
||||||
|
|
||||||
|
async function getUserId(username: string): Promise<string | null> {
|
||||||
|
if (!(await ensureTwitchAuth())) return null;
|
||||||
|
|
||||||
|
const fetchUser = async () => {
|
||||||
|
return await axios.get('https://api.twitch.tv/helix/users', {
|
||||||
params: { login: username },
|
params: { login: username },
|
||||||
headers: {
|
headers: {
|
||||||
'Client-ID': config.client_id,
|
'Client-ID': config.client_id,
|
||||||
@ -303,18 +311,32 @@ async function getUserId(username: string): Promise<string | null> {
|
|||||||
},
|
},
|
||||||
timeout: API_TIMEOUT
|
timeout: API_TIMEOUT
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetchUser();
|
||||||
return response.data.data[0]?.id || null;
|
return response.data.data[0]?.id || null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (axios.isAxiosError(e) && e.response?.status === 401 && (await ensureTwitchAuth(true))) {
|
||||||
|
try {
|
||||||
|
const retryResponse = await fetchUser();
|
||||||
|
return retryResponse.data.data[0]?.id || null;
|
||||||
|
} catch (retryError) {
|
||||||
|
console.error('Error getting user after relogin:', retryError);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error('Error getting user:', e);
|
console.error('Error getting user:', e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getVODs(userId: string): Promise<VOD[]> {
|
async function getVODs(userId: string): Promise<VOD[]> {
|
||||||
if (!accessToken) return [];
|
if (!(await ensureTwitchAuth())) return [];
|
||||||
|
|
||||||
try {
|
const fetchVods = async () => {
|
||||||
const response = await axios.get('https://api.twitch.tv/helix/videos', {
|
return await axios.get('https://api.twitch.tv/helix/videos', {
|
||||||
params: {
|
params: {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
type: 'archive',
|
type: 'archive',
|
||||||
@ -326,18 +348,32 @@ async function getVODs(userId: string): Promise<VOD[]> {
|
|||||||
},
|
},
|
||||||
timeout: API_TIMEOUT
|
timeout: API_TIMEOUT
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetchVods();
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (axios.isAxiosError(e) && e.response?.status === 401 && (await ensureTwitchAuth(true))) {
|
||||||
|
try {
|
||||||
|
const retryResponse = await fetchVods();
|
||||||
|
return retryResponse.data.data;
|
||||||
|
} catch (retryError) {
|
||||||
|
console.error('Error getting VODs after relogin:', retryError);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error('Error getting VODs:', e);
|
console.error('Error getting VODs:', e);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getClipInfo(clipId: string): Promise<any | null> {
|
async function getClipInfo(clipId: string): Promise<any | null> {
|
||||||
if (!accessToken) return null;
|
if (!(await ensureTwitchAuth())) return null;
|
||||||
|
|
||||||
try {
|
const fetchClip = async () => {
|
||||||
const response = await axios.get('https://api.twitch.tv/helix/clips', {
|
return await axios.get('https://api.twitch.tv/helix/clips', {
|
||||||
params: { id: clipId },
|
params: { id: clipId },
|
||||||
headers: {
|
headers: {
|
||||||
'Client-ID': config.client_id,
|
'Client-ID': config.client_id,
|
||||||
@ -345,8 +381,22 @@ async function getClipInfo(clipId: string): Promise<any | null> {
|
|||||||
},
|
},
|
||||||
timeout: API_TIMEOUT
|
timeout: API_TIMEOUT
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetchClip();
|
||||||
return response.data.data[0] || null;
|
return response.data.data[0] || null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (axios.isAxiosError(e) && e.response?.status === 401 && (await ensureTwitchAuth(true))) {
|
||||||
|
try {
|
||||||
|
const retryResponse = await fetchClip();
|
||||||
|
return retryResponse.data.data[0] || null;
|
||||||
|
} catch (retryError) {
|
||||||
|
console.error('Error getting clip after relogin:', retryError);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error('Error getting clip:', e);
|
console.error('Error getting clip:', e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user