mod: 样式、dio异常处理

This commit is contained in:
guozhigq
2023-05-09 14:39:52 +08:00
parent f3b57bfe7b
commit 04668b3591
29 changed files with 469 additions and 342 deletions

View File

@ -5,19 +5,11 @@ PODS:
- device_info_plus (0.0.1):
- Flutter
- Flutter (1.0.0)
- flutter_inappwebview (0.0.1):
- Flutter
- flutter_inappwebview/Core (= 0.0.1)
- OrderedSet (~> 5.0)
- flutter_inappwebview/Core (0.0.1):
- Flutter
- OrderedSet (~> 5.0)
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- image_gallery_saver (1.5.0):
- Flutter
- OrderedSet (5.0.0)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
@ -40,7 +32,6 @@ DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
@ -53,7 +44,6 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- FMDB
- OrderedSet
- ReachabilitySwift
EXTERNAL SOURCES:
@ -63,8 +53,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/device_info_plus/ios"
Flutter:
:path: Flutter
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
path_provider_foundation:
@ -86,10 +74,8 @@ SPEC CHECKSUMS:
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825

View File

@ -23,7 +23,6 @@ class VideoCardVSkeleton extends StatelessWidget {
return Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(6),
),
);

View File

@ -71,12 +71,6 @@ class VideoReplySkeleton extends StatelessWidget {
],
),
),
Divider(
height: 1,
indent: 52,
endIndent: 10,
color: Theme.of(context).dividerColor.withOpacity(0.08),
)
],
),
);

View File

