mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 21:35:32 +00:00
refactor: improve code structure and enhance UI elements in the code editor and manga detail view
This commit is contained in:
parent
494e31e396
commit
0903b9d7e3
3 changed files with 750 additions and 310 deletions
|
|
@ -1,9 +1,10 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:json_view/json_view.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.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/models/manga.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/browse/providers/browse_state_provider.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_latest_updates.dart';
|
||||
import 'package:mangayomi/services/get_popular.dart';
|
||||
import 'package:mangayomi/services/isolate_service.dart';
|
||||
import 'package:mangayomi/services/search.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:re_editor/re_editor.dart';
|
||||
import 'package:re_highlight/languages/dart.dart';
|
||||
|
|
@ -50,6 +50,29 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
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 _page = 1;
|
||||
String _query = "";
|
||||
|
|
@ -153,7 +176,37 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
final appFontFamily = ref.watch(appFontFamilyProvider);
|
||||
return Scaffold(
|
||||
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: () {
|
||||
isar.writeTxnSync(() {
|
||||
isar.sources.putSync(
|
||||
|
|
@ -172,6 +225,22 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
children: [
|
||||
Flexible(
|
||||
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(
|
||||
style: CodeEditorStyle(
|
||||
fontSize: 15,
|
||||
|
|
@ -223,27 +292,71 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
},
|
||||
sperator: Container(
|
||||
width: 1,
|
||||
color: context.dynamicThemeColor,
|
||||
color: context.dynamicThemeColor.withValues(
|
||||
alpha: 0.3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (context.isTablet)
|
||||
Flexible(
|
||||
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(
|
||||
children: [
|
||||
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)>(
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
icon: Icon(
|
||||
Icons.keyboard_arrow_down_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
isExpanded: true,
|
||||
underline: const SizedBox.shrink(),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
),
|
||||
value: _getServices(context).firstWhere(
|
||||
(element) => element.$2 == _serviceIndex,
|
||||
),
|
||||
hint: Text(
|
||||
_getServices(context)
|
||||
.firstWhere(
|
||||
(element) => element.$2 == _serviceIndex,
|
||||
(element) =>
|
||||
element.$2 == _serviceIndex,
|
||||
)
|
||||
.$1,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
|
|
@ -252,9 +365,21 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
.map(
|
||||
(e) => DropdownMenuItem(
|
||||
value: e,
|
||||
child: Text(
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
_getServiceIcon(e.$2),
|
||||
size: 18,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
e.$1,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -266,6 +391,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_serviceIndex == 0 ||
|
||||
_serviceIndex == 1 ||
|
||||
_serviceIndex == 2)
|
||||
|
|
@ -273,28 +399,59 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
_page = int.tryParse(v) ?? 1;
|
||||
}),
|
||||
if (_serviceIndex == 2)
|
||||
_textEditing("Query", context, "ex: one piece", (v) {
|
||||
_textEditing("Query", context, "ex: one piece", (
|
||||
v,
|
||||
) {
|
||||
_query = v;
|
||||
}),
|
||||
if (_serviceIndex == 3 ||
|
||||
_serviceIndex == 4 ||
|
||||
_serviceIndex == 5 ||
|
||||
_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,
|
||||
) {
|
||||
_url = v;
|
||||
}),
|
||||
if (_serviceIndex == 7)
|
||||
_textEditing("Html", context, "ex. <p>Text</p>", (v) {
|
||||
_html = v;
|
||||
}),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
alignment: WrapAlignment.center,
|
||||
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 {
|
||||
source?.sourceCode = _controller.text;
|
||||
if (source != null && context.mounted) {
|
||||
|
|
@ -313,45 +470,62 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
_errorText = "";
|
||||
});
|
||||
if (source != null) {
|
||||
final proxyServer = ref.read(
|
||||
androidProxyServerStateProvider,
|
||||
);
|
||||
final service = getExtensionService(
|
||||
source!,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
proxyServer,
|
||||
);
|
||||
|
||||
try {
|
||||
if (_serviceIndex == 0) {
|
||||
final getManga = await ref.watch(
|
||||
getPopularProvider(
|
||||
source: source!,
|
||||
final getManga =
|
||||
await getIsolateService.get<
|
||||
MPages?
|
||||
>(
|
||||
page: _page,
|
||||
).future,
|
||||
source: source,
|
||||
serviceType: 'getPopular',
|
||||
proxyServer: ref.read(
|
||||
androidProxyServerStateProvider,
|
||||
),
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 1) {
|
||||
final getManga = await ref.watch(
|
||||
getLatestUpdatesProvider(
|
||||
source: source!,
|
||||
final getManga =
|
||||
await getIsolateService.get<
|
||||
MPages?
|
||||
>(
|
||||
page: _page,
|
||||
).future,
|
||||
source: source,
|
||||
serviceType: 'getLatestUpdates',
|
||||
proxyServer: ref.read(
|
||||
androidProxyServerStateProvider,
|
||||
),
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 2) {
|
||||
final getManga = await ref.watch(
|
||||
searchProvider(
|
||||
source: source!,
|
||||
final getManga =
|
||||
await getIsolateService
|
||||
.get<MPages?>(
|
||||
query: _query,
|
||||
page: _page,
|
||||
filterList: filterList,
|
||||
).future,
|
||||
source: source,
|
||||
page: _page,
|
||||
serviceType: 'search',
|
||||
proxyServer: proxyServer,
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 3) {
|
||||
final getManga = await ref.watch(
|
||||
getDetailProvider(
|
||||
source: source!,
|
||||
final getManga =
|
||||
await getIsolateService
|
||||
.get<MManga>(
|
||||
url: _url,
|
||||
).future,
|
||||
source: source,
|
||||
serviceType: 'getDetail',
|
||||
proxyServer: proxyServer,
|
||||
);
|
||||
|
||||
result = getManga.toJson();
|
||||
} else if (_serviceIndex == 4) {
|
||||
result = {
|
||||
|
|
@ -364,10 +538,8 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
_url,
|
||||
)).map((e) => e.toJson()).toList();
|
||||
} else if (_serviceIndex == 6) {
|
||||
result = (await service.getHtmlContent(
|
||||
"test",
|
||||
_url,
|
||||
));
|
||||
result = (await service
|
||||
.getHtmlContent("test", _url));
|
||||
} else {
|
||||
result = (await service
|
||||
.cleanHtmlContent(_html));
|
||||
|
|
@ -388,11 +560,34 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
}
|
||||
}
|
||||
},
|
||||
child: const Text("Execute"),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: ElevatedButton(
|
||||
OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
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: () {
|
||||
setState(() {
|
||||
result = null;
|
||||
|
|
@ -402,11 +597,31 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
filters = [];
|
||||
});
|
||||
},
|
||||
child: Text(context.l10n.reset),
|
||||
),
|
||||
),
|
||||
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 {
|
||||
if (source != null) {
|
||||
setState(() {
|
||||
|
|
@ -418,7 +633,9 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
if (filters.isEmpty) {
|
||||
filters = filterList;
|
||||
}
|
||||
final res = await filterDialog(context);
|
||||
final res = await filterDialog(
|
||||
context,
|
||||
);
|
||||
if (res == 'filter' &&
|
||||
context.mounted) {
|
||||
setState(() {
|
||||
|
|
@ -449,68 +666,255 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
}
|
||||
}
|
||||
},
|
||||
child: Text(context.l10n.filter),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: _error
|
||||
? SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(_errorText)],
|
||||
? Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Center(
|
||||
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
|
||||
? 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
|
||||
? JsonConfig(
|
||||
? Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: JsonConfig(
|
||||
data: JsonConfigData(
|
||||
gap: 100,
|
||||
style: const JsonStyleScheme(
|
||||
quotation: JsonQuotation.same('"'),
|
||||
openAtStart: false,
|
||||
arrow: Icon(Icons.arrow_forward),
|
||||
arrow: Icon(
|
||||
Icons.arrow_forward_rounded,
|
||||
),
|
||||
depth: 4,
|
||||
),
|
||||
color: const JsonColorScheme(),
|
||||
),
|
||||
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)
|
||||
Container(
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white, width: 0.5),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: Colors.black,
|
||||
border: Border.all(
|
||||
color: context.primaryColor.withValues(alpha: 0.3),
|
||||
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,
|
||||
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(
|
||||
valueListenable: _logsNotifier,
|
||||
builder: (context, logs, child) => SuperListView.separated(
|
||||
separatorBuilder: (context, index) => const Divider(),
|
||||
builder: (context, logs, child) => logs.isEmpty
|
||||
? 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,
|
||||
padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.all(12),
|
||||
itemCount: logs.length,
|
||||
itemBuilder: (context, index) {
|
||||
final value = logs[index];
|
||||
return SelectableText(
|
||||
value.$2,
|
||||
style: TextStyle(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
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
|
||||
? Colors.yellow
|
||||
: 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,
|
||||
) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
child: TextFormField(
|
||||
keyboardType: label == "Page" ? TextInputType.number : TextInputType.text,
|
||||
onChanged: onChanged,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
labelText: label,
|
||||
isDense: 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(
|
||||
borderSide: BorderSide(color: context.dynamicThemeColor),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: context.dynamicThemeColor.withValues(alpha: 0.3),
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: context.dynamicThemeColor),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(color: context.primaryColor, width: 2),
|
||||
),
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -661,8 +661,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
widget.manga!.source!,
|
||||
widget.manga!.sourceId,
|
||||
);
|
||||
if (source == null) return;
|
||||
final url =
|
||||
"${source!.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
|
||||
"${source.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
|
||||
final box =
|
||||
context.findRenderObject() as RenderBox?;
|
||||
SharePlus.instance.share(
|
||||
|
|
@ -683,6 +684,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
widget.manga!.source!,
|
||||
widget.manga!.sourceId,
|
||||
);
|
||||
if (source == null) return;
|
||||
context.push(
|
||||
'/extension_detail',
|
||||
extra: source,
|
||||
|
|
@ -1954,8 +1956,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
widget.manga!.source!,
|
||||
widget.manga!.sourceId,
|
||||
);
|
||||
if (source == null) return;
|
||||
final url =
|
||||
"${source!.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
|
||||
"${source.baseUrl}${widget.manga!.link!.getUrlWithoutDomain}";
|
||||
|
||||
Map<String, dynamic> data = {
|
||||
'url': url,
|
||||
|
|
|
|||
|
|
@ -140,12 +140,12 @@ SPEC CHECKSUMS:
|
|||
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
|
||||
rust_lib_mangayomi: 4cbf39f5d158ad8eb0f17fd8e52d88514d435cd8
|
||||
screen_brightness_macos: 2a3ee243f8051c340381e8e51bcedced8360f421
|
||||
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
|
||||
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
|
||||
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
|
||||
url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd
|
||||
volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd
|
||||
wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b
|
||||
window_manager: b729e31d38fb04905235df9ea896128991cad99e
|
||||
|
|
|
|||
Loading…
Reference in a new issue