将json解析更改为freezed

main
落雨楓 2 years ago
parent 7c80f5b5ea
commit b4f04e5394

@ -1,53 +1,33 @@
import 'package:json_annotation/json_annotation.dart';
// ignore_for_file: invalid_annotation_target
part 'page_info.g.dart';
@JsonSerializable()
class PageInfo {
int pageid;
int ns;
String title;
String? displayTitle;
String? subtitle;
int? lastrevid;
String? contentmodel;
String? pagelanguage;
String? pagelanguagehtmlcode;
String? pagelanguagedir;
bool? inwatchlist;
int? length;
String? fullurl;
String? editurl;
String? canonicalurl;
import 'package:freezed_annotation/freezed_annotation.dart';
PageImageInfo? thumbnail;
@JsonKey(name: "extract")
String? description;
@JsonKey(name: "touched")
DateTime? updatedTime;
part 'page_info.freezed.dart';
part 'page_info.g.dart';
PageInfo({
required this.pageid,
required this.ns,
required this.title,
this.subtitle,
this.displayTitle,
this.description,
this.contentmodel,
this.pagelanguage,
this.pagelanguagehtmlcode,
this.pagelanguagedir,
this.inwatchlist,
this.updatedTime,
this.lastrevid,
this.length,
this.fullurl,
this.editurl,
this.canonicalurl,
});
@freezed
class PageInfo with _$PageInfo {
const PageInfo._();
factory PageInfo({
required int pageid,
required int ns,
required String title,
String? subtitle,
String? displayTitle,
@JsonKey(name: "extract") String? description,
String? contentmodel,
String? pagelanguage,
String? pagelanguagehtmlcode,
String? pagelanguagedir,
bool? inwatchlist,
@JsonKey(name: "touched") DateTime? updatedTime,
int? lastrevid,
int? length,
String? fullurl,
String? editurl,
String? canonicalurl,
}) = _PageInfo;
String get mainTitle {
return displayTitle ?? title;
@ -57,34 +37,19 @@ class PageInfo {
return null;
}
factory PageInfo.fromJson(Map<String, dynamic> json) =>
_$PageInfoFromJson(json);
Map<String, dynamic> toJson() => _$PageInfoToJson(this);
factory PageInfo.fromJson(Map<String, dynamic> json) => _$PageInfoFromJson(json);
}
@JsonSerializable()
class PagesResponse {
List<PageInfo> pages;
PagesResponse({required this.pages});
factory PagesResponse.fromJson(Map<String, dynamic> json) =>
_$PagesResponseFromJson(json);
@freezed
class PagesResponse with _$PagesResponse {
factory PagesResponse({required List<PageInfo> pages}) = _PageResponse;
Map<String, dynamic> toJson() => _$PagesResponseToJson(this);
factory PagesResponse.fromJson(Map<String, dynamic> json) => _$PagesResponseFromJson(json);
}
@JsonSerializable()
class PageImageInfo {
String source;
int? width;
int? height;
PageImageInfo({required this.source, this.width, this.height});
factory PageImageInfo.fromJson(Map<String, dynamic> json) =>
_$PageImageInfoFromJson(json);
@freezed
class PageImageInfo with _$PageImageInfo {
factory PageImageInfo({required String source, int? width, int? height}) = _PageImageInfo;
Map<String, dynamic> toJson() => _$PageImageInfoToJson(this);
factory PageImageInfo.fromJson(Map<String, dynamic> json) => _$PageImageInfoFromJson(json);
}

@ -1,149 +1,92 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'parse.freezed.dart';
part 'parse.g.dart';
@JsonSerializable()
class MWParseCategoryInfo {
String sortkey;
String category;
MWParseCategoryInfo({
required this.category,
this.sortkey = "",
});
@freezed
class MWParseCategoryInfo with _$MWParseCategoryInfo {
factory MWParseCategoryInfo({
required String category,
@Default("") String sortkey,
}) = _MWParseCategoryInfo;
factory MWParseCategoryInfo.fromJson(Map<String, dynamic> json) =>
_$MWParseCategoryInfoFromJson(json);
Map<String, dynamic> toJson() => _$MWParseCategoryInfoToJson(this);
}
@JsonSerializable()
class MWParseLangLinkInfo {
String lang;
String url;
String langname;
String autonym;
String title;
MWParseLangLinkInfo({
required this.lang,
this.url = "",
this.langname = "",
this.autonym = "",
required this.title,
});
@freezed
class MWParseLangLinkInfo with _$MWParseLangLinkInfo {
factory MWParseLangLinkInfo({
required String lang,
required String title,
@Default("") String url,
@Default("") String langname,
@Default("") autonym,
}) = _MWParseLangLinkInfo;
factory MWParseLangLinkInfo.fromJson(Map<String, dynamic> json) =>
_$MWParseLangLinkInfoFromJson(json);
Map<String, dynamic> toJson() => _$MWParseLangLinkInfoToJson(this);
}
@JsonSerializable()
class MWParsePageLinkInfo {
int ns;
String title;
bool exists;
MWParsePageLinkInfo({
required this.ns,
required this.title,
this.exists = false,
});
@freezed
class MWParsePageLinkInfo with _$MWParsePageLinkInfo {
factory MWParsePageLinkInfo({
required int ns,
required String title,
@Default(false) bool exists,
}) = _MWParsePageLinkInfo;
factory MWParsePageLinkInfo.fromJson(Map<String, dynamic> json) =>
_$MWParsePageLinkInfoFromJson(json);
Map<String, dynamic> toJson() => _$MWParsePageLinkInfoToJson(this);
}
@JsonSerializable()
class MWParseSectionInfo {
int toclevel;
int level;
String line;
String number;
String index;
String fromtitle;
int? byteoffset;
String anchor;
MWParseSectionInfo({
this.toclevel = -1,
this.level = -1,
this.line = "",
this.number = "",
this.index = "",
this.fromtitle = "",
this.byteoffset,
this.anchor = "",
});
@freezed
class MWParseSectionInfo with _$MWParseSectionInfo {
factory MWParseSectionInfo({
required int toclevel,
required int level,
required String line,
@Default("") String number,
@Default("") String index,
@Default("") String fromtitle,
@Default(-1) int byteoffset,
@Default("") String anchor,
}) = _MWParseSectionInfo;
factory MWParseSectionInfo.fromJson(Map<String, dynamic> json) =>
_$MWParseSectionInfoFromJson(json);
Map<String, dynamic> toJson() => _$MWParseSectionInfoToJson(this);
}
@JsonSerializable()
class MWParseInfo {
String title;
int pageid;
int revid;
String text;
List<MWParseLangLinkInfo> langlink;
List<MWParseCategoryInfo> categories;
List<MWParsePageLinkInfo> links;
List<MWParsePageLinkInfo> templates;
List<String> images;
List<String> externallinks;
List<MWParseSectionInfo> sections;
bool showtoc;
String displaytitle;
List<String> modules;
List<String> modulescripts;
List<String> modulestyles;
Map<String, dynamic> jsconfigvars;
Map<String, dynamic> iwlinks;
Map<String, dynamic> properties;
MWParseInfo({
required this.title,
required this.pageid,
this.revid = -1,
this.text = "",
this.langlink = const [],
this.categories = const [],
this.links = const [],
this.templates = const [],
this.images = const [],
this.externallinks = const [],
this.sections = const [],
this.showtoc = true,
this.displaytitle = "",
this.modules = const [],
this.modulescripts = const [],
this.modulestyles = const [],
this.jsconfigvars = const {},
this.iwlinks = const {},
this.properties = const {},
});
factory MWParseInfo.fromJson(Map<String, dynamic> json) =>
_$MWParseInfoFromJson(json);
Map<String, dynamic> toJson() => _$MWParseInfoToJson(this);
@freezed
class MWParseInfo with _$MWParseInfo {
factory MWParseInfo({
required String title,
required int pageid,
required int revid,
required String text,
String? displaytitle,
@Default([]) List<MWParseLangLinkInfo> langlink,
@Default([]) List<MWParseCategoryInfo> categories,
@Default([]) List<MWParsePageLinkInfo> links,
@Default([]) List<MWParsePageLinkInfo> templates,
@Default([]) List<String> images,
@Default([]) List<String> externallinks,
@Default([]) List<MWParseSectionInfo> sections,
@Default(true) bool showtoc,
@Default([]) List<String> modules,
@Default([]) List<String> modulescripts,
@Default([]) List<String> modulestyles,
@Default({}) Map<String, dynamic> jsconfigvars,
@Default({}) Map<String, dynamic> iwlinks,
@Default({}) Map<String, dynamic> properties,
}) = _MWParseInfo;
factory MWParseInfo.fromJson(Map<String, dynamic> json) => _$MWParseInfoFromJson(json);
}
@JsonSerializable()
class MWParseResponse {
MWParseInfo parse;
MWParseResponse({required this.parse});
factory MWParseResponse.fromJson(Map<String, dynamic> json) =>
_$MWParseResponseFromJson(json);
@freezed
class MWParseResponse with _$MWParseResponse {
factory MWParseResponse({required MWParseInfo parse}) = _MWParseResponse;
Map<String, dynamic> toJson() => _$MWParseResponseToJson(this);
factory MWParseResponse.fromJson(Map<String, dynamic> json) => _$MWParseResponseFromJson(json);
}

@ -1,51 +1,32 @@
import 'package:json_annotation/json_annotation.dart';
// ignore_for_file: invalid_annotation_target
part 'recent_changes.g.dart';
@JsonSerializable()
class RecentChangesItem {
String? type;
int ns;
String title;
int pageid;
int revid;
import 'package:freezed_annotation/freezed_annotation.dart';
@JsonKey(name: 'old_revid')
int? oldRevid;
int? rcid;
DateTime timestamp;
part 'recent_changes.freezed.dart';
part 'recent_changes.g.dart';
RecentChangesItem({
this.type,
required this.ns,
required this.title,
required this.pageid,
required this.revid,
this.oldRevid,
this.rcid,
required this.timestamp,
});
@freezed
class RecentChangesItem with _$RecentChangesItem {
factory RecentChangesItem({
String? type,
required int ns,
required String title,
required int pageid,
required int revid,
required DateTime timestamp,
@JsonKey(name: 'old_revid') int? oldRevid,
int? rcid,
}) = _RecentChangesItem;
factory RecentChangesItem.fromJson(Map<String, dynamic> json) =>
_$RecentChangesItemFromJson(json);
Map<String, dynamic> toJson() => _$RecentChangesItemToJson(this);
}
@JsonSerializable()
class RecentChangesResponse {
List<RecentChangesItem> recentchanges;
RecentChangesResponse({required this.recentchanges});
@freezed
class RecentChangesResponse with _$RecentChangesResponse {
factory RecentChangesResponse({required List<RecentChangesItem> recentchanges}) =
_RecentChangesResponse;
factory RecentChangesResponse.fromJson(Map<String, dynamic> json) =>
_$RecentChangesResponseFromJson(json);
Map<String, dynamic> toJson() => _$RecentChangesResponseToJson(this);
}

@ -1,101 +1,64 @@
import 'package:json_annotation/json_annotation.dart';
// ignore_for_file: invalid_annotation_target
part 'userinfo.g.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@JsonSerializable()
class UserGroupMembership {
String group;
String expiry;
part 'userinfo.freezed.dart';
part 'userinfo.g.dart';
UserGroupMembership({
required this.group,
required this.expiry,
});
@freezed
class UserGroupMembership with _$UserGroupMembership {
factory UserGroupMembership({
required String group,
required String expiry,
}) = _UserGroupMembership;
factory UserGroupMembership.fromJson(Map<String, dynamic> json) =>
_$UserGroupMembershipFromJson(json);
Map<String, dynamic> toJson() => _$UserGroupMembershipToJson(this);
}
@JsonSerializable()
class UserAcceptLang {
double q;
@JsonKey(name: '*')
String langCode;
UserAcceptLang({
required this.q,
required this.langCode,
});
factory UserAcceptLang.fromJson(Map<String, dynamic> json) =>
_$UserAcceptLangFromJson(json);
@freezed
class UserAcceptLang with _$UserAcceptLang {
factory UserAcceptLang({
required double q,
@JsonKey(name: '*') required String langCode,
}) = _UserAcceptLang;
Map<String, dynamic> toJson() => _$UserAcceptLangToJson(this);
factory UserAcceptLang.fromJson(Map<String, dynamic> json) => _$UserAcceptLangFromJson(json);
}
@JsonSerializable()
class MetaUserInfo {
int id;
String name;
List<String>? groups;
List<UserGroupMembership>? groupmemberships;
List<String>? implicitgroups;
List<String>? rights;
Map<String, List<String>>? changeablegroups;
Map<String, dynamic>? options;
int? editcount;
String? realname;
String? email;
DateTime? emailauthenticated;
DateTime? registrationdate;
List<UserAcceptLang>? acceptlang;
int? unreadcount;
Map<String, int>? centralids;
Map<String, String>? attachedlocal;
DateTime? latestcontrib;
MetaUserInfo({
required this.id,
required this.name,
this.groups,
this.groupmemberships,
this.implicitgroups,
this.rights,
this.changeablegroups,
this.options,
this.editcount,
this.realname,
this.email,
this.emailauthenticated,
this.registrationdate,
this.acceptlang,
this.unreadcount,
this.centralids,
this.attachedlocal,
this.latestcontrib,
});
factory MetaUserInfo.fromJson(Map<String, dynamic> json) =>
_$MetaUserInfoFromJson(json);
Map<String, dynamic> toJson() => _$MetaUserInfoToJson(this);
@freezed
class MetaUserInfo with _$MetaUserInfo {
factory MetaUserInfo({
required int id,
required String name,
List<String>? groups,
List<UserGroupMembership>? groupmemberships,
List<String>? implicitgroups,
List<String>? rights,
Map<String, List<String>>? changeablegroups,
Map<String, dynamic>? options,
int? editcount,
String? realname,
String? email,
DateTime? emailauthenticated,
DateTime? registrationdate,
List<UserAcceptLang>? acceptlang,
int? unreadcount,
Map<String, int>? centralids,
Map<String, String>? attachedlocal,
DateTime? latestcontrib,
}) = _MetaUserInfo;
factory MetaUserInfo.fromJson(Map<String, dynamic> json) => _$MetaUserInfoFromJson(json);
}
@JsonSerializable()
class MetaUserInfoResponse {
MetaUserInfo userinfo;
Map<int, String>? useravatar;
MetaUserInfoResponse({
required this.userinfo,
this.useravatar,
});
@freezed
class MetaUserInfoResponse with _$MetaUserInfoResponse {
factory MetaUserInfoResponse({
required MetaUserInfo userinfo,
Map<int, String>? useravatar,
}) = _MetaUserInfoResponse;
factory MetaUserInfoResponse.fromJson(Map<String, dynamic> json) =>
_$MetaUserInfoResponseFromJson(json);
Map<String, dynamic> toJson() => _$MetaUserInfoResponseToJson(this);
}

@ -4,9 +4,9 @@ import 'package:flutter/services.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:isekai_wiki/global.dart';
import 'package:isekai_wiki/models/lifecycle.dart';
import 'package:isekai_wiki/models/user.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -25,6 +25,7 @@ Future<void> init() async {
}
Global.sharedPreferences = await SharedPreferences.getInstance();
await GetStorage.init();
}
Future<void> postInit() async {

@ -9,6 +9,7 @@ import 'package:isekai_wiki/api/mw/mw_api.dart';
import 'package:isekai_wiki/api/mw/user.dart';
import 'package:isekai_wiki/api/response/mugenapp.dart';
import 'package:isekai_wiki/global.dart';
import 'package:isekai_wiki/styles.dart';
import 'package:isekai_wiki/utils/dialog.dart';
import 'package:isekai_wiki/utils/error.dart';
import 'package:json_annotation/json_annotation.dart';
@ -29,8 +30,7 @@ class UserInfo {
this.avatarUrlSet,
});
factory UserInfo.fromJson(Map<String, dynamic> json) =>
_$UserInfoFromJson(json);
factory UserInfo.fromJson(Map<String, dynamic> json) => _$UserInfoFromJson(json);
Map<String, dynamic> toJson() => _$UserInfoToJson(this);
}
@ -52,7 +52,7 @@ class UserController extends GetxController {
return userId.value > 0;
}
String get getDisplayName {
String get displayName {
return nickName.isNotEmpty ? nickName.string : userName.string;
}
@ -179,18 +179,7 @@ class UserController extends GetxController {
var startAuthInfo = startAuthRes.data;
loginRequestToken.value = startAuthInfo.loginRequestKey;
await FlutterWebBrowser.openWebPage(
url: startAuthInfo.loginUrl,
customTabsOptions: const CustomTabsOptions(
defaultColorSchemeParams: CustomTabsColorSchemeParams(
toolbarColor: Color.fromRGBO(33, 37, 41, 1),
),
shareState: CustomTabsShareState.off,
showTitle: true,
),
safariVCOptions: const SafariViewControllerOptions(
barCollapsingEnabled: true,
));
await openUrl(startAuthInfo.loginUrl, inApp: true);
} catch (err, stack) {
authProcessing.value = false;
loginRequestToken.value = "";

@ -1,8 +1,7 @@
import 'package:cupertino_lists/cupertino_lists.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:get/get.dart';
import 'package:isekai_wiki/utils/dialog.dart';
import '../components/dummy_icon.dart';
import '../components/isekai_nav_bar.dart';
@ -12,16 +11,7 @@ import '../styles.dart';
class AboutPageController extends GetxController {
Future<void> handleMainPageLinkClick() async {
if (GetPlatform.isAndroid || GetPlatform.isIOS) {
await FlutterWebBrowser.openWebPage(
url: Global.wikiHomeUrl,
customTabsOptions: const CustomTabsOptions(
defaultColorSchemeParams: CustomTabsColorSchemeParams(
toolbarColor: Colors.black87,
),
),
);
} else {}
openUrl(Global.wikiHomeUrl);
}
}
@ -46,8 +36,7 @@ class AboutPage extends StatelessWidget {
top: false,
bottom: false,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: Column(
children: const <Widget>[
Text("异世界百科APP", style: Styles.articleTitle),
@ -63,8 +52,7 @@ class AboutPage extends StatelessWidget {
backgroundColor: Styles.themePageBackgroundColor,
children: <CupertinoListTile>[
CupertinoListTile.notched(
title: const Text('异世界百科',
style: TextStyle(color: Styles.linkColor)),
title: const Text('异世界百科', style: TextStyle(color: Styles.linkColor)),
leading: const DummyIcon(
color: CupertinoColors.systemBlue,
icon: CupertinoIcons.globe,

@ -1,6 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cupertino_lists/cupertino_lists.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:get/get.dart';
import 'package:isekai_wiki/components/isekai_nav_bar.dart';
import 'package:isekai_wiki/models/user.dart';
@ -20,13 +22,15 @@ class OwnProfileController extends GetxController {
uc = Get.find<UserController>();
}
Future<void> handleLoginClick() {
if (uc.authProcessing.isFalse) {
handleStartAuth();
return Future.delayed(const Duration(milliseconds: 100));
Future<void> handleUserClick() {
if (uc.isLoggedIn) {
} else {
return Future.value();
if (uc.authProcessing.isFalse) {
handleStartAuth();
return Future.delayed(const Duration(milliseconds: 100));
}
}
return Future.value();
}
Future<void> handleStartAuth() async {
@ -63,8 +67,7 @@ class OwnProfileTab extends StatelessWidget {
child: CachedNetworkImage(
width: size,
height: size,
placeholder: (_, __) =>
const CupertinoActivityIndicator(radius: 12),
placeholder: (_, __) => const CupertinoActivityIndicator(radius: 12),
imageUrl: avatarUrl,
fit: BoxFit.cover,
),
@ -91,41 +94,27 @@ class OwnProfileTab extends StatelessWidget {
dividerMargin: uc.isLoggedIn ? 14 : double.infinity,
children: <Widget>[
Obx(
() => uc.isLoggedIn
? CupertinoListTile.notched(
title: Text(uc.getDisplayName,
style: Styles.listTileLargeTitle),
padding: const EdgeInsets.only(
left: 6, right: 14, top: 0, bottom: 0),
leading: _buildUserAvatar(uc),
leadingSize: 80,
leadingToTitle: 4,
trailing: const CupertinoListTileChevron(),
onTap: () {},
)
: CupertinoListTile.notched(
title:
const Text('登录/注册', style: Styles.listTileLargeTitle),
padding: const EdgeInsets.only(
left: 6, right: 14, top: 0, bottom: 0),
leading: const DummyIcon(
color: CupertinoColors.systemGrey,
icon: CupertinoIcons.person_fill,
size: 64,
rounded: true,
),
leadingSize: 80,
leadingToTitle: 4,
trailing: uc.authProcessing.value
? const Padding(
padding: EdgeInsets.only(right: 5),
child: CupertinoActivityIndicator(
radius: 12,
),
)
: const CupertinoListTileChevron(),
onTap: c.handleLoginClick,
),
() => CupertinoListTile.notched(
title: uc.isLoggedIn
? Text(uc.displayName, style: Styles.listTileLargeTitle)
: const Text('登录/注册', style: Styles.listTileLargeTitle),
subtitle: uc.isLoggedIn
? Text("@${uc.userName.value}", style: Styles.listTileSubTitle)
: null,
padding: const EdgeInsets.only(left: 6, right: 14, top: 0, bottom: 0),
leading: _buildUserAvatar(uc),
leadingSize: 80,
leadingToTitle: 4,
trailing: uc.authProcessing.value
? const Padding(
padding: EdgeInsets.only(right: 5),
child: CupertinoActivityIndicator(
radius: 12,
),
)
: const CupertinoListTileChevron(),
onTap: c.handleUserClick,
),
),
AnimatedSize(
duration: const Duration(milliseconds: 250),
@ -214,12 +203,21 @@ class OwnProfileTab extends StatelessWidget {
);
},
),
if (kDebugMode)
CupertinoListTile.notched(
title: const Text('内部浏览器测试'),
leading: const DummyIcon(
color: CupertinoColors.systemBlue,
icon: CupertinoIcons.airplane,
),
trailing: const CupertinoListTileChevron(),
onTap: () async {},
),
],
));
}
SliverChildBuilderDelegate _buildSliverChildBuilderDelegate(
BuildContext context) {
SliverChildBuilderDelegate _buildSliverChildBuilderDelegate(BuildContext context) {
return SliverChildBuilderDelegate(
(context, index) {
switch (index) {

@ -6,14 +6,10 @@ abstract class Styles {
static bool isXs = false;
static const CupertinoTextThemeData defaultTextTheme =
CupertinoTextThemeData();
static const CupertinoTextThemeData defaultTextTheme = CupertinoTextThemeData();
static const TextStyle navLargeTitleTextStyle = TextStyle(
fontWeight: FontWeight.normal,
fontSize: 32,
color: CupertinoColors.label,
inherit: false);
fontWeight: FontWeight.normal, fontSize: 32, color: CupertinoColors.label, inherit: false);
static const TextStyle productRowItemName = TextStyle(
color: Color.fromRGBO(0, 0, 0, 0.8),
@ -43,18 +39,20 @@ abstract class Styles {
static const TextStyle pageCardDescription = TextStyle(
color: Colors.black54,
fontSize: 14,
fontSize: 16,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
);
static const TextStyle listTileLargeTitle = TextStyle(fontSize: 18);
static const TextStyle listTileSubTitle = TextStyle(fontSize: 16);
static const Color websiteNavbarColor = Color.fromRGBO(33, 37, 41, 1);
static const Color themeMainColor = Color.fromRGBO(65, 147, 135, 1);
static const Color themeNavTitleColor = Color.fromRGBO(255, 255, 255, 1);
static const Color themeBottomColor = Color.fromRGBO(255, 255, 255, 1);
static const Color themePageBackgroundColor =
Color.fromRGBO(240, 240, 240, 1);
static const Color themePageBackgroundColor = Color.fromRGBO(240, 240, 240, 1);
static const Color themeNavSegmentTextColor = Color.fromRGBO(12, 12, 12, 1);
static const Color panelBackgroundColor = Color.fromRGBO(255, 255, 255, 1);
static const Color linkColor = CupertinoColors.link;

@ -1,5 +1,12 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../styles.dart';
Future<void> alert(BuildContext context, String content, {String? title}) {
var c = Completer();
@ -26,10 +33,7 @@ Future<void> alert(BuildContext context, String content, {String? title}) {
}
Future<bool> confirm(BuildContext context, String content,
{String? title,
String? positiveText,
String? negativeText,
bool isDanger = false}) {
{String? title, String? positiveText, String? negativeText, bool isDanger = false}) {
var c = Completer<bool>();
positiveText ??= "";
@ -63,3 +67,27 @@ Future<bool> confirm(BuildContext context, String content,
return c.future;
}
Future<void> openUrl(String url, {bool inApp = false}) async {
if (!kIsWeb && inApp) {
// APP
if (GetPlatform.isAndroid || GetPlatform.isIOS) {
// IOS使
await FlutterWebBrowser.openWebPage(
url: url,
customTabsOptions: const CustomTabsOptions(
defaultColorSchemeParams: CustomTabsColorSchemeParams(
toolbarColor: Styles.websiteNavbarColor,
),
shareState: CustomTabsShareState.off,
showTitle: true,
),
safariVCOptions: const SafariViewControllerOptions(
barCollapsingEnabled: true,
));
return;
}
}
//
launchUrlString(url);
}

@ -9,6 +9,7 @@ import package_info_plus
import path_provider_macos
import shared_preferences_macos
import sqflite
import url_launcher_macos
import wakelock_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
@ -16,5 +17,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))
}

File diff suppressed because it is too large Load Diff

@ -48,6 +48,7 @@ dependencies:
like_button: ^2.0.4
skeletons: ^0.0.3
modal_bottom_sheet: ^2.1.2
url_launcher: ^6.1.7
flutter_web_browser: ^0.17.1
flutter_inappwebview: ^5.7.2+3
web_smooth_scroll: ^1.0.0
@ -63,7 +64,8 @@ dependencies:
dio_cookie_manager: ^2.0.0
dio_http2_adapter: ^2.0.0
dio_cache_interceptor: ^3.3.1
get:
get: ^4.6.5
get_storage: ^2.0.3
freezed_annotation: ^2.2.0
dev_dependencies:

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

Loading…
Cancel
Save