refactor: improve code structure and enhance UI elements in the code editor and manga detail view

This commit is contained in:
Moustapha Kodjo Amadou 2025-11-11 10:38:27 +01:00
parent 494e31e396
commit 0903b9d7e3
3 changed files with 750 additions and 310 deletions

View file

@ -1,9 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:json_view/json_view.dart'; import 'package:json_view/json_view.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/lib.dart'; import 'package:mangayomi/eval/lib.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/models/source.dart';
@ -11,12 +12,11 @@ import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/app_font_family.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/app_font_family.dart';
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart'; import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/services/get_detail.dart';
import 'package:mangayomi/services/get_filter_list.dart'; import 'package:mangayomi/services/get_filter_list.dart';
import 'package:mangayomi/services/get_latest_updates.dart'; import 'package:mangayomi/services/isolate_service.dart';
import 'package:mangayomi/services/get_popular.dart';
import 'package:mangayomi/services/search.dart'; import 'package:mangayomi/services/search.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart'; import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
import 'package:mangayomi/utils/language.dart';
import 'package:mangayomi/utils/log/log.dart'; import 'package:mangayomi/utils/log/log.dart';
import 'package:re_editor/re_editor.dart'; import 'package:re_editor/re_editor.dart';
import 'package:re_highlight/languages/dart.dart'; import 'package:re_highlight/languages/dart.dart';
@ -50,6 +50,29 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
if (source?.itemType == ItemType.novel) ("cleanHtmlContent", 7), if (source?.itemType == ItemType.novel) ("cleanHtmlContent", 7),
]; ];
IconData _getServiceIcon(int index) {
switch (index) {
case 0:
return Icons.star_rounded;
case 1:
return Icons.update_rounded;
case 2:
return Icons.search_rounded;
case 3:
return Icons.info_outline_rounded;
case 4:
return Icons.image_rounded;
case 5:
return Icons.video_library_rounded;
case 6:
return Icons.article_rounded;
case 7:
return Icons.cleaning_services_rounded;
default:
return Icons.code_rounded;
}
}
int _serviceIndex = 0; int _serviceIndex = 0;
int _page = 1; int _page = 1;
String _query = ""; String _query = "";
@ -153,7 +176,37 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
final appFontFamily = ref.watch(appFontFamilyProvider); final appFontFamily = ref.watch(appFontFamilyProvider);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
leading: BackButton( elevation: 0,
title: Row(
children: [
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
source?.name ?? 'Code Editor',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
if (source != null)
Text(
completeLanguageName(source!.lang ?? ''),
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
fontWeight: FontWeight.normal,
),
),
],
),
),
],
),
leading: IconButton(
icon: const Icon(Icons.arrow_back_rounded),
onPressed: () { onPressed: () {
isar.writeTxnSync(() { isar.writeTxnSync(() {
isar.sources.putSync( isar.sources.putSync(
@ -172,6 +225,22 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
children: [ children: [
Flexible( Flexible(
flex: 7, flex: 7,
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: context.primaryColor.withValues(alpha: 0.2),
width: 1,
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12),
bottomLeft: Radius.circular(12),
),
),
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12),
bottomLeft: Radius.circular(12),
),
child: CodeEditor( child: CodeEditor(
style: CodeEditorStyle( style: CodeEditorStyle(
fontSize: 15, fontSize: 15,
@ -223,27 +292,71 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
}, },
sperator: Container( sperator: Container(
width: 1, width: 1,
color: context.dynamicThemeColor, color: context.dynamicThemeColor.withValues(
alpha: 0.3,
),
),
),
), ),
), ),
), ),
if (context.isTablet) if (context.isTablet)
Flexible( Flexible(
flex: 3, flex: 3,
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: context.primaryColor.withValues(alpha: 0.2),
width: 1,
),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(12),
bottomRight: Radius.circular(12),
),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
context.primaryColor.withValues(alpha: 0.03),
Colors.transparent,
],
),
),
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(12),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: context.primaryColor.withValues(
alpha: 0.3,
),
width: 1.5,
),
color: context.primaryColor.withValues(
alpha: 0.05,
),
),
child: DropdownButton<(String, int)>( child: DropdownButton<(String, int)>(
icon: const Icon(Icons.keyboard_arrow_down), icon: Icon(
Icons.keyboard_arrow_down_rounded,
color: context.primaryColor,
),
isExpanded: true, isExpanded: true,
underline: const SizedBox.shrink(),
padding: const EdgeInsets.symmetric(
horizontal: 12,
),
value: _getServices(context).firstWhere( value: _getServices(context).firstWhere(
(element) => element.$2 == _serviceIndex, (element) => element.$2 == _serviceIndex,
), ),
hint: Text( hint: Text(
_getServices(context) _getServices(context)
.firstWhere( .firstWhere(
(element) => element.$2 == _serviceIndex, (element) =>
element.$2 == _serviceIndex,
) )
.$1, .$1,
style: const TextStyle(fontSize: 13), style: const TextStyle(fontSize: 13),
@ -252,9 +365,21 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
.map( .map(
(e) => DropdownMenuItem( (e) => DropdownMenuItem(
value: e, value: e,
child: Text( child: Row(
children: [
Icon(
_getServiceIcon(e.$2),
size: 18,
color: context.primaryColor,
),
const SizedBox(width: 10),
Text(
e.$1, e.$1,
style: const TextStyle(fontSize: 13), style: const TextStyle(
fontSize: 13,
),
),
],
), ),
), ),
) )
@ -266,6 +391,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
}, },
), ),
), ),
),
if (_serviceIndex == 0 || if (_serviceIndex == 0 ||
_serviceIndex == 1 || _serviceIndex == 1 ||
_serviceIndex == 2) _serviceIndex == 2)
@ -273,28 +399,59 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
_page = int.tryParse(v) ?? 1; _page = int.tryParse(v) ?? 1;
}), }),
if (_serviceIndex == 2) if (_serviceIndex == 2)
_textEditing("Query", context, "ex: one piece", (v) { _textEditing("Query", context, "ex: one piece", (
v,
) {
_query = v; _query = v;
}), }),
if (_serviceIndex == 3 || if (_serviceIndex == 3 ||
_serviceIndex == 4 || _serviceIndex == 4 ||
_serviceIndex == 5 || _serviceIndex == 5 ||
_serviceIndex == 6) _serviceIndex == 6)
_textEditing("Url", context, "ex: url of the entry", ( _textEditing(
"Url",
context,
"ex: url of the entry",
(v) {
_url = v;
},
),
if (_serviceIndex == 7)
_textEditing("Html", context, "ex. <p>Text</p>", (
v, v,
) { ) {
_url = v;
}),
if (_serviceIndex == 7)
_textEditing("Html", context, "ex. <p>Text</p>", (v) {
_html = v; _html = v;
}), }),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(12),
child: Wrap( child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center, spacing: 8,
runSpacing: 8,
alignment: WrapAlignment.center,
children: [ children: [
ElevatedButton( FilledButton.icon(
style: FilledButton.styleFrom(
backgroundColor: context.primaryColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
),
icon: const Icon(
Icons.play_arrow_rounded,
size: 20,
),
label: const Text(
"Execute",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onPressed: () async { onPressed: () async {
source?.sourceCode = _controller.text; source?.sourceCode = _controller.text;
if (source != null && context.mounted) { if (source != null && context.mounted) {
@ -313,45 +470,62 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
_errorText = ""; _errorText = "";
}); });
if (source != null) { if (source != null) {
final proxyServer = ref.read(
androidProxyServerStateProvider,
);
final service = getExtensionService( final service = getExtensionService(
source!, source!,
ref.read(androidProxyServerStateProvider), proxyServer,
); );
try { try {
if (_serviceIndex == 0) { if (_serviceIndex == 0) {
final getManga = await ref.watch( final getManga =
getPopularProvider( await getIsolateService.get<
source: source!, MPages?
>(
page: _page, page: _page,
).future, source: source,
serviceType: 'getPopular',
proxyServer: ref.read(
androidProxyServerStateProvider,
),
); );
result = getManga!.toJson(); result = getManga!.toJson();
} else if (_serviceIndex == 1) { } else if (_serviceIndex == 1) {
final getManga = await ref.watch( final getManga =
getLatestUpdatesProvider( await getIsolateService.get<
source: source!, MPages?
>(
page: _page, page: _page,
).future, source: source,
serviceType: 'getLatestUpdates',
proxyServer: ref.read(
androidProxyServerStateProvider,
),
); );
result = getManga!.toJson(); result = getManga!.toJson();
} else if (_serviceIndex == 2) { } else if (_serviceIndex == 2) {
final getManga = await ref.watch( final getManga =
searchProvider( await getIsolateService
source: source!, .get<MPages?>(
query: _query, query: _query,
page: _page,
filterList: filterList, filterList: filterList,
).future, source: source,
page: _page,
serviceType: 'search',
proxyServer: proxyServer,
); );
result = getManga!.toJson(); result = getManga!.toJson();
} else if (_serviceIndex == 3) { } else if (_serviceIndex == 3) {
final getManga = await ref.watch( final getManga =
getDetailProvider( await getIsolateService
source: source!, .get<MManga>(
url: _url, url: _url,
).future, source: source,
serviceType: 'getDetail',
proxyServer: proxyServer,
); );
result = getManga.toJson(); result = getManga.toJson();
} else if (_serviceIndex == 4) { } else if (_serviceIndex == 4) {
result = { result = {
@ -364,10 +538,8 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
_url, _url,
)).map((e) => e.toJson()).toList(); )).map((e) => e.toJson()).toList();
} else if (_serviceIndex == 6) { } else if (_serviceIndex == 6) {
result = (await service.getHtmlContent( result = (await service
"test", .getHtmlContent("test", _url));
_url,
));
} else { } else {
result = (await service result = (await service
.cleanHtmlContent(_html)); .cleanHtmlContent(_html));
@ -388,11 +560,34 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
} }
} }
}, },
child: const Text("Execute"),
), ),
Padding( OutlinedButton.icon(
padding: const EdgeInsets.all(10), style: OutlinedButton.styleFrom(
child: ElevatedButton( foregroundColor: context.primaryColor,
side: BorderSide(
color: context.primaryColor.withValues(
alpha: 0.5,
),
width: 1.5,
),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
icon: const Icon(
Icons.refresh_rounded,
size: 20,
),
label: Text(
context.l10n.reset,
style: const TextStyle(
fontWeight: FontWeight.w600,
),
),
onPressed: () { onPressed: () {
setState(() { setState(() {
result = null; result = null;
@ -402,11 +597,31 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
filters = []; filters = [];
}); });
}, },
child: Text(context.l10n.reset),
),
), ),
if (_serviceIndex == 2 && filterList.isNotEmpty) if (_serviceIndex == 2 && filterList.isNotEmpty)
ElevatedButton( FilledButton.tonalIcon(
style: FilledButton.styleFrom(
backgroundColor: context.primaryColor
.withValues(alpha: 0.15),
foregroundColor: context.primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
icon: const Icon(
Icons.filter_alt_rounded,
size: 20,
),
label: Text(
context.l10n.filter,
style: const TextStyle(
fontWeight: FontWeight.w600,
),
),
onPressed: () async { onPressed: () async {
if (source != null) { if (source != null) {
setState(() { setState(() {
@ -418,7 +633,9 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
if (filters.isEmpty) { if (filters.isEmpty) {
filters = filterList; filters = filterList;
} }
final res = await filterDialog(context); final res = await filterDialog(
context,
);
if (res == 'filter' && if (res == 'filter' &&
context.mounted) { context.mounted) {
setState(() { setState(() {
@ -449,68 +666,255 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
} }
} }
}, },
child: Text(context.l10n.filter),
), ),
], ],
), ),
), ),
const Divider(height: 1),
Expanded( Expanded(
child: _error child: _error
? SingleChildScrollView( ? Container(
child: Column( padding: const EdgeInsets.all(20),
mainAxisAlignment: MainAxisAlignment.center, child: Center(
children: [Text(_errorText)], child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.red.withValues(
alpha: 0.1,
),
borderRadius: BorderRadius.circular(
12,
),
border: Border.all(
color: Colors.red.withValues(
alpha: 0.3,
),
width: 1,
),
),
child: SelectableText(
_errorText,
style: const TextStyle(
fontSize: 12,
fontFamily: 'monospace',
),
),
),
), ),
) )
: _isLoading : _isLoading
? const Center(child: CircularProgressIndicator()) ? Center(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
CircularProgressIndicator(
color: context.primaryColor,
),
const SizedBox(height: 16),
Text(
'Executing...',
style: TextStyle(
color: context.primaryColor,
fontWeight: FontWeight.w500,
),
),
],
),
)
: result != null : result != null
? JsonConfig( ? Container(
padding: const EdgeInsets.all(12),
child: JsonConfig(
data: JsonConfigData( data: JsonConfigData(
gap: 100, gap: 100,
style: const JsonStyleScheme( style: const JsonStyleScheme(
quotation: JsonQuotation.same('"'), quotation: JsonQuotation.same('"'),
openAtStart: false, openAtStart: false,
arrow: Icon(Icons.arrow_forward), arrow: Icon(
Icons.arrow_forward_rounded,
),
depth: 4, depth: 4,
), ),
color: const JsonColorScheme(), color: const JsonColorScheme(),
), ),
child: JsonView(json: result), child: JsonView(json: result),
),
) )
: const SizedBox.shrink(), : Center(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Icon(
Icons.data_object_rounded,
size: 64,
color: Colors.grey.withValues(
alpha: 0.5,
),
),
const SizedBox(height: 16),
Text(
'No results yet',
style: TextStyle(
color: Colors.grey.withValues(
alpha: 0.7,
),
fontSize: 15,
),
),
const SizedBox(height: 8),
Text(
'Execute a service to see results',
style: TextStyle(
color: Colors.grey.withValues(
alpha: 0.5,
),
fontSize: 12,
),
), ),
], ],
), ),
), ),
),
],
),
),
),
], ],
), ),
), ),
if (context.isTablet) if (context.isTablet)
Container( Padding(
padding: const EdgeInsets.all(12),
child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 0.5), border: Border.all(
borderRadius: BorderRadius.circular(5), color: context.primaryColor.withValues(alpha: 0.3),
color: Colors.black, width: 1.5,
),
borderRadius: BorderRadius.circular(12),
color: Colors.black,
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.2),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
), ),
width: context.width(1),
height: 200, height: 200,
child: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
border: Border(
bottom: BorderSide(
color: context.primaryColor.withValues(alpha: 0.3),
width: 1,
),
),
),
child: Row(
children: [
Icon(
Icons.terminal_rounded,
size: 18,
color: context.primaryColor,
),
const SizedBox(width: 8),
Text(
'Console Logs',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: context.primaryColor,
),
),
const Spacer(),
IconButton(
icon: const Icon(
Icons.clear_all_rounded,
size: 18,
color: Colors.grey,
),
tooltip: 'Clear logs',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () {
setState(() {
_logsNotifier.value.clear();
});
},
),
],
),
),
Expanded(
child: ValueListenableBuilder( child: ValueListenableBuilder(
valueListenable: _logsNotifier, valueListenable: _logsNotifier,
builder: (context, logs, child) => SuperListView.separated( builder: (context, logs, child) => logs.isEmpty
separatorBuilder: (context, index) => const Divider(), ? Center(
child: Text(
'No logs yet',
style: TextStyle(
color: Colors.grey.withValues(alpha: 0.5),
fontSize: 12,
),
),
)
: SuperListView.separated(
separatorBuilder: (context, index) => Divider(
height: 1,
color: Colors.grey.withValues(alpha: 0.2),
),
controller: _scrollController, controller: _scrollController,
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(12),
itemCount: logs.length, itemCount: logs.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final value = logs[index]; final value = logs[index];
return SelectableText( return Padding(
value.$2, padding: const EdgeInsets.symmetric(
style: TextStyle( vertical: 4,
),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Icon(
value.$1 == LoggerLevel.info
? Icons.info_outline_rounded
: Icons.bug_report_rounded,
size: 14,
color: value.$1 == LoggerLevel.info color: value.$1 == LoggerLevel.info
? Colors.yellow ? Colors.yellow
: Colors.blueAccent, : Colors.blueAccent,
), ),
const SizedBox(width: 8),
Expanded(
child: SelectableText(
value.$2,
style: TextStyle(
fontSize: 11,
fontFamily: 'monospace',
color:
value.$1 == LoggerLevel.info
? Colors.yellow
: Colors.blueAccent,
),
),
),
],
),
); );
}, },
), ),
@ -518,6 +922,10 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
), ),
], ],
), ),
),
),
],
),
); );
} }
} }
@ -529,24 +937,53 @@ Widget _textEditing(
void Function(String)? onChanged, void Function(String)? onChanged,
) { ) {
return Padding( return Padding(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
child: TextFormField( child: TextFormField(
keyboardType: label == "Page" ? TextInputType.number : TextInputType.text, keyboardType: label == "Page" ? TextInputType.number : TextInputType.text,
onChanged: onChanged, onChanged: onChanged,
style: const TextStyle(fontSize: 13),
decoration: InputDecoration( decoration: InputDecoration(
hintText: hintText, hintText: hintText,
labelText: label, labelText: label,
isDense: true, isDense: true,
filled: true, filled: true,
fillColor: Colors.transparent, fillColor: context.primaryColor.withValues(alpha: 0.05),
prefixIcon: Icon(
label == "Page"
? Icons.numbers_rounded
: label == "Query"
? Icons.search_rounded
: label == "Url"
? Icons.link_rounded
: Icons.code_rounded,
size: 20,
color: context.primaryColor,
),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: context.dynamicThemeColor), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: context.dynamicThemeColor.withValues(alpha: 0.3),
width: 1.5,
),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: context.dynamicThemeColor), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: context.primaryColor, width: 2),
), ),
border: OutlineInputBorder( border: OutlineInputBorder(
borderSide: BorderSide(color: context.dynamicThemeColor), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: context.dynamicThemeColor.withValues(alpha: 0.3),
width: 1.5,
),
),
labelStyle: TextStyle(
fontSize: 12,
color: context.primaryColor.withValues(alpha: 0.7),
),
hintStyle: TextStyle(
fontSize: 12,
color: Colors.grey.withValues(alpha: 0.5),
), ),
), ),
), ),

