mod: 样式、dio异常处理
This commit is contained in:
@ -5,19 +5,11 @@ PODS:
|
|||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- 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 (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
- image_gallery_saver (1.5.0):
|
- image_gallery_saver (1.5.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- OrderedSet (5.0.0)
|
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
@ -40,7 +32,6 @@ DEPENDENCIES:
|
|||||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
|
|
||||||
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
|
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
@ -53,7 +44,6 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
- OrderedSet
|
|
||||||
- ReachabilitySwift
|
- ReachabilitySwift
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@ -63,8 +53,6 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
flutter_inappwebview:
|
|
||||||
:path: ".symlinks/plugins/flutter_inappwebview/ios"
|
|
||||||
image_gallery_saver:
|
image_gallery_saver:
|
||||||
:path: ".symlinks/plugins/image_gallery_saver/ios"
|
:path: ".symlinks/plugins/image_gallery_saver/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
@ -86,10 +74,8 @@ SPEC CHECKSUMS:
|
|||||||
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
||||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
|
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
|
||||||
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
|
||||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||||
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
|
|||||||
@ -23,7 +23,6 @@ class VideoCardVSkeleton extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.background,
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(6),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -71,12 +71,6 @@ class VideoReplySkeleton extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(
|
|
||||||
height: 1,
|
|
||||||
indent: 52,
|
|
||||||
endIndent: 10,
|
|
||||||
color: Theme.of(context).dividerColor.withOpacity(0.08),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ class HttpError extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
errMsg,
|
errMsg,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
@ -11,21 +12,21 @@ class StatDanMu extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Color color =
|
||||||
|
theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline;
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Icon(
|
||||||
'assets/images/dm_$theme.png',
|
CupertinoIcons.ellipses_bubble,
|
||||||
width: size == 'medium' ? 16 : 14,
|
size: 14,
|
||||||
height: size == 'medium' ? 16 : 14,
|
color: color,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 3),
|
||||||
Text(
|
Text(
|
||||||
Utils.numFormat(danmu!),
|
Utils.numFormat(danmu!),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: size == 'medium' ? 12 : 11,
|
fontSize: size == 'medium' ? 12 : 11,
|
||||||
color: theme == 'white'
|
color: color,
|
||||||
? Colors.white
|
|
||||||
: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
24
lib/common/widgets/stat/up.dart
Normal file
24
lib/common/widgets/stat/up.dart
Normal 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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
@ -6,26 +7,26 @@ class StatView extends StatelessWidget {
|
|||||||
final int? view;
|
final int? view;
|
||||||
final String? size;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Color color =
|
||||||
|
theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline;
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Icon(
|
||||||
'assets/images/view_$theme.png',
|
CupertinoIcons.play_rectangle,
|
||||||
width: size == 'medium' ? 16 : 14,
|
size: 13,
|
||||||
height: size == 'medium' ? 16 : 14,
|
color: color,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 3),
|
||||||
Text(
|
Text(
|
||||||
Utils.numFormat(view!),
|
Utils.numFormat(view!),
|
||||||
// videoItem['stat']['view'].toString(),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: size == 'medium' ? 12 : 11,
|
fontSize: size == 'medium' ? 12 : 11,
|
||||||
color: theme == 'white'
|
color: color,
|
||||||
? Colors.white
|
|
||||||
: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/common/constants.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/common/widgets/stat/view.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
@ -137,11 +138,12 @@ class VideoContent extends StatelessWidget {
|
|||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
// Image.asset(
|
||||||
'assets/images/up_gray.png',
|
// 'assets/images/up_gray.png',
|
||||||
width: 14,
|
// width: 14,
|
||||||
height: 12,
|
// height: 12,
|
||||||
),
|
// ),
|
||||||
|
const UpTag(),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 2),
|
||||||
Text(
|
Text(
|
||||||
videoItem.owner.name,
|
videoItem.owner.name,
|
||||||
|
|||||||
@ -111,7 +111,7 @@ class Request {
|
|||||||
return response;
|
return response;
|
||||||
} on DioError catch (e) {
|
} on DioError catch (e) {
|
||||||
print('get error: $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;
|
return response;
|
||||||
} on DioError catch (e) {
|
} on DioError catch (e) {
|
||||||
print('post error: $e');
|
print('post error: $e');
|
||||||
return Future.error(ApiInterceptor.dioError(e));
|
return Future.error(await ApiInterceptor.dioError(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:connectivity_plus/connectivity_plus.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 {
|
class ApiInterceptor extends Interceptor {
|
||||||
@override
|
@override
|
||||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||||
// print("请求之前");
|
print("请求之前");
|
||||||
// 在请求之前添加头部或认证信息
|
// 在请求之前添加头部或认证信息
|
||||||
// options.headers['Authorization'] = 'Bearer token';
|
// options.headers['Authorization'] = 'Bearer token';
|
||||||
// options.headers['Content-Type'] = 'application/json';
|
// options.headers['Content-Type'] = 'application/json';
|
||||||
@ -13,15 +15,14 @@ class ApiInterceptor extends Interceptor {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||||
// print("响应之前");
|
|
||||||
handler.next(response);
|
handler.next(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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);
|
super.onError(err, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ class ApiInterceptor extends Interceptor {
|
|||||||
return "发送请求超时,请检查网络设置";
|
return "发送请求超时,请检查网络设置";
|
||||||
case DioErrorType.unknown:
|
case DioErrorType.unknown:
|
||||||
var res = await checkConect();
|
var res = await checkConect();
|
||||||
return "$res 网络异常,请稍后重试!";
|
return res + " \n 网络异常,请稍后重试!";
|
||||||
default:
|
default:
|
||||||
return "Dio异常";
|
return "Dio异常";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:pilipala/http/api.dart';
|
import 'package:pilipala/http/api.dart';
|
||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
|
import 'package:pilipala/models/user/info.dart';
|
||||||
|
|
||||||
class UserHttp {
|
class UserHttp {
|
||||||
static Future<dynamic> userStat({required int mid}) async {
|
static Future<dynamic> userStat({required int mid}) async {
|
||||||
@ -14,7 +15,8 @@ class UserHttp {
|
|||||||
static Future<dynamic> userInfo() async {
|
static Future<dynamic> userInfo() async {
|
||||||
var res = await Request().get(Api.userInfo);
|
var res = await Request().get(Api.userInfo);
|
||||||
if (res.data['code'] == 0) {
|
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 {
|
} else {
|
||||||
return {'status': false};
|
return {'status': false};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,39 +11,47 @@ import 'package:pilipala/models/video_detail_res.dart';
|
|||||||
class VideoHttp {
|
class VideoHttp {
|
||||||
// 首页推荐视频
|
// 首页推荐视频
|
||||||
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
||||||
var res = await Request().get(
|
try {
|
||||||
Api.recommendList,
|
var res = await Request().get(
|
||||||
data: {
|
Api.recommendList,
|
||||||
'feed_version': 'V3',
|
data: {
|
||||||
'ps': ps,
|
'feed_version': 'V3',
|
||||||
'fresh_idx': freshIdx,
|
'ps': ps,
|
||||||
},
|
'fresh_idx': freshIdx,
|
||||||
);
|
},
|
||||||
if (res.data['code'] == 0) {
|
);
|
||||||
List<RecVideoItemModel> list = [];
|
if (res.data['code'] == 0) {
|
||||||
for (var i in res.data['data']['item']) {
|
List<RecVideoItemModel> list = [];
|
||||||
list.add(RecVideoItemModel.fromJson(i));
|
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};
|
} catch (err) {
|
||||||
} else {
|
return {'status': false, 'data': [], 'msg': err};
|
||||||
return {'status': false, 'data': []};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最热视频
|
// 最热视频
|
||||||
static Future hotVideoList({required int pn, required int ps}) async {
|
static Future hotVideoList({required int pn, required int ps}) async {
|
||||||
var res = await Request().get(
|
try {
|
||||||
Api.hotList,
|
var res = await Request().get(
|
||||||
data: {'pn': pn, 'ps': ps},
|
Api.hotList,
|
||||||
);
|
data: {'pn': pn, 'ps': ps},
|
||||||
if (res.data['code'] == 0) {
|
);
|
||||||
List<HotVideoItemModel> list = [];
|
if (res.data['code'] == 0) {
|
||||||
for (var i in res.data['data']['list']) {
|
List<HotVideoItemModel> list = [];
|
||||||
list.add(HotVideoItemModel.fromJson(i));
|
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};
|
} catch (err) {
|
||||||
} else {
|
return {'status': false, 'data': [], 'msg': err};
|
||||||
return {'status': false, 'data': []};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,80 @@
|
|||||||
class UserInfoData {
|
class UserInfoData {
|
||||||
UserInfoData({
|
UserInfoData({
|
||||||
this.isLogin,
|
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;
|
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'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,6 +149,6 @@ class ReplyControl {
|
|||||||
entryText = json['sub_reply_entry_text'];
|
entryText = json['sub_reply_entry_text'];
|
||||||
titleText = json['sub_reply_title_text'];
|
titleText = json['sub_reply_title_text'];
|
||||||
time = json['time_desc'];
|
time = json['time_desc'];
|
||||||
location = json['location'] ?? '';
|
location = json['location'] != null ? json['location'].split(':')[1] : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class HomeController extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
queryRcmdFeed('init');
|
// queryRcmdFeed('init');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取推荐
|
// 获取推荐
|
||||||
@ -35,6 +35,7 @@ class HomeController extends GetxController {
|
|||||||
_currentPage += 1;
|
_currentPage += 1;
|
||||||
}
|
}
|
||||||
isLoadingMore = false;
|
isLoadingMore = false;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下拉刷新
|
// 下拉刷新
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/common/skeleton/video_card_v.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 'package:pilipala/common/widgets/video_card_v.dart';
|
||||||
import './controller.dart';
|
import './controller.dart';
|
||||||
import 'package:pilipala/common/constants.dart';
|
import 'package:pilipala/common/constants.dart';
|
||||||
@ -16,6 +17,7 @@ class HomePage extends StatefulWidget {
|
|||||||
class _HomePageState extends State<HomePage>
|
class _HomePageState extends State<HomePage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
final HomeController _homeController = Get.put(HomeController());
|
final HomeController _homeController = Get.put(HomeController());
|
||||||
|
Future? _futureBuilderFuture;
|
||||||
List videoList = [];
|
List videoList = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -24,6 +26,7 @@ class _HomePageState extends State<HomePage>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_futureBuilderFuture = _homeController.queryRcmdFeed('init');
|
||||||
_homeController.videoList.listen((value) {
|
_homeController.videoList.listen((value) {
|
||||||
videoList = value;
|
videoList = value;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -69,26 +72,25 @@ class _HomePageState extends State<HomePage>
|
|||||||
? EdgeInsets.zero
|
? EdgeInsets.zero
|
||||||
: const EdgeInsets.fromLTRB(
|
: const EdgeInsets.fromLTRB(
|
||||||
StyleString.cardSpace, 0, StyleString.cardSpace, 8),
|
StyleString.cardSpace, 0, StyleString.cardSpace, 8),
|
||||||
sliver: SliverGrid(
|
sliver: FutureBuilder(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
future: _futureBuilderFuture,
|
||||||
// 行间距
|
builder: (context, snapshot) {
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
// 列间距
|
Map data = snapshot.data as Map;
|
||||||
crossAxisSpacing: StyleString.cardSpace,
|
if (data['status']) {
|
||||||
// 列数
|
return Obx(() => contentGrid(
|
||||||
crossAxisCount: _homeController.crossAxisCount,
|
_homeController, _homeController.videoList));
|
||||||
mainAxisExtent: MediaQuery.of(context).size.width /
|
} else {
|
||||||
_homeController.crossAxisCount /
|
return HttpError(
|
||||||
StyleString.aspectRatio +
|
errMsg: data['msg'],
|
||||||
70),
|
fn: () => setState(() {}),
|
||||||
delegate: SliverChildBuilderDelegate(
|
);
|
||||||
(BuildContext context, int index) {
|
}
|
||||||
return videoList.isNotEmpty
|
} else {
|
||||||
? VideoCardV(videoItem: videoList[index])
|
// 骨架屏
|
||||||
: const VideoCardVSkeleton();
|
return contentGrid(_homeController, []);
|
||||||
},
|
}
|
||||||
childCount: videoList.isNotEmpty ? videoList.length : 10,
|
},
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const LoadingMore()
|
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 {
|
class MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
@ -10,11 +11,7 @@ class HomeAppBar extends StatelessWidget {
|
|||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
// forceElevated: true,
|
// forceElevated: true,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
toolbarHeight: Platform.isAndroid
|
toolbarHeight: MediaQuery.of(context).padding.top,
|
||||||
? (MediaQuery.of(context).padding.top + 6)
|
|
||||||
: Platform.isIOS
|
|
||||||
? MediaQuery.of(context).padding.top - 2
|
|
||||||
: kToolbarHeight,
|
|
||||||
expandedHeight: kToolbarHeight + MediaQuery.of(context).padding.top,
|
expandedHeight: kToolbarHeight + MediaQuery.of(context).padding.top,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
@ -39,18 +36,12 @@ class HomeAppBar extends StatelessWidget {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
icon: const FaIcon(
|
icon: const Icon(CupertinoIcons.search, size: 22),
|
||||||
FontAwesomeIcons.magnifyingGlass,
|
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {},
|
|
||||||
icon: const FaIcon(
|
|
||||||
FontAwesomeIcons.envelope,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
// IconButton(
|
||||||
|
// onPressed: () {},
|
||||||
|
// icon: const Icon(CupertinoIcons.bell, size: 22),
|
||||||
|
// ),
|
||||||
const SizedBox(width: 10)
|
const SizedBox(width: 10)
|
||||||
],
|
],
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
|||||||
@ -24,7 +24,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_futureBuilderFuture = _hotController!.queryHotFeed('init');
|
_futureBuilderFuture = _hotController.queryHotFeed('init');
|
||||||
_hotController.scrollController.addListener(
|
_hotController.scrollController.addListener(
|
||||||
() {
|
() {
|
||||||
if (_hotController.scrollController.position.pixels >=
|
if (_hotController.scrollController.position.pixels >=
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/pages/home/view.dart';
|
import 'package:pilipala/pages/home/view.dart';
|
||||||
@ -12,18 +13,42 @@ class MainController extends GetxController {
|
|||||||
];
|
];
|
||||||
List navigationBars = [
|
List navigationBars = [
|
||||||
{
|
{
|
||||||
'icon': const Icon(Icons.home_outlined),
|
// 'icon': const Icon(Icons.home_outlined),
|
||||||
'selectedIcon': const Icon(Icons.home),
|
// 'selectedIcon': const Icon(Icons.home),
|
||||||
|
'icon': const Icon(
|
||||||
|
CupertinoIcons.house,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
'selectedIcon': const Icon(
|
||||||
|
CupertinoIcons.house_fill,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
'label': "推荐",
|
'label': "推荐",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'icon': const Icon(Icons.whatshot_outlined),
|
// 'icon': const Icon(Icons.whatshot_outlined),
|
||||||
'selectedIcon': const Icon(Icons.whatshot_rounded),
|
// 'selectedIcon': const Icon(Icons.whatshot_rounded),
|
||||||
|
'icon': const Icon(
|
||||||
|
CupertinoIcons.flame,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
'selectedIcon': const Icon(
|
||||||
|
CupertinoIcons.flame_fill,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
'label': "热门",
|
'label': "热门",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'icon': const Icon(Icons.person_outline),
|
// 'icon': const Icon(Icons.person_outline),
|
||||||
'selectedIcon': const Icon(Icons.person),
|
// 'selectedIcon': const Icon(Icons.person),
|
||||||
|
'icon': const Icon(
|
||||||
|
CupertinoIcons.person,
|
||||||
|
size: 21,
|
||||||
|
),
|
||||||
|
'selectedIcon': const Icon(
|
||||||
|
CupertinoIcons.person_fill,
|
||||||
|
size: 21,
|
||||||
|
),
|
||||||
'label': "我的",
|
'label': "我的",
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
|
import 'package:pilipala/models/user/info.dart';
|
||||||
|
|
||||||
class MineController extends GetxController {
|
class MineController extends GetxController {
|
||||||
|
UserInfoData? userInfo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -22,13 +23,19 @@ class _MinePageState extends State<MinePage> {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
icon: const Icon(Icons.light_mode_rounded),
|
icon: const Icon(
|
||||||
|
CupertinoIcons.moon,
|
||||||
|
size: 22,
|
||||||
|
),
|
||||||
|
// icon: const Icon(
|
||||||
|
// CupertinoIcons.sun_max,
|
||||||
|
// size: 22,
|
||||||
|
// ),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
icon: const FaIcon(
|
icon: const Icon(
|
||||||
FontAwesomeIcons.sliders,
|
CupertinoIcons.slider_horizontal_3,
|
||||||
size: 18,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
@ -36,161 +43,183 @@ class _MinePageState extends State<MinePage> {
|
|||||||
),
|
),
|
||||||
body: RefreshIndicator(
|
body: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await Future.delayed(Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
},
|
},
|
||||||
child: Column(
|
child: LayoutBuilder(
|
||||||
children: [
|
builder: (context, constraint) {
|
||||||
InkWell(
|
return SingleChildScrollView(
|
||||||
onTap: () {
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
Get.toNamed(
|
child: SizedBox(
|
||||||
'/webview',
|
height: constraint.maxHeight,
|
||||||
parameters: {
|
child: Column(
|
||||||
'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: [
|
children: [
|
||||||
const SizedBox(width: 20),
|
InkWell(
|
||||||
ClipOval(
|
onTap: () {
|
||||||
child: Container(
|
Get.toNamed(
|
||||||
width: 75,
|
'/webview',
|
||||||
height: 75,
|
parameters: {
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
'url':
|
||||||
child: Center(
|
'https://passport.bilibili.com/h5-app/passport/login',
|
||||||
child: Image.asset('assets/images/loading.png'),
|
'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),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Padding(
|
||||||
'点击登录',
|
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
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(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(icon!.icon!),
|
||||||
icon!.icon!,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
text!,
|
text!,
|
||||||
|
|||||||
@ -69,9 +69,4 @@ class PreviewController extends GetxController {
|
|||||||
File(path).writeAsBytesSync(response.data);
|
File(path).writeAsBytesSync(response.data);
|
||||||
Share.shareXFiles([XFile(path)], subject: imgList[initialPage.value]);
|
Share.shareXFiles([XFile(path)], subject: imgList[initialPage.value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 浏览器中查看
|
|
||||||
void onBrowserImg() async {
|
|
||||||
Utils.openURL(imgList[initialPage.value]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,11 +74,6 @@ class _ImagePreviewState extends State<ImagePreview>
|
|||||||
onTap: _previewController.onSaveImg,
|
onTap: _previewController.onSaveImg,
|
||||||
child: const Text('保存'),
|
child: const Text('保存'),
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
|
||||||
value: 'browser',
|
|
||||||
onTap: _previewController.onBrowserImg,
|
|
||||||
child: const Text('浏览器中查看'),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -246,8 +247,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: const [
|
children: const [
|
||||||
Icon(
|
Icon(
|
||||||
FontAwesomeIcons.lemon,
|
CupertinoIcons.plus,
|
||||||
size: 15,
|
size: 16,
|
||||||
),
|
),
|
||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
Text('关注'),
|
Text('关注'),
|
||||||
@ -383,7 +384,7 @@ class ActionItem extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(icon!.icon!,
|
Icon(icon!.icon!,
|
||||||
size: 20,
|
size: 21,
|
||||||
color: selectStatus
|
color: selectStatus
|
||||||
? Theme.of(context).primaryColor
|
? Theme.of(context).primaryColor
|
||||||
: Theme.of(context).colorScheme.outline),
|
: Theme.of(context).colorScheme.outline),
|
||||||
|
|||||||
@ -18,15 +18,15 @@ class ReplyItem extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(12, 8, 8, 2),
|
padding: const EdgeInsets.fromLTRB(12, 6, 8, 0),
|
||||||
child: content(context),
|
child: content(context),
|
||||||
),
|
),
|
||||||
Divider(
|
// Divider(
|
||||||
height: 1,
|
// height: 1,
|
||||||
indent: 52,
|
// indent: 52,
|
||||||
endIndent: 10,
|
// endIndent: 10,
|
||||||
color: Theme.of(context).dividerColor.withOpacity(0.08),
|
// color: Theme.of(context).dividerColor.withOpacity(0.08),
|
||||||
)
|
// )
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -154,7 +154,7 @@ class ReplyItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
// title
|
// title
|
||||||
Container(
|
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(
|
child: SelectableRegion(
|
||||||
magnifierConfiguration: const TextMagnifierConfiguration(),
|
magnifierConfiguration: const TextMagnifierConfiguration(),
|
||||||
focusNode: FocusNode(),
|
focusNode: FocusNode(),
|
||||||
@ -201,7 +201,7 @@ class ReplyItem extends StatelessWidget {
|
|||||||
.copyWith(color: Theme.of(context).colorScheme.outline),
|
.copyWith(color: Theme.of(context).colorScheme.outline),
|
||||||
),
|
),
|
||||||
if (replyItem!.replyControl != null &&
|
if (replyItem!.replyControl != null &&
|
||||||
replyItem!.replyControl!.location != null)
|
replyItem!.replyControl!.location != '')
|
||||||
Text(
|
Text(
|
||||||
' • ${replyItem!.replyControl!.location!}',
|
' • ${replyItem!.replyControl!.location!}',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
@ -315,10 +315,6 @@ class ReplyItemRow extends StatelessWidget {
|
|||||||
maxLines: extraRow == 1 ? 2 : null,
|
maxLines: extraRow == 1 ? 2 : null,
|
||||||
TextSpan(
|
TextSpan(
|
||||||
children: [
|
children: [
|
||||||
if (replies![index].isUp)
|
|
||||||
WidgetSpan(
|
|
||||||
child: UpTag(),
|
|
||||||
),
|
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: replies![index].member.uname + ' ',
|
text: replies![index].member.uname + ' ',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -333,6 +329,10 @@ class ReplyItemRow extends StatelessWidget {
|
|||||||
print('跳转至用户主页'),
|
print('跳转至用户主页'),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (replies![index].isUp)
|
||||||
|
WidgetSpan(
|
||||||
|
child: UpTag(),
|
||||||
|
),
|
||||||
buildContent(context, replies![index].content),
|
buildContent(context, replies![index].content),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -352,13 +352,14 @@ class ReplyItemRow extends StatelessWidget {
|
|||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
Container(
|
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,
|
color: Theme.of(context).colorScheme.background,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
AppBar(
|
AppBar(
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
|
elevation: 1,
|
||||||
title: Text(
|
title: Text(
|
||||||
'评论详情',
|
'评论详情',
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
@ -367,7 +368,6 @@ class ReplyItemRow extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Future.delayed(const Duration(milliseconds: 200));
|
|
||||||
Get.back();
|
Get.back();
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -546,7 +546,7 @@ InlineSpan buildContent(BuildContext context, content) {
|
|||||||
arguments: {'initialPage': 0, 'imgList': picList});
|
arguments: {'initialPage': 0, 'imgList': picList});
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
child: NetworkImgLayer(
|
child: NetworkImgLayer(
|
||||||
src: pictureItem['img_src'],
|
src: pictureItem['img_src'],
|
||||||
width: box.maxWidth / 2,
|
width: box.maxWidth / 2,
|
||||||
@ -634,8 +634,8 @@ class UpTag extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Color primary = Theme.of(context).colorScheme.primary;
|
Color primary = Theme.of(context).colorScheme.primary;
|
||||||
return Container(
|
return Container(
|
||||||
width: tagText == 'UP' ? 25 : 32,
|
width: 24,
|
||||||
height: tagText == 'UP' ? 16 : 18,
|
height: 15,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(3),
|
borderRadius: BorderRadius.circular(3),
|
||||||
color: tagText == 'UP' ? primary : null,
|
color: tagText == 'UP' ? primary : null,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/http/constants.dart';
|
import 'package:pilipala/http/constants.dart';
|
||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
|
import 'package:pilipala/pages/mine/index.dart';
|
||||||
import 'package:pilipala/utils/cookie.dart';
|
import 'package:pilipala/utils/cookie.dart';
|
||||||
import 'package:webview_cookie_manager/webview_cookie_manager.dart';
|
import 'package:webview_cookie_manager/webview_cookie_manager.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.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(cookies, HttpString.baseUrl);
|
||||||
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
|
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
|
||||||
var result = await UserHttp.userInfo();
|
var result = await UserHttp.userInfo();
|
||||||
bool isLogin = result['data']['isLogin'];
|
if (result['status'] && result['data'].isLogin) {
|
||||||
if (isLogin) {
|
|
||||||
SmartDialog.showToast('登录成功');
|
SmartDialog.showToast('登录成功');
|
||||||
Get.back();
|
Get.find<MineController>().userInfo = result['data'];
|
||||||
|
// Get.back();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
// 工具函数
|
// 工具函数
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
import 'package:get/get_utils/get_utils.dart';
|
import 'package:get/get_utils/get_utils.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
final ChromeSafariBrowser browser = ChromeSafariBrowser();
|
|
||||||
|
|
||||||
static Future<String> getCookiePath() async {
|
static Future<String> getCookiePath() async {
|
||||||
Directory tempDir = await getApplicationSupportDirectory();
|
Directory tempDir = await getApplicationSupportDirectory();
|
||||||
String tempPath = "${tempDir.path}/.plpl/";
|
String tempPath = "${tempDir.path}/.plpl/";
|
||||||
@ -138,22 +135,4 @@ class Utils {
|
|||||||
static String makeHeroTag(v) {
|
static String makeHeroTag(v) {
|
||||||
return v.toString() + Random().nextInt(9999).toString();
|
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -246,14 +246,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.0"
|
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:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -62,7 +62,6 @@ dependencies:
|
|||||||
share_plus: ^6.3.1
|
share_plus: ^6.3.1
|
||||||
# webView
|
# webView
|
||||||
url_launcher: ^6.1.9
|
url_launcher: ^6.1.9
|
||||||
flutter_inappwebview: 5.4.4
|
|
||||||
webview_cookie_manager: ^2.0.6
|
webview_cookie_manager: ^2.0.6
|
||||||
webview_flutter: ^4.2.0
|
webview_flutter: ^4.2.0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user