mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
- Remove unnecessary email and password state variables - Rely on TextEditingController values instead of onChanged - Reset error state on submit - Dispose controllers after dialog closes
318 lines
12 KiB
Dart
318 lines
12 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:isar_community/isar.dart';
|
|
import 'package:mangayomi/main.dart';
|
|
import 'package:mangayomi/models/track_preference.dart';
|
|
import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart';
|
|
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
|
|
import 'package:mangayomi/modules/more/widgets/list_tile_widget.dart';
|
|
import 'package:mangayomi/modules/tracker_library/tracker_library_screen.dart';
|
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
|
import 'package:mangayomi/services/trackers/anilist.dart';
|
|
import 'package:mangayomi/services/trackers/kitsu.dart';
|
|
import 'package:mangayomi/services/trackers/myanimelist.dart';
|
|
import 'package:mangayomi/services/trackers/simkl.dart';
|
|
import 'package:mangayomi/services/trackers/trakt_tv.dart';
|
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
|
|
|
class TrackScreen extends ConsumerWidget {
|
|
const TrackScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final updateProgressAfterReading = ref.watch(
|
|
updateProgressAfterReadingStateProvider,
|
|
);
|
|
final l10n = l10nLocalizations(context)!;
|
|
return Scaffold(
|
|
appBar: AppBar(title: Text(l10nLocalizations(context)!.tracking)),
|
|
body: SingleChildScrollView(
|
|
child: StreamBuilder(
|
|
stream: isar.trackPreferences.filter().syncIdIsNotNull().watch(
|
|
fireImmediately: true,
|
|
),
|
|
builder: (context, snapshot) {
|
|
List<TrackPreference>? entries = snapshot.hasData
|
|
? snapshot.data
|
|
: [];
|
|
return Column(
|
|
children: [
|
|
SwitchListTile(
|
|
value: updateProgressAfterReading,
|
|
title: Text(context.l10n.updateProgressAfterReading),
|
|
onChanged: (value) {
|
|
ref
|
|
.read(updateProgressAfterReadingStateProvider.notifier)
|
|
.set(value);
|
|
},
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(
|
|
left: 15,
|
|
right: 15,
|
|
bottom: 10,
|
|
top: 5,
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Text(
|
|
l10n.services,
|
|
style: TextStyle(
|
|
fontSize: 13,
|
|
color: context.primaryColor,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
TrackListile(
|
|
onTap: () async {
|
|
await ref
|
|
.read(
|
|
anilistProvider(
|
|
syncId: TrackerProviders.anilist.syncId,
|
|
widgetRef: ref,
|
|
).notifier,
|
|
)
|
|
.login();
|
|
},
|
|
id: TrackerProviders.anilist.syncId,
|
|
entries: entries!,
|
|
),
|
|
TrackListile(
|
|
onTap: () => _showDialogLogin(context, ref),
|
|
id: TrackerProviders.kitsu.syncId,
|
|
entries: entries,
|
|
),
|
|
TrackListile(
|
|
onTap: () async {
|
|
await ref
|
|
.read(
|
|
myAnimeListProvider(
|
|
syncId: TrackerProviders.myAnimeList.syncId,
|
|
itemType: null,
|
|
widgetRef: ref,
|
|
).notifier,
|
|
)
|
|
.login();
|
|
},
|
|
id: TrackerProviders.myAnimeList.syncId,
|
|
entries: entries,
|
|
),
|
|
TrackListile(
|
|
onTap: () async {
|
|
await ref
|
|
.read(
|
|
simklProvider(
|
|
syncId: TrackerProviders.simkl.syncId,
|
|
itemType: null,
|
|
widgetRef: ref,
|
|
).notifier,
|
|
)
|
|
.login();
|
|
},
|
|
id: TrackerProviders.simkl.syncId,
|
|
entries: entries,
|
|
),
|
|
TrackListile(
|
|
onTap: () async {
|
|
await ref
|
|
.read(
|
|
traktTvProvider(
|
|
syncId: TrackerProviders.trakt.syncId,
|
|
itemType: null,
|
|
widgetRef: ref,
|
|
).notifier,
|
|
)
|
|
.login();
|
|
},
|
|
id: TrackerProviders.trakt.syncId,
|
|
entries: entries,
|
|
),
|
|
ListTile(
|
|
title: Padding(
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
Icons.info_outline_rounded,
|
|
color: context.secondaryColor,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
subtitle: Text(
|
|
l10n.tracking_warning_info,
|
|
style: TextStyle(
|
|
fontSize: 11,
|
|
color: context.secondaryColor,
|
|
),
|
|
),
|
|
),
|
|
ListTileWidget(
|
|
title: l10n.manage_trackers,
|
|
icon: Icons.settings,
|
|
onTap: () => context.push('/manageTrackers'),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _showDialogLogin(BuildContext context, WidgetRef ref) async {
|
|
final passwordController = TextEditingController();
|
|
final emailController = TextEditingController();
|
|
String errorMessage = "";
|
|
bool isLoading = false;
|
|
bool obscureText = true;
|
|
final l10n = l10nLocalizations(context)!;
|
|
await showDialog(
|
|
context: context,
|
|
builder: (context) => StatefulBuilder(
|
|
builder: (context, setState) {
|
|
return AlertDialog(
|
|
title: Text(
|
|
l10n.login_into("Kitsu"),
|
|
style: const TextStyle(fontSize: 30),
|
|
),
|
|
content: SizedBox(
|
|
height: 300,
|
|
width: MediaQuery.of(context).size.width,
|
|
child: AutofillGroup(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const SizedBox(height: 10),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: TextFormField(
|
|
controller: emailController,
|
|
keyboardType: TextInputType.emailAddress,
|
|
textInputAction: TextInputAction.next,
|
|
autofillHints: const [
|
|
AutofillHints.email,
|
|
AutofillHints.username,
|
|
],
|
|
autofocus: true,
|
|
onFieldSubmitted: (_) =>
|
|
FocusScope.of(context).nextFocus(),
|
|
decoration: InputDecoration(
|
|
hintText: l10n.email_adress,
|
|
filled: false,
|
|
contentPadding: const EdgeInsets.all(12),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderSide: const BorderSide(width: 0.4),
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderSide: const BorderSide(),
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(5),
|
|
borderSide: const BorderSide(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 10),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: TextFormField(
|
|
controller: passwordController,
|
|
obscureText: obscureText,
|
|
keyboardType: TextInputType.visiblePassword,
|
|
textInputAction: TextInputAction.done,
|
|
enableSuggestions: false,
|
|
autocorrect: false,
|
|
autofillHints: const [AutofillHints.password],
|
|
decoration: InputDecoration(
|
|
hintText: l10n.password,
|
|
suffixIcon: IconButton(
|
|
onPressed: () => setState(() {
|
|
obscureText = !obscureText;
|
|
}),
|
|
icon: Icon(
|
|
obscureText
|
|
? Icons.visibility_outlined
|
|
: Icons.visibility_off_outlined,
|
|
),
|
|
),
|
|
filled: false,
|
|
contentPadding: const EdgeInsets.all(12),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderSide: const BorderSide(width: 0.4),
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderSide: const BorderSide(),
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(5),
|
|
borderSide: const BorderSide(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 10),
|
|
Text(errorMessage, style: const TextStyle(color: Colors.red)),
|
|
const SizedBox(height: 10),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
child: SizedBox(
|
|
width: context.width(1),
|
|
height: 50,
|
|
child: ElevatedButton(
|
|
onPressed: isLoading
|
|
? null
|
|
: () async {
|
|
setState(() {
|
|
isLoading = true;
|
|
errorMessage = "";
|
|
});
|
|
final email = emailController.text.trim();
|
|
final password = passwordController.text;
|
|
final res = await ref
|
|
.read(
|
|
kitsuProvider(
|
|
syncId: TrackerProviders.kitsu.syncId,
|
|
widgetRef: ref,
|
|
).notifier,
|
|
)
|
|
.login(email, password);
|
|
if (!res.$1) {
|
|
setState(() {
|
|
isLoading = false;
|
|
errorMessage = res.$2;
|
|
});
|
|
} else {
|
|
TextInput.finishAutofillContext();
|
|
if (context.mounted) {
|
|
Navigator.pop(context);
|
|
}
|
|
}
|
|
},
|
|
child: isLoading
|
|
? const CircularProgressIndicator()
|
|
: Text(l10n.login),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
emailController.dispose();
|
|
passwordController.dispose();
|
|
}
|