View file

@ -661,8 +661,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
widget.manga!.source!, widget.manga!.source!,
widget.manga!.sourceId, widget.manga!.sourceId,
); );
if (source == null) return;
final url = final url =
"${source!.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}"; "${source.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
final box = final box =
context.findRenderObject() as RenderBox?; context.findRenderObject() as RenderBox?;
SharePlus.instance.share( SharePlus.instance.share(
@ -683,6 +684,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
widget.manga!.source!, widget.manga!.source!,
widget.manga!.sourceId, widget.manga!.sourceId,
); );
if (source == null) return;
context.push( context.push(
'/extension_detail', '/extension_detail',
extra: source, extra: source,
@ -1954,8 +1956,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
widget.manga!.source!, widget.manga!.source!,
widget.manga!.sourceId, widget.manga!.sourceId,
); );
if (source == null) return;
final url = final url =
"${source!.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}"; "${source.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
Map<String, dynamic> data = { Map<String, dynamic> data = {
'url': url, 'url': url,

View file

@ -140,12 +140,12 @@ SPEC CHECKSUMS:
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758 media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: f0052d280d17aa382b932f399edf32507174e870 package_info_plus: f0052d280d17aa382b932f399edf32507174e870
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
rust_lib_mangayomi: 4cbf39f5d158ad8eb0f17fd8e52d88514d435cd8 rust_lib_mangayomi: 4cbf39f5d158ad8eb0f17fd8e52d88514d435cd8
screen_brightness_macos: 2a3ee243f8051c340381e8e51bcedced8360f421 screen_brightness_macos: 2a3ee243f8051c340381e8e51bcedced8360f421
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd
volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd
wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b
window_manager: b729e31d38fb04905235df9ea896128991cad99e window_manager: b729e31d38fb04905235df9ea896128991cad99e