import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:isekai_wiki/api/mw/list.dart'; import 'package:isekai_wiki/api/mw/mw_api.dart'; import 'package:isekai_wiki/api/response/page_info.dart'; import 'package:isekai_wiki/components/responsive_pair.dart'; import 'package:isekai_wiki/components/isekai_nav_bar.dart'; import 'package:isekai_wiki/components/isekai_page_scaffold.dart'; import 'package:isekai_wiki/global.dart'; import 'package:isekai_wiki/reactive/reactive.dart'; import 'package:isekai_wiki/utils/dialog.dart'; import 'package:isekai_wiki/utils/error.dart'; class WikiInfoPageController extends GetxController { var pageTitle = "".obs; var pageId = 0.obs; var pageInfo = Rx<PageInfo?>(null); var loadingPageInfo = true.obs; @override void onInit() { super.onInit(); Future.delayed(const Duration(milliseconds: 150)).then((_) { loadPageInfo(); }); } Future<void> loadPageInfo() async { if (pageTitle.isNotEmpty || pageId.value != 0) { try { // 加载页面信息 loadingPageInfo.value = true; MWResponse<List<PageInfo>> pageInfoRes; if (pageId.value != 0) { pageInfoRes = await MWApiList.getPageInfoList(pageids: [ pageId.value ], prop: [ "info", "pageimages", "pageviews" ], extraParams: { "inprop": "url|protection|watched|watchers|visitingwatchers|displaytitle", }); } else { pageInfoRes = await MWApiList.getPageInfoList(titles: [pageTitle.value]); } if (pageInfoRes.data.isEmpty) { throw MWApiErrorException(code: 'no-page', info: "页面信息丢失"); } pageInfo.value = pageInfoRes.data[0]; pageId.value = pageInfo.value!.pageid; pageTitle.value = pageInfo.value!.title; } catch (err, stack) { alert(Get.overlayContext!, ErrorUtils.getErrorMessage(err), title: "错误"); if (kDebugMode) { print("Exception in page: $err"); stack.printError(); } } finally { loadingPageInfo.value = false; } } else { alert(Get.overlayContext!, "页面不存在"); } } } class WikiInfoPage extends StatefulWidget { final String? targetPage; final int? targetPageId; const WikiInfoPage({super.key, this.targetPage, this.targetPageId}); @override State<StatefulWidget> createState() => _WikiInfoPageState(); } class _WikiInfoPageState extends ReactiveState<WikiInfoPage> { WikiInfoPageController c = WikiInfoPageController(); @override void initState() { super.initState(); Get.put(c); } @override void dispose() { super.dispose(); Get.delete<WikiInfoPageController>(); } @override void receiveProps() { c.pageId.value = widget.targetPageId ?? 0; c.pageTitle.value = widget.targetPage ?? ""; } Widget buildLoading(BuildContext context) { return CupertinoListSection.insetGrouped( header: Text("基本信息"), backgroundColor: CupertinoTheme.of(context).scaffoldBackgroundColor, children: <CupertinoListTile>[ CupertinoListTile.notched( title: Center( child: CupertinoActivityIndicator(radius: 10 * MediaQuery.of(context).textScaleFactor), ), ), ], ); } CupertinoListTile buildPageInfo(BuildContext context, String label, dynamic value, {VoidFutureCallback? onTap}) { final Locale appLocale = Localizations.localeOf(context); var valueStr = "未知"; if (value is String) { valueStr = value; } if (value is int) { valueStr = NumberFormat.decimalPattern(appLocale.toLanguageTag()).format(value); } else if (value is double) { var pattern = NumberFormat.decimalPattern(appLocale.toLanguageTag()); pattern.maximumFractionDigits = 2; valueStr = pattern.format(value); } else if (value is DateTime) { // ignore: prefer_interpolation_to_compose_strings valueStr = DateFormat.yMMMd(appLocale.toLanguageTag()).format(value) + " " + DateFormat.Hms(appLocale.toLanguageTag()).format(value); } return CupertinoListTile.notched( padding: const EdgeInsetsDirectional.fromSTEB(20.0, 10.0, 14.0, 10.0), title: Container( width: MediaQuery.of(context).size.width, child: ResponsivePair( children: [ Text(label), Text( valueStr, style: TextStyle(color: CupertinoColors.systemGrey2.resolveFrom(context)), ), ], ), ), trailing: onTap != null ? const Padding( padding: EdgeInsets.only(left: 8), child: CupertinoListTileChevron(), ) : null, onTap: onTap, ); } int? getPageViews(Map<DateTime, int?>? pageViews) { if (pageViews == null) return null; int validData = 0; int visitSum = 0; pageViews.forEach((key, value) { if (value != null) { validData++; visitSum += value; } }); return validData != 0 ? visitSum : null; } Widget buildPageInfoList(BuildContext context) { var pageInfo = c.pageInfo.value; return Column( children: [ CupertinoListSection.insetGrouped( additionalDividerMargin: 6, header: const Text("基本信息"), backgroundColor: CupertinoTheme.of(context).scaffoldBackgroundColor, children: <CupertinoListTile>[ buildPageInfo(context, "页面标题", pageInfo?.title), buildPageInfo(context, "显示标题", pageInfo?.mainTitle), buildPageInfo(context, "页面长度(字节)", pageInfo?.length), buildPageInfo(context, "页面ID", pageInfo?.pageid), buildPageInfo(context, "页面内容语言", pageInfo?.pagelanguage), buildPageInfo(context, "页面内容类型", pageInfo?.contentmodel), buildPageInfo(context, "收藏者数", pageInfo?.watchers), buildPageInfo(context, "更新后已查看的收藏者", pageInfo?.visitingwatchers), buildPageInfo(context, "最后修改于", pageInfo?.updatedTime), buildPageInfo(context, "该页面的子页面数", null), buildPageInfo(context, "过去30天的页面访问量", getPageViews(pageInfo?.pageviews)), ], ), ], ); } @override Widget render(BuildContext context) { return IsekaiPageScaffold( navigationBar: const IsekaiNavigationBar( middle: Text("页面信息"), ), child: SafeArea( child: ListView( children: [ Obx(() => c.loadingPageInfo.value ? buildLoading(context) : buildPageInfoList(context)) ], ), ), ); } }