mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
feat: use catcher to handle exceptions
This commit is contained in:
parent
013aac4543
commit
84d94b05bc
@ -20,7 +20,6 @@ class PlayPauseAction extends Action<PlayPauseIntent> {
|
||||
|
||||
@override
|
||||
invoke(intent) async {
|
||||
try {
|
||||
if (PlayerControls.focusNode.canRequestFocus) {
|
||||
PlayerControls.focusNode.requestFocus();
|
||||
}
|
||||
@ -43,10 +42,6 @@ class PlayPauseAction extends Action<PlayPauseIntent> {
|
||||
await playback.togglePlayPause();
|
||||
}
|
||||
return null;
|
||||
} catch (e, stack) {
|
||||
logger.e("useTogglePlayPause", e, stack);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:spotify/spotify.dart' hide Search;
|
||||
@ -19,7 +20,7 @@ import 'package:spotube/pages/search/search.dart';
|
||||
import 'package:spotube/pages/settings/settings.dart';
|
||||
import 'package:spotube/pages/mobile_login/mobile_login.dart';
|
||||
|
||||
final rootNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final rootNavigatorKey = Catcher.navigatorKey;
|
||||
final shellRouteNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final router = GoRouter(
|
||||
navigatorKey: rootNavigatorKey,
|
||||
|
@ -60,5 +60,5 @@ abstract class SpotubeIcons {
|
||||
static const info = FeatherIcons.info;
|
||||
static const userRemove = FeatherIcons.userX;
|
||||
static const close = FeatherIcons.x;
|
||||
static const minimize = FeatherIcons.minimize2;
|
||||
static const minimize = FeatherIcons.chevronDown;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@ -98,12 +99,11 @@ final localTracksProvider = FutureProvider<List<Track>>((ref) async {
|
||||
} on FfiException catch (e) {
|
||||
if (e.message == "NoTag: reader does not contain an id3 tag") {
|
||||
getLogger(FutureProvider<List<Track>>)
|
||||
.w("[Fetching metadata]", e.message);
|
||||
.v("[Fetching metadata]", e.message);
|
||||
}
|
||||
return {};
|
||||
} on Exception catch (e, stack) {
|
||||
getLogger(FutureProvider<List<Track>>)
|
||||
.e("[Fetching metadata]", e, stack);
|
||||
} catch (e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
@ -124,7 +124,7 @@ final localTracksProvider = FutureProvider<List<Track>>((ref) async {
|
||||
|
||||
return tracks;
|
||||
} catch (e, stack) {
|
||||
getLogger(FutureProvider).e("[LocalTracksProvider]", e, stack);
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
@ -199,15 +199,7 @@ class PlayerControls extends HookConsumerWidget {
|
||||
SpotubeIcons.stop,
|
||||
color: iconColor,
|
||||
),
|
||||
onPressed: playback.track != null
|
||||
? () async {
|
||||
try {
|
||||
await playback.stop();
|
||||
} catch (e, stack) {
|
||||
logger.e("onStop", e, stack);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
onPressed: playback.track != null ? playback.stop : null,
|
||||
),
|
||||
PlatformIconButton(
|
||||
tooltip:
|
||||
|
@ -145,14 +145,10 @@ class BottomPlayer extends HookConsumerWidget {
|
||||
volume.value = v;
|
||||
},
|
||||
onChangeEnd: (value) async {
|
||||
try {
|
||||
// You don't really need to know why but this
|
||||
// way it works only
|
||||
await playback.setVolume(value);
|
||||
await playback.setVolume(value);
|
||||
} catch (e, stack) {
|
||||
logger.e("onChange", e, stack);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -10,7 +10,6 @@ import 'package:audio_service_web/audio_service_web.dart';
|
||||
import 'package:audio_session/audio_session_web.dart';
|
||||
import 'package:audioplayers_web/audioplayers_web.dart';
|
||||
import 'package:file_picker/_internal/file_picker_web.dart';
|
||||
import 'package:package_info_plus_web/package_info_plus_web.dart';
|
||||
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
||||
import 'package:url_launcher_web/url_launcher_web.dart';
|
||||
|
||||
@ -22,7 +21,6 @@ void registerPlugins(Registrar registrar) {
|
||||
AudioSessionWeb.registerWith(registrar);
|
||||
AudioplayersPlugin.registerWith(registrar);
|
||||
FilePickerWeb.registerWith(registrar);
|
||||
PackageInfoPlugin.registerWith(registrar);
|
||||
SharedPreferencesPlugin.registerWith(registrar);
|
||||
UrlLauncherPlugin.registerWith(registrar);
|
||||
registrar.registerMessageHandler();
|
||||
|
@ -1,31 +1,20 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:spotube/models/logger.dart';
|
||||
import 'package:spotube/provider/playback_provider.dart';
|
||||
|
||||
final logger = getLogger("PlaybackHook");
|
||||
|
||||
Future<void> Function() useNextTrack(WidgetRef ref) {
|
||||
return () async {
|
||||
try {
|
||||
final playback = ref.read(playbackProvider);
|
||||
await playback.player.pause();
|
||||
await playback.player.seek(Duration.zero);
|
||||
playback.seekForward();
|
||||
} catch (e, stack) {
|
||||
logger.e("useNextTrack", e, stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> Function() usePreviousTrack(WidgetRef ref) {
|
||||
return () async {
|
||||
try {
|
||||
final playback = ref.read(playbackProvider);
|
||||
await playback.player.pause();
|
||||
await playback.player.seek(Duration.zero);
|
||||
playback.seekBackward();
|
||||
} catch (e, stack) {
|
||||
logger.e("onPrevious", e, stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:fl_query/fl_query.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -61,6 +62,23 @@ void main() async {
|
||||
});
|
||||
}
|
||||
MobileAudioService? audioServiceHandler;
|
||||
|
||||
Catcher(
|
||||
debugConfig: CatcherOptions(
|
||||
SilentReportMode(),
|
||||
[
|
||||
ConsoleHandler(
|
||||
enableDeviceParameters: false,
|
||||
enableApplicationParameters: false,
|
||||
),
|
||||
FileHandler(await getLogsPath(), printLogs: false),
|
||||
SnackbarHandler(const Duration(seconds: 5)),
|
||||
],
|
||||
),
|
||||
releaseConfig: CatcherOptions(SilentReportMode(), [
|
||||
FileHandler(await getLogsPath(), printLogs: false),
|
||||
]),
|
||||
runAppFunction: () {
|
||||
runApp(
|
||||
Builder(
|
||||
builder: (context) {
|
||||
@ -115,14 +133,11 @@ void main() async {
|
||||
);
|
||||
return showPlatformAlertDialog<bool>(
|
||||
context,
|
||||
builder: (_) => ReplaceDownloadedDialog(track: track),
|
||||
builder: (_) =>
|
||||
ReplaceDownloadedDialog(track: track),
|
||||
).then((s) => s ?? false);
|
||||
} catch (e, stack) {
|
||||
logger.e(
|
||||
"onFileExists",
|
||||
e,
|
||||
stack,
|
||||
);
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@ -138,6 +153,8 @@ void main() async {
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class Spotube extends StatefulHookConsumerWidget {
|
||||
|
@ -13,6 +13,22 @@ SpotubeLogger getLogger<T>(T owner) {
|
||||
return _loggerFactory;
|
||||
}
|
||||
|
||||
Future<File> getLogsPath() async {
|
||||
String dir = (await getApplicationDocumentsDirectory()).path;
|
||||
if (kIsAndroid) {
|
||||
dir = (await getExternalStorageDirectory())?.path ?? "";
|
||||
}
|
||||
|
||||
if (kIsMacOS) {
|
||||
dir = path.join((await getLibraryDirectory()).path, "Logs");
|
||||
}
|
||||
final file = File(path.join(dir, ".spotube_logs"));
|
||||
if (!await file.exists()) {
|
||||
await file.create();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
class SpotubeLogger extends Logger {
|
||||
String? owner;
|
||||
SpotubeLogger([this.owner]) : super(filter: _SpotubeLogFilter());
|
||||
|
@ -203,12 +203,6 @@ class ArtistPage extends HookConsumerWidget {
|
||||
.queryKey,
|
||||
)
|
||||
?.refetch();
|
||||
} catch (e, stack) {
|
||||
logger.e(
|
||||
"FollowButton.onPressed",
|
||||
e,
|
||||
stack,
|
||||
);
|
||||
} finally {
|
||||
QueryBowl.of(context)
|
||||
.refetchQueries([
|
||||
|
@ -134,12 +134,8 @@ class Downloader with ChangeNotifier {
|
||||
logger.v(
|
||||
"[addToQueue] Writing metadata to ${file.path} is successful",
|
||||
);
|
||||
} catch (e, stack) {
|
||||
logger.e(
|
||||
"[addToQueue] Failed download of ${file.path}",
|
||||
e,
|
||||
stack,
|
||||
);
|
||||
} catch (e) {
|
||||
logger.v("[addToQueue] Failed download of ${file.path}", e);
|
||||
rethrow;
|
||||
} finally {
|
||||
currentlyRunning--;
|
||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
@ -198,7 +199,6 @@ class Playback extends PersistedChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> playPlaylist(CurrentPlaylist playlist, [int index = 0]) async {
|
||||
try {
|
||||
if (index < 0 || index > playlist.tracks.length - 1) return;
|
||||
if (isPlaying || status == PlaybackStatus.playing) await stop();
|
||||
this.playlist = blacklistNotifier.filterPlaylist(playlist);
|
||||
@ -214,15 +214,11 @@ class Playback extends PersistedChangeNotifier {
|
||||
if (index == -1) return;
|
||||
this.playlist!.tracks[i] = track!;
|
||||
});
|
||||
} catch (e) {
|
||||
_logger.e("[playPlaylist] $e");
|
||||
}
|
||||
}
|
||||
|
||||
// player methods
|
||||
Future<void> play(Track track, {AudioOnlyStreamInfo? manifest}) async {
|
||||
_logger.v("[Track Playing] ${track.name} - ${track.id}");
|
||||
try {
|
||||
// the track is already playing so no need to change that
|
||||
if (track.id == this.track?.id) return;
|
||||
if (status != PlaybackStatus.loading) {
|
||||
@ -264,9 +260,6 @@ class Playback extends PersistedChangeNotifier {
|
||||
);
|
||||
status = PlaybackStatus.playing;
|
||||
notifyListeners();
|
||||
} catch (e, stack) {
|
||||
_logger.e("play", e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> resume() async {
|
||||
@ -382,7 +375,7 @@ class Playback extends PersistedChangeNotifier {
|
||||
);
|
||||
return List.castFrom<dynamic, Map<String, int>>(segments);
|
||||
} catch (e, stack) {
|
||||
_logger.e("[getSkipSegments]", e, stack);
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return List.castFrom<dynamic, Map<String, int>>([]);
|
||||
}
|
||||
}
|
||||
@ -465,14 +458,10 @@ class Playback extends PersistedChangeNotifier {
|
||||
bool noSponsorBlock = false,
|
||||
bool ignoreCache = false,
|
||||
}) async {
|
||||
try {
|
||||
final format = preferences.ytSearchFormat;
|
||||
final matchAlgorithm = preferences.trackMatchAlgorithm;
|
||||
final artistsName = track.artists
|
||||
?.map((ar) => ar.name)
|
||||
.toList()
|
||||
.whereNotNull()
|
||||
.toList() ??
|
||||
final artistsName =
|
||||
track.artists?.map((ar) => ar.name).toList().whereNotNull().toList() ??
|
||||
[];
|
||||
_logger.v("[Track Search Artists] $artistsName");
|
||||
final mainArtist = artistsName.first;
|
||||
@ -567,10 +556,6 @@ class Playback extends PersistedChangeNotifier {
|
||||
track,
|
||||
noSponsorBlock: noSponsorBlock,
|
||||
);
|
||||
} catch (e, stack) {
|
||||
_logger.e("topSpotubeTrack", e, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Source> getAppropriateSource(
|
||||
@ -650,7 +635,6 @@ class Playback extends PersistedChangeNotifier {
|
||||
|
||||
@override
|
||||
FutureOr<void> loadFromLocal(Map<String, dynamic> map) async {
|
||||
try {
|
||||
if (map["playlist"] != null) {
|
||||
playlist = CurrentPlaylist.fromJson(jsonDecode(map["playlist"]));
|
||||
}
|
||||
@ -665,9 +649,6 @@ class Playback extends PersistedChangeNotifier {
|
||||
track = SpotubeTrack.fromJson(trackMap);
|
||||
}
|
||||
volume = map["volume"] ?? volume;
|
||||
} catch (e, stack) {
|
||||
_logger.e("loadFromLocal", e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -283,7 +283,6 @@ class _MprisMediaPlayer2Player extends DBusObject {
|
||||
|
||||
/// Gets value of property org.mpris.MediaPlayer2.Player.Metadata
|
||||
Future<DBusMethodResponse> getMetadata() async {
|
||||
try {
|
||||
if (playback.track == null) {
|
||||
return DBusMethodSuccessResponse([DBusDict.stringVariant({})]);
|
||||
}
|
||||
@ -317,10 +316,6 @@ class _MprisMediaPlayer2Player extends DBusObject {
|
||||
"xesam:genre": const DBusString("Unknown"),
|
||||
}),
|
||||
]);
|
||||
} catch (e) {
|
||||
print("[DBUS ERROR] $e");
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets value of property org.mpris.MediaPlayer2.Player.Volume
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:catcher/catcher.dart';
|
||||
|
||||
/// Parses duration string formatted by Duration.toString() to [Duration].
|
||||
/// The string should be of form hours:minutes:seconds.microseconds
|
||||
///
|
||||
@ -50,7 +52,8 @@ Duration parseDuration(String input) {
|
||||
Duration? tryParseDuration(String input) {
|
||||
try {
|
||||
return parseDuration(input);
|
||||
} catch (_) {
|
||||
} catch (e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -54,22 +54,21 @@ abstract class ServiceUtils {
|
||||
}
|
||||
|
||||
static Future<String?> extractLyrics(Uri url) async {
|
||||
try {
|
||||
var response = await http.get(url);
|
||||
final response = await http.get(url);
|
||||
|
||||
Document document = parser.parse(response.body);
|
||||
var lyrics = document.querySelector('div.lyrics')?.text.trim();
|
||||
String? lyrics = document.querySelector('div.lyrics')?.text.trim();
|
||||
if (lyrics == null) {
|
||||
lyrics = "";
|
||||
document
|
||||
.querySelectorAll("div[class^=\"Lyrics__Container\"]")
|
||||
.forEach((element) {
|
||||
if (element.text.trim().isNotEmpty) {
|
||||
var snippet = element.innerHtml.replaceAll("<br>", "\n").replaceAll(
|
||||
final snippet = element.innerHtml.replaceAll("<br>", "\n").replaceAll(
|
||||
RegExp("<(?!\\s*br\\s*\\/?)[^>]+>", caseSensitive: false),
|
||||
"",
|
||||
);
|
||||
var el = document.createElement("textarea");
|
||||
final el = document.createElement("textarea");
|
||||
el.innerHtml = snippet;
|
||||
lyrics = "$lyrics${el.text.trim()}\n\n";
|
||||
}
|
||||
@ -77,10 +76,6 @@ abstract class ServiceUtils {
|
||||
}
|
||||
|
||||
return lyrics;
|
||||
} catch (e, stack) {
|
||||
logger.e("extractLyrics", e, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List?> searchSong(
|
||||
@ -90,7 +85,6 @@ abstract class ServiceUtils {
|
||||
bool optimizeQuery = false,
|
||||
bool authHeader = false,
|
||||
}) async {
|
||||
try {
|
||||
if (apiKey == "" || apiKey == null) {
|
||||
apiKey = PrimitiveUtils.getRandomElement(lyricsSecrets);
|
||||
}
|
||||
@ -116,10 +110,6 @@ abstract class ServiceUtils {
|
||||
};
|
||||
}).toList();
|
||||
return results;
|
||||
} catch (e, stack) {
|
||||
logger.e("searchSong", e, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<String?> getLyrics(
|
||||
@ -129,7 +119,6 @@ abstract class ServiceUtils {
|
||||
bool optimizeQuery = false,
|
||||
bool authHeader = false,
|
||||
}) async {
|
||||
try {
|
||||
final results = await searchSong(
|
||||
title,
|
||||
artists,
|
||||
@ -168,10 +157,6 @@ abstract class ServiceUtils {
|
||||
|
||||
String? lyrics = await extractLyrics(Uri.parse(worthyOne["url"]));
|
||||
return lyrics;
|
||||
} catch (e, stack) {
|
||||
logger.e("getLyrics", e, stack);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static const baseUri = "https://www.rentanadviser.com/subtitles";
|
||||
@ -263,7 +248,6 @@ abstract class ServiceUtils {
|
||||
|
||||
static Future<SpotifySpotubeCredentials> getAccessToken(
|
||||
String cookieHeader) async {
|
||||
try {
|
||||
final res = await http.get(
|
||||
Uri.parse(
|
||||
"https://open.spotify.com/get_access_token?reason=transport&productType=web_player",
|
||||
@ -277,10 +261,6 @@ abstract class ServiceUtils {
|
||||
return SpotifySpotubeCredentials.fromJson(
|
||||
jsonDecode(res.body),
|
||||
);
|
||||
} catch (e, stack) {
|
||||
logger.e("getAccessToken", e, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
static void navigate(BuildContext context, String location, {Object? extra}) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <catcher/catcher_plugin.h>
|
||||
#include <metadata_god/metadata_god_plugin.h>
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) catcher_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "CatcherPlugin");
|
||||
catcher_plugin_register_with_registrar(catcher_registrar);
|
||||
g_autoptr(FlPluginRegistrar) metadata_god_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MetadataGodPlugin");
|
||||
metadata_god_plugin_register_with_registrar(metadata_god_registrar);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_linux
|
||||
catcher
|
||||
metadata_god
|
||||
screen_retriever
|
||||
url_launcher_linux
|
||||
|
@ -8,10 +8,12 @@ import Foundation
|
||||
import audio_service
|
||||
import audio_session
|
||||
import audioplayers_darwin
|
||||
import catcher
|
||||
import connectivity_plus_macos
|
||||
import device_info_plus
|
||||
import macos_ui
|
||||
import metadata_god
|
||||
import package_info_plus_macos
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import screen_retriever
|
||||
import shared_preferences_foundation
|
||||
@ -24,7 +26,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin"))
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
CatcherPlugin.register(with: registry.registrar(forPlugin: "CatcherPlugin"))
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin"))
|
||||
MetadataGodPlugin.register(with: registry.registrar(forPlugin: "MetadataGodPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
|
97
pubspec.lock
97
pubspec.lock
@ -281,6 +281,15 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
catcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "5ccf7c0d8bbb07329667cff561aede1a9bee4934"
|
||||
url: "https://github.com/ThexXTURBOXx/catcher"
|
||||
source: git
|
||||
version: "0.7.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -428,6 +437,27 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
device_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
dio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.6"
|
||||
dots_indicator:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -599,6 +629,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_mailer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_mailer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -637,6 +674,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
fluttertoast:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fluttertoast
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.2"
|
||||
freezed_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -826,6 +870,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.6"
|
||||
mailer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mailer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
marquee:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -902,42 +953,14 @@ packages:
|
||||
name: package_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.3+1"
|
||||
package_info_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
package_info_plus_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "3.0.2"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
package_info_plus_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
package_info_plus_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.0.1"
|
||||
palette_generator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1185,6 +1208,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
sentry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.19.0"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1393,6 +1423,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: universal_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -18,6 +18,9 @@ dependencies:
|
||||
auto_size_text: ^3.0.0
|
||||
badges: ^2.0.3
|
||||
cached_network_image: ^3.2.2
|
||||
catcher:
|
||||
git:
|
||||
url: https://github.com/ThexXTURBOXx/catcher
|
||||
collection: ^1.15.0
|
||||
cupertino_icons: ^1.0.5
|
||||
dbus: ^0.7.8
|
||||
@ -47,7 +50,7 @@ dependencies:
|
||||
marquee: ^2.2.3
|
||||
metadata_god: ^0.3.2
|
||||
mime: ^1.0.2
|
||||
package_info_plus: ^1.4.3
|
||||
package_info_plus: ^3.0.2
|
||||
palette_generator: ^0.3.3
|
||||
path: ^1.8.0
|
||||
path_provider: ^2.0.8
|
||||
@ -85,6 +88,9 @@ dev_dependencies:
|
||||
sdk: flutter
|
||||
hive_generator: ^2.0.0
|
||||
|
||||
dependency_overrides:
|
||||
package_info_plus: ^3.0.2
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
assets:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||
#include <catcher/catcher_plugin.h>
|
||||
#include <connectivity_plus_windows/connectivity_plus_windows_plugin.h>
|
||||
#include <metadata_god/metadata_god_plugin_c_api.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
@ -18,6 +19,8 @@
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
CatcherPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("CatcherPlugin"));
|
||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
MetadataGodPluginCApiRegisterWithRegistrar(
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_windows
|
||||
catcher
|
||||
connectivity_plus_windows
|
||||
metadata_god
|
||||
permission_handler_windows
|
||||
|
Loading…
Reference in New Issue
Block a user