@ -17,6 +17,7 @@ class HttpError extends StatelessWidget {
children: [
Text(
errMsg,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 10),

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pilipala/utils/utils.dart';
@ -11,21 +12,21 @@ class StatDanMu extends StatelessWidget {
@override
Widget build(BuildContext context) {
Color color =
theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline;
return Row(
children: [
Image.asset(
'assets/images/dm_$theme.png',
width: size == 'medium' ? 16 : 14,
height: size == 'medium' ? 16 : 14,
Icon(
CupertinoIcons.ellipses_bubble,
size: 14,
color: color,
),
const SizedBox(width: 2),
const SizedBox(width: 3),
Text(
Utils.numFormat(danmu!),
style: TextStyle(
fontSize: size == 'medium' ? 12 : 11,
color: theme == 'white'
? Colors.white
: Theme.of(context).colorScheme.outline,
color: color,
),
)
],

View File

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
class UpTag extends StatelessWidget {
const UpTag({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 14,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
border: Border.all(color: Theme.of(context).colorScheme.outline)),
margin: const EdgeInsets.only(right: 4),
child: Center(
child: Text(
'UP',
style: TextStyle(
fontSize: 6, color: Theme.of(context).colorScheme.outline),
),
),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pilipala/utils/utils.dart';
@ -6,26 +7,26 @@ class StatView extends StatelessWidget {
final int? view;
final String? size;
const StatView({Key? key, this.theme, this.view, this.size}) : super(key: key);
const StatView({Key? key, this.theme, this.view, this.size})
: super(key: key);
@override
Widget build(BuildContext context) {
Color color =
theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline;
return Row(
children: [
Image.asset(
'assets/images/view_$theme.png',
width: size == 'medium' ? 16 : 14,
height: size == 'medium' ? 16 : 14,
Icon(
CupertinoIcons.play_rectangle,
size: 13,
color: color,
),
const SizedBox(width: 2),
const SizedBox(width: 3),
Text(
Utils.numFormat(view!),
// videoItem['stat']['view'].toString(),
style: TextStyle(
fontSize: size == 'medium' ? 12 : 11,
color: theme == 'white'
? Colors.white
: Theme.of(context).colorScheme.outline,
color: color,
),
),
],

View File

@ -1,6 +1,7 @@
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/stat/up.dart';
import 'package:pilipala/common/widgets/stat/view.dart';
import 'package:pilipala/utils/utils.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
@ -137,11 +138,12 @@ class VideoContent extends StatelessWidget {
const SizedBox(height: 4),
Row(
children: [
Image.asset(
'assets/images/up_gray.png',
width: 14,
height: 12,
),
// Image.asset(
// 'assets/images/up_gray.png',
// width: 14,
// height: 12,
// ),
const UpTag(),
const SizedBox(width: 2),
Text(
videoItem.owner.name,

View File

@ -111,7 +111,7 @@ class Request {
return response;
} on DioError catch (e) {
print('get error: $e');
return Future.error(ApiInterceptor.dioError(e));
return Future.error(await ApiInterceptor.dioError(e));
}
}
@ -132,7 +132,7 @@ class Request {
return response;
} on DioError catch (e) {
print('post error: $e');
return Future.error(ApiInterceptor.dioError(e));
return Future.error(await ApiInterceptor.dioError(e));
}
}

View File

@ -1,10 +1,12 @@
import 'package:dio/dio.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart' hide Response;
class ApiInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
// print("请求之前");
print("请求之前");
// 在请求之前添加头部或认证信息
// options.headers['Authorization'] = 'Bearer token';
// options.headers['Content-Type'] = 'application/json';
@ -13,15 +15,14 @@ class ApiInterceptor extends Interceptor {
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
// print("响应之前");
handler.next(response);
}
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
void onError(DioError err, ErrorInterceptorHandler handler) async {
// 处理网络请求错误
handler.next(err);
// handler.next(err);
SmartDialog.showToast(await dioError(err));
super.onError(err, handler);
}
@ -43,7 +44,7 @@ class ApiInterceptor extends Interceptor {
return "发送请求超时,请检查网络设置";
case DioErrorType.unknown:
var res = await checkConect();
return "$res 网络异常,请稍后重试!";
return res + " \n 网络异常,请稍后重试!";
default:
return "Dio异常";
}

View File

@ -1,5 +1,6 @@
import 'package:pilipala/http/api.dart';
import 'package:pilipala/http/init.dart';
import 'package:pilipala/models/user/info.dart';
class UserHttp {
static Future<dynamic> userStat({required int mid}) async {
@ -14,7 +15,8 @@ class UserHttp {
static Future<dynamic> userInfo() async {
var res = await Request().get(Api.userInfo);
if (res.data['code'] == 0) {
return {'status': true, 'data': res.data['data']};
UserInfoData data = UserInfoData.fromJson(res.data['data']);
return {'status': true, 'data': data};
} else {
return {'status': false};
}

View File

@ -11,39 +11,47 @@ import 'package:pilipala/models/video_detail_res.dart';
class VideoHttp {
// 首页推荐视频
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
var res = await Request().get(
Api.recommendList,
data: {
'feed_version': 'V3',
'ps': ps,
'fresh_idx': freshIdx,
},
);
if (res.data['code'] == 0) {
List<RecVideoItemModel> list = [];
for (var i in res.data['data']['item']) {
list.add(RecVideoItemModel.fromJson(i));
try {
var res = await Request().get(
Api.recommendList,
data: {
'feed_version': 'V3',
'ps': ps,
'fresh_idx': freshIdx,
},
);
if (res.data['code'] == 0) {
List<RecVideoItemModel> list = [];
for (var i in res.data['data']['item']) {
list.add(RecVideoItemModel.fromJson(i));
}
return {'status': true, 'data': list};
} else {
return {'status': false, 'data': []};
}
return {'status': true, 'data': list};
} else {
return {'status': false, 'data': []};
} catch (err) {
return {'status': false, 'data': [], 'msg': err};
}
}
// 最热视频
static Future hotVideoList({required int pn, required int ps}) async {
var res = await Request().get(
Api.hotList,
data: {'pn': pn, 'ps': ps},
);
if (res.data['code'] == 0) {
List<HotVideoItemModel> list = [];
for (var i in res.data['data']['list']) {
list.add(HotVideoItemModel.fromJson(i));
try {
var res = await Request().get(
Api.hotList,
data: {'pn': pn, 'ps': ps},
);
if (res.data['code'] == 0) {
List<HotVideoItemModel> list = [];
for (var i in res.data['data']['list']) {
list.add(HotVideoItemModel.fromJson(i));
}
return {'status': true, 'data': list};
} else {
return {'status': false, 'data': []};
}
return {'status': true, 'data': list};
} else {
return {'status': false, 'data': []};
} catch (err) {
return {'status': false, 'data': [], 'msg': err};
}
}

View File

@ -1,7 +1,80 @@
class UserInfoData {
UserInfoData({
this.isLogin,
this.emailVerified,
this.face,
this.levelInfo,
this.mid,
this.mobileVerified,
this.money,
this.moral,
this.official,
this.officialVerify,
this.pendant,
this.scores,
this.uname,
this.vipDueDate,
this.vipStatus,
this.vipType,
this.vipPayType,
this.vipThemeType,
this.vipLabel,
this.vipAvatarSub,
this.vipNicknameColor,
this.wallet,
this.hasShop,
this.shopUrl,
});
bool? isLogin;
int? emailVerified;
String? face;
Map? levelInfo;
int? mid;
int? mobileVerified;
int? money;
int? moral;
Map? official;
Map? officialVerify;
Map? pendant;
int? scores;
String? uname;
int? vipDueDate;
int? vipStatus;
int? vipType;
int? vipPayType;
int? vipThemeType;
Map? vipLabel;
int? vipAvatarSub;
String? vipNicknameColor;
Map? wallet;
bool? hasShop;
String? shopUrl;
UserInfoData.fromJson(Map<String, dynamic> json) {
isLogin = json['isLogin'] ?? false;
emailVerified = json['email_verified'];
face = json['face'];
levelInfo = json['level_info'];
mid = json['mid'];
mobileVerified = json['mobile_verified'];
money = json['money'];
moral = json['moral'];
official = json['official'];
officialVerify = json['officialVerify'];
pendant = json['pendant'];
scores = json['scores'];
uname = json['uname'];
vipDueDate = json['vipDueDate'];
vipStatus = json['vipStatus'];
vipType = json['vipType'];
vipPayType = json['vip_pay_type'];
vipThemeType = json['vip_theme_type'];
vipLabel = json['vip_label'];
vipAvatarSub = json['vip_avatar_subscript'];
vipNicknameColor = json['vip_nickname_color'];
wallet = json['wallet'];
hasShop = json['has_shop'];
shopUrl = json['shop_url'];
}
}

View File

@ -149,6 +149,6 @@ class ReplyControl {
entryText = json['sub_reply_entry_text'];
titleText = json['sub_reply_title_text'];
time = json['time_desc'];
location = json['location'] ?? '';
location = json['location'] != null ? json['location'].split('')[1] : '';
}
}

View File

@ -15,7 +15,7 @@ class HomeController extends GetxController {
@override
void onInit() {
super.onInit();
queryRcmdFeed('init');
// queryRcmdFeed('init');
}
// 获取推荐
@ -35,6 +35,7 @@ class HomeController extends GetxController {
_currentPage += 1;
}
isLoadingMore = false;
return res;
}
// 下拉刷新

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/skeleton/video_card_v.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/common/widgets/video_card_v.dart';
import './controller.dart';
import 'package:pilipala/common/constants.dart';
@ -16,6 +17,7 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage>
with AutomaticKeepAliveClientMixin {
final HomeController _homeController = Get.put(HomeController());
Future? _futureBuilderFuture;
List videoList = [];
@override
@ -24,6 +26,7 @@ class _HomePageState extends State<HomePage>
@override
void initState() {
super.initState();
_futureBuilderFuture = _homeController.queryRcmdFeed('init');
_homeController.videoList.listen((value) {
videoList = value;
setState(() {});
@ -69,26 +72,25 @@ class _HomePageState extends State<HomePage>
? EdgeInsets.zero
: const EdgeInsets.fromLTRB(
StyleString.cardSpace, 0, StyleString.cardSpace, 8),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 行间距
mainAxisSpacing: StyleString.cardSpace,
// 列间距
crossAxisSpacing: StyleString.cardSpace,
// 列数
crossAxisCount: _homeController.crossAxisCount,
mainAxisExtent: MediaQuery.of(context).size.width /
_homeController.crossAxisCount /
StyleString.aspectRatio +
70),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return videoList.isNotEmpty
? VideoCardV(videoItem: videoList[index])
: const VideoCardVSkeleton();
},
childCount: videoList.isNotEmpty ? videoList.length : 10,
),
sliver: FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map data = snapshot.data as Map;
if (data['status']) {
return Obx(() => contentGrid(
_homeController, _homeController.videoList));
} else {
return HttpError(
errMsg: data['msg'],
fn: () => setState(() {}),
);
}
} else {
// 骨架屏
return contentGrid(_homeController, []);
}
},
),
),
const LoadingMore()
@ -98,6 +100,31 @@ class _HomePageState extends State<HomePage>
// ),
);
}
Widget contentGrid(ctr, videoList) {
return SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 行间距
mainAxisSpacing: StyleString.cardSpace,
// 列间距
crossAxisSpacing: StyleString.cardSpace,
// 列数
crossAxisCount: ctr.crossAxisCount,
mainAxisExtent: MediaQuery.of(context).size.width /
ctr.crossAxisCount /
StyleString.aspectRatio +
70,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return videoList!.isNotEmpty
? VideoCardV(videoItem: videoList![index])
: const VideoCardVSkeleton();
},
childCount: videoList!.isNotEmpty ? videoList!.length : 10,
),
);
}
}
class MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@ -10,11 +11,7 @@ class HomeAppBar extends StatelessWidget {
return SliverAppBar(
// forceElevated: true,
scrolledUnderElevation: 0,
toolbarHeight: Platform.isAndroid
? (MediaQuery.of(context).padding.top + 6)
: Platform.isIOS
? MediaQuery.of(context).padding.top - 2
: kToolbarHeight,
toolbarHeight: MediaQuery.of(context).padding.top,
expandedHeight: kToolbarHeight + MediaQuery.of(context).padding.top,
automaticallyImplyLeading: false,
pinned: true,
@ -39,18 +36,12 @@ class HomeAppBar extends StatelessWidget {
actions: [
IconButton(
onPressed: () {},
icon: const FaIcon(
FontAwesomeIcons.magnifyingGlass,
size: 18,
),
),
IconButton(
onPressed: () {},
icon: const FaIcon(
FontAwesomeIcons.envelope,
size: 20,
),
icon: const Icon(CupertinoIcons.search, size: 22),
),
// IconButton(
// onPressed: () {},
// icon: const Icon(CupertinoIcons.bell, size: 22),
// ),
const SizedBox(width: 10)
],
elevation: 0,

View File

@ -24,7 +24,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
@override
void initState() {
super.initState();
_futureBuilderFuture = _hotController!.queryHotFeed('init');
_futureBuilderFuture = _hotController.queryHotFeed('init');
_hotController.scrollController.addListener(
() {
if (_hotController.scrollController.position.pixels >=

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:pilipala/pages/home/view.dart';
@ -12,18 +13,42 @@ class MainController extends GetxController {
];
List navigationBars = [
{
'icon': const Icon(Icons.home_outlined),
'selectedIcon': const Icon(Icons.home),
// 'icon': const Icon(Icons.home_outlined),
// 'selectedIcon': const Icon(Icons.home),
'icon': const Icon(
CupertinoIcons.house,
size: 18,
),
'selectedIcon': const Icon(
CupertinoIcons.house_fill,
size: 18,
),
'label': "推荐",
},
{
'icon': const Icon(Icons.whatshot_outlined),
'selectedIcon': const Icon(Icons.whatshot_rounded),
// 'icon': const Icon(Icons.whatshot_outlined),
// 'selectedIcon': const Icon(Icons.whatshot_rounded),
'icon': const Icon(
CupertinoIcons.flame,
size: 20,
),
'selectedIcon': const Icon(
CupertinoIcons.flame_fill,
size: 20,
),
'label': "热门",
},
{
'icon': const Icon(Icons.person_outline),
'selectedIcon': const Icon(Icons.person),
// 'icon': const Icon(Icons.person_outline),
// 'selectedIcon': const Icon(Icons.person),
'icon': const Icon(
CupertinoIcons.person,
size: 21,
),
'selectedIcon': const Icon(
CupertinoIcons.person_fill,
size: 21,
),
'label': "我的",
}
];

View File

@ -1,7 +1,10 @@
import 'package:get/get.dart';
import 'package:pilipala/http/user.dart';
import 'package:pilipala/models/user/info.dart';
class MineController extends GetxController {
UserInfoData? userInfo;
@override
void onInit() {
super.onInit();

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
@ -22,13 +23,19 @@ class _MinePageState extends State<MinePage> {
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.light_mode_rounded),
icon: const Icon(
CupertinoIcons.moon,
size: 22,
),
// icon: const Icon(
// CupertinoIcons.sun_max,
// size: 22,
// ),
),
IconButton(
onPressed: () {},
icon: const FaIcon(
FontAwesomeIcons.sliders,
size: 18,
icon: const Icon(
CupertinoIcons.slider_horizontal_3,
),
),
const SizedBox(width: 10),
@ -36,161 +43,183 @@ class _MinePageState extends State<MinePage> {
),
body: RefreshIndicator(
onRefresh: () async {
await Future.delayed(Duration(seconds: 2));
await Future.delayed(const Duration(seconds: 2));
},
child: Column(
children: [
InkWell(
onTap: () {
Get.toNamed(
'/webview',
parameters: {
'url':
'https://passport.bilibili.com/h5-app/passport/login',
'type': 'login',
'pageTitle': '登录bilibili',
},
);
},
child: Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(
child: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: SizedBox(
height: constraint.maxHeight,
child: Column(
children: [
const SizedBox(width: 20),
ClipOval(
child: Container(
width: 75,
height: 75,
color: Theme.of(context).colorScheme.onInverseSurface,
child: Center(
child: Image.asset('assets/images/loading.png'),
InkWell(
onTap: () {
Get.toNamed(
'/webview',
parameters: {
'url':
'https://passport.bilibili.com/h5-app/passport/login',
'type': 'login',
'pageTitle': '登录bilibili',
},
);
},
child: Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(
children: [
const SizedBox(width: 20),
ClipOval(
child: Container(
width: 75,
height: 75,
color: Theme.of(context)
.colorScheme
.onInverseSurface,
child: Center(
child:
Image.asset('assets/images/loading.png'),
),
),
),
const SizedBox(width: 14),
Text(
'点击登录',
style: Theme.of(context).textTheme.titleMedium,
),
],
),
),
),
const SizedBox(width: 14),
Text(
'点击登录',
style: Theme.of(context).textTheme.titleMedium,
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: LayoutBuilder(
builder: (context, constraints) {
TextStyle style = TextStyle(
fontSize: Theme.of(context)
.textTheme
.titleMedium!
.fontSize,
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold);
return SizedBox(
height: constraints.maxWidth / 3 * 0.6,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisCount: 3,
childAspectRatio: 1.67,
children: <Widget>[
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('-', style: style),
const SizedBox(height: 8),
Text(
'动态',
style: Theme.of(context)
.textTheme
.labelMedium,
),
],
),
),
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'50',
style: style,
),
const SizedBox(height: 8),
Text(
'关注',
style: Theme.of(context)
.textTheme
.labelMedium,
),
],
),
),
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'-',
style: style,
),
const SizedBox(height: 8),
Text(
'粉丝',
style: Theme.of(context)
.textTheme
.labelMedium,
),
],
),
),
],
),
);
},
),
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
height: constraints.maxWidth / 4 * 0.8,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisCount: 4,
childAspectRatio: 1.25,
children: <Widget>[
ActionItem(
icon:
const Icon(CupertinoIcons.cloud_download),
onTap: () => {},
text: '离线缓存',
),
ActionItem(
icon: const Icon(CupertinoIcons.time),
onTap: () => {},
text: '历史记录',
),
ActionItem(
icon: const Icon(CupertinoIcons.star),
onTap: () => {},
text: '我的收藏',
),
ActionItem(
icon: const Icon(CupertinoIcons.film),
onTap: () => {},
text: '稍后再看',
),
],
),
);
},
),
),
],
),
),
),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: LayoutBuilder(
builder: (context, constraints) {
TextStyle style = TextStyle(
fontSize:
Theme.of(context).textTheme.titleMedium!.fontSize,
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold);
return SizedBox(
height: constraints.maxWidth / 3 * 0.6,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisCount: 3,
childAspectRatio: 1.67,
children: <Widget>[
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('-', style: style),
const SizedBox(height: 8),
Text(
'动态',
style: Theme.of(context).textTheme.labelMedium,
),
],
),
),
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'50',
style: style,
),
const SizedBox(height: 8),
Text(
'关注',
style: Theme.of(context).textTheme.labelMedium,
),
],
),
),
InkWell(
onTap: () {},
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'-',
style: style,
),
const SizedBox(height: 8),
Text(
'粉丝',
style: Theme.of(context).textTheme.labelMedium,
),
],
),
),
],
),
);
},
),
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
height: constraints.maxWidth / 4 * 0.8,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisCount: 4,
childAspectRatio: 1.25,
children: <Widget>[
ActionItem(
icon: const Icon(FontAwesomeIcons.download),
onTap: () => {},
text: '离线缓存',
),
ActionItem(
icon: const Icon(FontAwesomeIcons.clockRotateLeft),
onTap: () => {},
text: '历史记录',
),
ActionItem(
icon: const Icon(FontAwesomeIcons.star),
onTap: () => {},
text: '我的收藏',
),
ActionItem(
icon: const Icon(FontAwesomeIcons.film),
onTap: () => {},
text: '稍后再看',
),
],
),
);
},
),
),
],
);
},
),
),
);
@ -217,10 +246,7 @@ class ActionItem extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon!.icon!,
color: Theme.of(context).colorScheme.outline,
),
Icon(icon!.icon!),
const SizedBox(height: 8),
Text(
text!,

View File

@ -69,9 +69,4 @@ class PreviewController extends GetxController {
File(path).writeAsBytesSync(response.data);
Share.shareXFiles([XFile(path)], subject: imgList[initialPage.value]);
}
// 浏览器中查看
void onBrowserImg() async {
Utils.openURL(imgList[initialPage.value]);
}
}

