diff --git a/android/app/build.gradle b/android/app/build.gradle index b16d2c6..c734661 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -37,8 +37,7 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.SaufApp" + applicationId "com.tooxo.SaufApp" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() @@ -47,7 +46,6 @@ android { buildTypes { release { - // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index c98c86f..9585461 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.tooxo.SaufApp"> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e7f74fb..89f8234 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.tooxo.SaufApp"> diff --git a/lib/games/game.dart b/lib/games/game.dart index 896e5f9..f767c06 100644 --- a/lib/games/game.dart +++ b/lib/games/game.dart @@ -158,19 +158,22 @@ class BasicGameState extends State }, icon: Icon(Icons.clear), ), - title: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + title: /*Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - widget.title.tr(), + //widget.title, + "this is the title", style: GoogleFonts.caveatBrush( color: Colors.black, fontSize: 40, fontWeight: FontWeight.w600), - ), - ]), - /*Text( - widget.title.tr(), + ).tr(), + ]),*/ + Text( + // widget.title.tr(), + widget.title, style: GoogleFonts.caveatBrush( fontSize: 40, color: Colors.black, fontWeight: FontWeight.w600), - ), - centerTitle: true,*/ + textAlign: TextAlign.center, + ).tr(), + centerTitle: true, backgroundColor: widget.primaryColor, ); } diff --git a/lib/games/guess_the_song.dart b/lib/games/guess_the_song.dart index d031e35..491cddf 100644 --- a/lib/games/guess_the_song.dart +++ b/lib/games/guess_the_song.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:SaufApp/games/game.dart'; +import 'package:SaufApp/utils/networking.dart'; import 'package:SaufApp/utils/types.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:connectivity/connectivity.dart'; @@ -73,8 +74,7 @@ class GuessTheSongState extends BasicGameState with WidgetsBindingObserver { void buttonClick() async { if (state == 0 || state == 1) { - ConnectivityResult result = await Connectivity().checkConnectivity(); - if (result != ConnectivityResult.none) { + if (!(await checkConnection())) { audioPlayer.play(widget.mainTitle); } else { Fluttertoast.showToast( diff --git a/lib/menus/difficulty.dart b/lib/menus/difficulty.dart index b35b84e..4a43e48 100644 --- a/lib/menus/difficulty.dart +++ b/lib/menus/difficulty.dart @@ -5,12 +5,14 @@ import 'package:SaufApp/utils/ad.dart'; import 'package:SaufApp/games/challenges.dart'; import 'package:SaufApp/games/guess_the_song.dart'; import 'package:SaufApp/games/never_have_i_ever.dart'; +import 'package:SaufApp/utils/networking.dart'; import 'package:SaufApp/utils/player.dart'; import 'package:SaufApp/games/quiz.dart'; import 'package:SaufApp/menus/setting.dart'; import 'package:SaufApp/utils/shapes.dart'; import 'package:SaufApp/utils/spotify_api.dart'; import 'package:SaufApp/games/truth_or_dare.dart'; +import 'package:SaufApp/utils/sqlite.dart'; import 'package:SaufApp/utils/types.dart'; import 'package:SaufApp/games/who_would_rather.dart'; import 'package:assorted_layout_widgets/assorted_layout_widgets.dart'; @@ -220,9 +222,7 @@ class DifficultyState extends State { for (List game in availableGames) { GameType gameType = game[1]; if (gameType == GameType.GUESS_THE_SONG) { - ConnectivityResult connectivityResult = - await Connectivity().checkConnectivity(); - if (connectivityResult != ConnectivityResult.none) { + if (await checkConnection()) { List urls = []; if (selectedModes == SettingsState.ONLY_INCLUDED || selectedModes == SettingsState.BOTH) { @@ -237,6 +237,14 @@ class DifficultyState extends State { }); texts[gameType] = await buildSpotify(urls); + SqLite database = await SqLite().open(); + Spotify spotify = Spotify(); + dynamic missingSongs = + texts[GameType.GUESS_THE_SONG].where((e) => e.contains(null)); + texts[GameType.GUESS_THE_SONG] + .removeWhere((element) => element.contains(null)); + missingSongs.map((e) async => texts[GameType.GUESS_THE_SONG] + .add(await spotify.fillMissingPreviewUrls(e, database))); } else { Fluttertoast.showToast( msg: "Rate den Song wurde deaktiviert, da du über keine " @@ -359,9 +367,13 @@ class DifficultyState extends State { randomlyChosenText = json.encode({"truth": randomTextTruth, "dare": randomTextDare}); } else { - randomlyChosenText = texts[game.type] - [Random.secure().nextInt(texts[game.type].length)]; - texts[game.type].remove(randomlyChosenText); + try { + randomlyChosenText = texts[game.type] + [Random.secure().nextInt(texts[game.type].length)]; + texts[game.type].remove(randomlyChosenText); + } on IndexError { + continue; + } } /* @@ -773,12 +785,13 @@ class DifficultyState extends State { Column( children: [ Expanded( - flex: 3, + flex: 4, child: Container(), ), Expanded( flex: 1, - child: Center( + child: Align( + alignment: Alignment.bottomCenter, child: Material( color: Colors.transparent, child: Text( diff --git a/lib/menus/word_customization.dart b/lib/menus/word_customization.dart index eb26a1f..689aa45 100644 --- a/lib/menus/word_customization.dart +++ b/lib/menus/word_customization.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:SaufApp/utils/networking.dart'; import 'package:SaufApp/utils/shapes.dart'; import 'package:SaufApp/utils/spotify_api.dart'; import 'package:SaufApp/utils/types.dart'; @@ -104,7 +105,7 @@ class WordCustomizationState extends State { Future spotifyCheckerWrapper() async { if (getSelectedType() == GameType.GUESS_THE_SONG) { Connectivity c = new Connectivity(); - if ((await c.checkConnectivity()) == ConnectivityResult.none) { + if (!(await checkConnection())) { return true; } if (await Spotify.playlistExists(tf1Value)) { diff --git a/lib/utils/networking.dart b/lib/utils/networking.dart new file mode 100644 index 0000000..3a59a83 --- /dev/null +++ b/lib/utils/networking.dart @@ -0,0 +1,18 @@ +import 'dart:io'; + +import 'package:connectivity/connectivity.dart'; + +Future checkConnection() async { + return [ConnectivityResult.mobile, ConnectivityResult.wifi] + .contains(await Connectivity().checkConnectivity()) && + await _checkLookup(); +} + +Future _checkLookup() async { + try { + final result = await InternetAddress.lookup('example.com'); + return result.isNotEmpty && result[0].rawAddress.isNotEmpty; + } on SocketException catch (_) { + return false; + } +} diff --git a/lib/utils/spotify_api.dart b/lib/utils/spotify_api.dart index 4943017..a1cacac 100644 --- a/lib/utils/spotify_api.dart +++ b/lib/utils/spotify_api.dart @@ -56,6 +56,8 @@ class Spotify { /// Start with pulling the embed web page, because spotify is shit. + // Disabled for now, because it creates a way too great delay + /* http.Response embedPlaylistResponse = await http.get("https://open.spotify.com/embed/playlist/$playlistId"); @@ -65,7 +67,8 @@ class Spotify { dynamic decodedEmbedPage = jsonDecode(rawJson); for (Map track in decodedEmbedPage["tracks"]["items"]) { if (track["track"]["preview_url"] != null) { - track["track"]["preview_url"].replaceAll("\\/", "/"); + track["track"]["preview_url"] = + track["track"]["preview_url"].replaceAll("\\/", "/"); } List song = [ track["track"]["artists"][0]["name"] + " - " + track["track"]["name"], @@ -76,89 +79,76 @@ class Spotify { trackList.add(song); } } - - if (decodedEmbedPage["tracks"]["total"] > 100) { - String token = await generateAuthKey(); - String url = - "https://api.spotify.com/v1/playlists/$playlistId/tracks?limit=100&offset=100"; - - Map jsonResponse; - do { - http.Response response = - await http.get(url, headers: {"Authorization": "Bearer $token"}); - if (response.statusCode != 200) { - return trackList; + */ + + // if (decodedEmbedPage["tracks"]["total"] > 100) { + String token = await generateAuthKey(); + String url = + "https://api.spotify.com/v1/playlists/$playlistId/tracks?limit=100&offset=100"; + + Map jsonResponse; + do { + http.Response response = + await http.get(url, headers: {"Authorization": "Bearer $token"}); + if (response.statusCode != 200) { + return trackList; + } + jsonResponse = jsonDecode(response.body); + for (Map track in jsonResponse["items"]) { + if (track["is_local"]) { + continue; } - jsonResponse = jsonDecode(response.body); - for (Map track in jsonResponse["items"]) { - if (track["is_local"]) { - continue; - } - if (track["track"] == null) { - continue; - } - - List song = [ - track["track"]["artists"][0]["name"] + - " - " + - track["track"]["name"], - track["track"]["preview_url"], - track["track"]["id"] - ]; - - /// this fixes a weird error with spotify returning null as - /// the preview url, although they have a preview available - /// this also multiplies the time a playlist gets extracted by factor 50 - /// spotify big suck - /// Documented here: https://github.com/spotify/web-api/issues/148 - - if (track["track"]["preview_url"] == null) { - String previewFromDatabase = useCache - ? await database.getFromSpotifyCache(track["track"]["id"]) - : null; - - if (previewFromDatabase != null) { - song = [ - track["track"]["artists"][0]["name"] + - " - " + - track["track"]["name"], - previewFromDatabase, - track["track"]["id"] - ]; - } else { - try { - String trackId = track["track"]["id"]; - http.Response embedResponse = await http.get( - "https://open.spotify.com/embed/track/$trackId", - ); - String previewUrl = - RegExp(REGEX_EMBED).firstMatch(embedResponse.body).group(1); - if (previewUrl != null) { - previewUrl.replaceAll("\\/", "/"); - } - song = [ - track["track"]["artists"][0]["name"] + - " - " + - track["track"]["name"], - previewUrl, - track["track"]["id"] - ]; - } catch (ignored) { - song = [null, null]; - } - } - } - if (!song.contains(null)) { - trackList.add(song); - } + if (track["track"] == null) { + continue; } - url = jsonResponse["next"]; - } while (jsonResponse.containsKey("more")); - } + + List song = [ + track["track"]["artists"][0]["name"] + " - " + track["track"]["name"], + track["track"]["preview_url"], + track["track"]["id"] + ]; + + // if (!song.contains(null)) { + trackList.add(song); + // } + } + url = jsonResponse["next"]; + } while (jsonResponse.containsKey("more")); + //} if (useCache) database.putBulkInSpotifyCache(trackList); - /*database - .putBulkInSpotifyCache(trackList) - .then((value) async => await database.close());*/ return trackList; } + + Future> fillMissingPreviewUrls( + List track, SqLite database, + {useCache: true}) async { + /// this fixes a weird error with spotify returning null as + /// the preview url, although they have a preview available + /// this also multiplies the time a playlist gets extracted by factor 50 + /// spotify big suck + /// Documented here: https://github.com/spotify/web-api/issues/148 + + String previewFromDatabase = + useCache ? await database.getFromSpotifyCache(track[2]) : null; + + if (previewFromDatabase != null) { + track[1] = previewFromDatabase; + } else { + try { + String trackId = track[2]; + http.Response embedResponse = await http.get( + "https://open.spotify.com/embed/track/$trackId", + ); + String previewUrl = + RegExp(REGEX_EMBED).firstMatch(embedResponse.body).group(1); + if (previewUrl != null) { + previewUrl = previewUrl.replaceAll("\\/", "/"); + } + track[1] = previewUrl; + } catch (ignored) { + return [null, null, null]; + } + } + return track; + } }