mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
feat: show error dialog on piped API 500 error
This commit is contained in:
parent
c94e5ba430
commit
c69f81ec6f
46
lib/components/shared/dialogs/piped_down_dialog.dart
Normal file
46
lib/components/shared/dialogs/piped_down_dialog.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
|
import 'package:spotube/extensions/context.dart';
|
||||||
|
import 'package:spotube/provider/user_preferences_provider.dart';
|
||||||
|
|
||||||
|
class PipedDownDialog extends HookConsumerWidget {
|
||||||
|
const PipedDownDialog({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, ref) {
|
||||||
|
final pipedInstance =
|
||||||
|
ref.watch(userPreferencesProvider.select((s) => s.pipedInstance));
|
||||||
|
final ThemeData(:colorScheme) = Theme.of(context);
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
insetPadding: const EdgeInsets.all(6),
|
||||||
|
contentPadding: const EdgeInsets.all(6),
|
||||||
|
icon: Icon(
|
||||||
|
SpotubeIcons.error,
|
||||||
|
color: colorScheme.error,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
context.l10n.piped_api_down,
|
||||||
|
style: TextStyle(color: colorScheme.error),
|
||||||
|
),
|
||||||
|
content: Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child:
|
||||||
|
Text(context.l10n.piped_down_error_instructions(pipedInstance)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(context.l10n.ok),
|
||||||
|
),
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(context.l10n.settings),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -254,5 +254,7 @@
|
|||||||
"ok": "Ok",
|
"ok": "Ok",
|
||||||
"failed_to_encrypt": "Failed to encrypt",
|
"failed_to_encrypt": "Failed to encrypt",
|
||||||
"encryption_failed_warning": "Spotube uses encryption to securely store your data. But failed to do so. So it'll fallback to insecure storage\nIf you're using linux, please make sure you've any secret-service (gnome-keyring, kde-wallet, keepassxc etc) installed",
|
"encryption_failed_warning": "Spotube uses encryption to securely store your data. But failed to do so. So it'll fallback to insecure storage\nIf you're using linux, please make sure you've any secret-service (gnome-keyring, kde-wallet, keepassxc etc) installed",
|
||||||
"querying_info": "Querying info..."
|
"querying_info": "Querying info...",
|
||||||
|
"piped_api_down": "Piped API is down",
|
||||||
|
"piped_down_error_instructions": "The Piped instance {pipedInstance} is currently down\n\nEither change the instance or change the 'API type' to official YouTube API\n\nMake sure to restart the app after change"
|
||||||
}
|
}
|
@ -66,19 +66,17 @@ class SpotubeTrack extends Track {
|
|||||||
await client.search("$title - ${artists.join(", ")}").then(
|
await client.search("$title - ${artists.join(", ")}").then(
|
||||||
(res) {
|
(res) {
|
||||||
final siblings = res
|
final siblings = res
|
||||||
|
.sorted((a, b) => a.views.compareTo(b.views))
|
||||||
.where((item) {
|
.where((item) {
|
||||||
return artists.any(
|
return artists.any(
|
||||||
(artist) =>
|
(artist) =>
|
||||||
|
client.preferences.searchMode == SearchMode.youtube ||
|
||||||
artist.toLowerCase() == item.channelName.toLowerCase(),
|
artist.toLowerCase() == item.channelName.toLowerCase(),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.take(10)
|
.take(10)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (siblings.isEmpty) {
|
|
||||||
return res.take(10).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return siblings;
|
return siblings;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:piped_client/piped_client.dart';
|
import 'package:piped_client/piped_client.dart';
|
||||||
|
import 'package:spotube/collections/routes.dart';
|
||||||
|
import 'package:spotube/components/shared/dialogs/piped_down_dialog.dart';
|
||||||
import 'package:spotube/models/matched_track.dart';
|
import 'package:spotube/models/matched_track.dart';
|
||||||
import 'package:spotube/provider/user_preferences_provider.dart';
|
import 'package:spotube/provider/user_preferences_provider.dart';
|
||||||
import 'package:spotube/utils/primitive_utils.dart';
|
import 'package:spotube/utils/primitive_utils.dart';
|
||||||
@ -133,6 +136,18 @@ class YoutubeEndpoints {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> showPipedErrorDialog(Exception e) async {
|
||||||
|
if (e is DioException && (e.response?.statusCode ?? 0) >= 500) {
|
||||||
|
final context = rootNavigatorKey?.currentContext;
|
||||||
|
if (context != null) {
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => const PipedDownDialog(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<YoutubeVideoInfo>> search(String query) async {
|
Future<List<YoutubeVideoInfo>> search(String query) async {
|
||||||
if (youtube != null) {
|
if (youtube != null) {
|
||||||
final res = await youtube!.search(
|
final res = await youtube!.search(
|
||||||
@ -142,22 +157,27 @@ class YoutubeEndpoints {
|
|||||||
|
|
||||||
return res.map(YoutubeVideoInfo.fromVideo).toList();
|
return res.map(YoutubeVideoInfo.fromVideo).toList();
|
||||||
} else {
|
} else {
|
||||||
final res = await piped!.search(
|
try {
|
||||||
query,
|
final res = await piped!.search(
|
||||||
switch (preferences.searchMode) {
|
query,
|
||||||
SearchMode.youtube => PipedFilter.video,
|
switch (preferences.searchMode) {
|
||||||
SearchMode.youtubeMusic => PipedFilter.musicSongs,
|
SearchMode.youtube => PipedFilter.video,
|
||||||
},
|
SearchMode.youtubeMusic => PipedFilter.musicSongs,
|
||||||
);
|
},
|
||||||
return res.items
|
);
|
||||||
.whereType<PipedSearchItemStream>()
|
return res.items
|
||||||
.map(
|
.whereType<PipedSearchItemStream>()
|
||||||
(e) => YoutubeVideoInfo.fromSearchItemStream(
|
.map(
|
||||||
e,
|
(e) => YoutubeVideoInfo.fromSearchItemStream(
|
||||||
preferences.searchMode,
|
e,
|
||||||
),
|
preferences.searchMode,
|
||||||
)
|
),
|
||||||
.toList();
|
)
|
||||||
|
.toList();
|
||||||
|
} on Exception catch (e) {
|
||||||
|
await showPipedErrorDialog(e);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +213,9 @@ class YoutubeEndpoints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<(YoutubeVideoInfo info, String streamingUrl)> video(
|
Future<(YoutubeVideoInfo info, String streamingUrl)> video(
|
||||||
String id, SearchMode searchMode) async {
|
String id,
|
||||||
|
SearchMode searchMode,
|
||||||
|
) async {
|
||||||
if (youtube != null) {
|
if (youtube != null) {
|
||||||
final res = await youtube!.videos.get(id);
|
final res = await youtube!.videos.get(id);
|
||||||
return (
|
return (
|
||||||
@ -201,11 +223,16 @@ class YoutubeEndpoints {
|
|||||||
await streamingUrl(id),
|
await streamingUrl(id),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final res = await piped!.streams(id);
|
try {
|
||||||
return (
|
final res = await piped!.streams(id);
|
||||||
YoutubeVideoInfo.fromStreamResponse(res, searchMode),
|
return (
|
||||||
_pipedStreamResponseToStreamUrl(res),
|
YoutubeVideoInfo.fromStreamResponse(res, searchMode),
|
||||||
);
|
_pipedStreamResponseToStreamUrl(res),
|
||||||
|
);
|
||||||
|
} on Exception catch (e) {
|
||||||
|
await showPipedErrorDialog(e);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1,42 @@
|
|||||||
{}
|
{
|
||||||
|
"bn": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ca": [
|
||||||
|
"querying_info",
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"de": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"hi": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ja": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
],
|
||||||
|
|
||||||
|
"zh": [
|
||||||
|
"piped_api_down",
|
||||||
|
"piped_down_error_instructions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user