View File

@ -74,11 +74,6 @@ class _ImagePreviewState extends State<ImagePreview>
onTap: _previewController.onSaveImg,
child: const Text('保存'),
),
PopupMenuItem(
value: 'browser',
onTap: _previewController.onBrowserImg,
child: const Text('浏览器中查看'),
),
],
),
],

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
@ -246,8 +247,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
child: Row(
children: const [
Icon(
FontAwesomeIcons.lemon,
size: 15,
CupertinoIcons.plus,
size: 16,
),
SizedBox(width: 4),
Text('关注'),
@ -383,7 +384,7 @@ class ActionItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon!.icon!,
size: 20,
size: 21,
color: selectStatus
? Theme.of(context).primaryColor
: Theme.of(context).colorScheme.outline),

View File

@ -18,15 +18,15 @@ class ReplyItem extends StatelessWidget {
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 8, 2),
padding: const EdgeInsets.fromLTRB(12, 6, 8, 0),
child: content(context),
),
Divider(
height: 1,
indent: 52,
endIndent: 10,
color: Theme.of(context).dividerColor.withOpacity(0.08),
)
// Divider(
// height: 1,
// indent: 52,
// endIndent: 10,
// color: Theme.of(context).dividerColor.withOpacity(0.08),
// )
],
),
);
@ -154,7 +154,7 @@ class ReplyItem extends StatelessWidget {
),
// title
Container(
margin: const EdgeInsets.only(top: 0, left: 45, right: 6),
margin: const EdgeInsets.only(top: 0, left: 45, right: 6, bottom: 6),
child: SelectableRegion(
magnifierConfiguration: const TextMagnifierConfiguration(),
focusNode: FocusNode(),
@ -201,7 +201,7 @@ class ReplyItem extends StatelessWidget {
.copyWith(color: Theme.of(context).colorScheme.outline),
),
if (replyItem!.replyControl != null &&
replyItem!.replyControl!.location != null)
replyItem!.replyControl!.location != '')
Text(
'${replyItem!.replyControl!.location!}',
style: Theme.of(context)
@ -315,10 +315,6 @@ class ReplyItemRow extends StatelessWidget {
maxLines: extraRow == 1 ? 2 : null,
TextSpan(
children: [
if (replies![index].isUp)
WidgetSpan(
child: UpTag(),
),
TextSpan(
text: replies![index].member.uname + ' ',
style: TextStyle(
@ -333,6 +329,10 @@ class ReplyItemRow extends StatelessWidget {
print('跳转至用户主页'),
},
),
if (replies![index].isUp)
WidgetSpan(
child: UpTag(),
),
buildContent(context, replies![index].content),
],
),
@ -352,13 +352,14 @@ class ReplyItemRow extends StatelessWidget {
useRootNavigator: true,
isScrollControlled: true,
Container(
height: Get.size.height - Get.size.width * 9 / 16 - 50,
height: Get.size.height - Get.size.width * 9 / 16 - 45,
color: Theme.of(context).colorScheme.background,
child: Column(
children: [
AppBar(
automaticallyImplyLeading: false,
centerTitle: false,
elevation: 1,
title: Text(
'评论详情',
style: Theme.of(context).textTheme.titleMedium,
@ -367,7 +368,6 @@ class ReplyItemRow extends StatelessWidget {
IconButton(
icon: const Icon(Icons.close),
onPressed: () async {
await Future.delayed(const Duration(milliseconds: 200));
Get.back();
},
)
@ -546,7 +546,7 @@ InlineSpan buildContent(BuildContext context, content) {
arguments: {'initialPage': 0, 'imgList': picList});
},
child: Padding(
padding: EdgeInsets.only(top: 4),
padding: const EdgeInsets.only(top: 4),
child: NetworkImgLayer(
src: pictureItem['img_src'],
width: box.maxWidth / 2,
@ -634,8 +634,8 @@ class UpTag extends StatelessWidget {
Widget build(BuildContext context) {
Color primary = Theme.of(context).colorScheme.primary;
return Container(
width: tagText == 'UP' ? 25 : 32,
height: tagText == 'UP' ? 16 : 18,
width: 24,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: tagText == 'UP' ? primary : null,

View File

@ -2,6 +2,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:pilipala/http/constants.dart';
import 'package:pilipala/http/user.dart';
import 'package:pilipala/pages/mine/index.dart';
import 'package:pilipala/utils/cookie.dart';
import 'package:webview_cookie_manager/webview_cookie_manager.dart';
import 'package:webview_flutter/webview_flutter.dart';
@ -45,10 +46,10 @@ class WebviewController extends GetxController {
await SetCookie.onSet(cookies, HttpString.baseUrl);
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
var result = await UserHttp.userInfo();
bool isLogin = result['data']['isLogin'];
if (isLogin) {
if (result['status'] && result['data'].isLogin) {
SmartDialog.showToast('登录成功');
Get.back();
Get.find<MineController>().userInfo = result['data'];
// Get.back();
}
} catch (e) {
print(e);

View File

@ -1,13 +1,10 @@
// 工具函数
import 'dart:io';
import 'dart:math';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:get/get_utils/get_utils.dart';
import 'package:path_provider/path_provider.dart';
class Utils {
final ChromeSafariBrowser browser = ChromeSafariBrowser();
static Future<String> getCookiePath() async {
Directory tempDir = await getApplicationSupportDirectory();
String tempPath = "${tempDir.path}/.plpl/";
@ -138,22 +135,4 @@ class Utils {
static String makeHeroTag(v) {
return v.toString() + Random().nextInt(9999).toString();
}
static openURL(aUrl) async {
try {
await Utils().browser.open(
url: Uri.parse(aUrl),
options: ChromeSafariBrowserClassOptions(
android: AndroidChromeCustomTabsOptions(
shareState: CustomTabsShareState.SHARE_STATE_OFF,
isSingleInstance: false,
isTrustedWebActivity: false,
keepAliveEnabled: true,
),
),
);
} catch (err) {
await InAppBrowser.openWithSystemBrowser(url: Uri.parse(aUrl));
}
}
}

View File

@ -246,14 +246,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.3.0"
flutter_inappwebview:
dependency: "direct main"
description:
name: flutter_inappwebview
sha256: "1c370ac07de80a579a0047c94c5bb586128d4ef50c0f3f501d6e77010374a319"
url: "https://pub.dev"
source: hosted
version: "5.4.4"
flutter_lints:
dependency: "direct dev"
description:

View File

@ -62,7 +62,6 @@ dependencies:
share_plus: ^6.3.1
# webView
url_launcher: ^6.1.9
flutter_inappwebview: 5.4.4
webview_cookie_manager: ^2.0.6
webview_flutter: ^4.2.0