Merge branch 'main' into feature-minePage
This commit is contained in:
@ -28,7 +28,7 @@ class BlackHttp {
|
||||
static Future removeBlack({required int fid}) async {
|
||||
var res = await Request().post(
|
||||
Api.removeBlack,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'act': 6,
|
||||
'csrf': await Request.getCsrf(),
|
||||
'fid': fid,
|
||||
|
||||
@ -67,9 +67,6 @@ class DanmakaHttp {
|
||||
var response = await Request().post(
|
||||
Api.shootDanmaku,
|
||||
data: params,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
return {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:math';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../models/dynamics/result.dart';
|
||||
import '../models/dynamics/up.dart';
|
||||
import 'index.dart';
|
||||
@ -69,7 +70,7 @@ class DynamicsHttp {
|
||||
}) async {
|
||||
var res = await Request().post(
|
||||
Api.likeDynamic,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'dynamic_id': dynamicId,
|
||||
'up': up,
|
||||
'csrf': await Request.getCsrf(),
|
||||
@ -175,12 +176,15 @@ class DynamicsHttp {
|
||||
'revs_id': {'dyn_type': 8, 'rid': oid}
|
||||
};
|
||||
}
|
||||
var res = await Request().post(Api.dynamicCreate, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.dynamicCreate,
|
||||
queryParameters: {
|
||||
'platform': 'web',
|
||||
'csrf': await Request.getCsrf(),
|
||||
'x-bili-device-req-json': {'platform': 'web', 'device': 'pc'},
|
||||
'x-bili-web-req-json': {'spm_id': '333.999'},
|
||||
}, data: {
|
||||
},
|
||||
data: {
|
||||
'dyn_req': {
|
||||
'content': {
|
||||
'contents': [
|
||||
@ -195,7 +199,9 @@ class DynamicsHttp {
|
||||
}
|
||||
},
|
||||
'web_repost_src': webRepostSrc
|
||||
});
|
||||
},
|
||||
options: Options(contentType: 'application/json'),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
'status': true,
|
||||
|
||||
@ -11,7 +11,7 @@ class FavHttp {
|
||||
}) async {
|
||||
var res = await Request().post(
|
||||
Api.editFavFolder,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'title': title,
|
||||
'intro': intro,
|
||||
'media_id': mediaId,
|
||||
@ -43,7 +43,7 @@ class FavHttp {
|
||||
}) async {
|
||||
var res = await Request().post(
|
||||
Api.addFavFolder,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'title': title,
|
||||
'intro': intro,
|
||||
'cover': cover ?? '',
|
||||
|
||||
@ -260,7 +260,8 @@ class Request {
|
||||
url,
|
||||
data: data,
|
||||
queryParameters: queryParameters,
|
||||
options: options,
|
||||
options:
|
||||
options ?? Options(contentType: Headers.formUrlEncodedContentType),
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
// print('post success: ${response.data}');
|
||||
|
||||
@ -89,7 +89,9 @@ class LiveHttp {
|
||||
|
||||
// 发送弹幕
|
||||
static Future sendDanmaku({roomId, msg}) async {
|
||||
var res = await Request().post(Api.sendLiveMsg, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.sendLiveMsg,
|
||||
data: {
|
||||
'bubble': 0,
|
||||
'msg': msg,
|
||||
'color': 16777215, // 颜色
|
||||
@ -105,7 +107,8 @@ class LiveHttp {
|
||||
'roomid': roomId,
|
||||
'csrf': await Request.getCsrf(),
|
||||
'csrf_token': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
'status': true,
|
||||
@ -145,12 +148,15 @@ class LiveHttp {
|
||||
|
||||
// 直播历史记录
|
||||
static Future liveRoomEntry({required int roomId}) async {
|
||||
await Request().post(Api.liveRoomEntry, queryParameters: {
|
||||
await Request().post(
|
||||
Api.liveRoomEntry,
|
||||
data: {
|
||||
'room_id': roomId,
|
||||
'platform': 'pc',
|
||||
'csrf_token': await Request.getCsrf(),
|
||||
'csrf': await Request.getCsrf(),
|
||||
'visit_id': '',
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,9 +71,6 @@ class LoginHttp {
|
||||
var res = await Request().post(
|
||||
Api.webSmsCode,
|
||||
data: formData,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
@ -106,9 +103,6 @@ class LoginHttp {
|
||||
var res = await Request().post(
|
||||
Api.webSmsLogin,
|
||||
data: formData,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
@ -155,9 +149,6 @@ class LoginHttp {
|
||||
var res = await Request().post(
|
||||
Api.appSmsCode,
|
||||
data: data,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
}
|
||||
@ -208,9 +199,6 @@ class LoginHttp {
|
||||
var res = await Request().post(
|
||||
Api.loginInByPwdApi,
|
||||
data: data,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
}
|
||||
@ -239,17 +227,27 @@ class LoginHttp {
|
||||
var res = await Request().post(
|
||||
Api.loginInByWebPwd,
|
||||
data: formData,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
if (res.data['data']['status'] == 0) {
|
||||
return {
|
||||
'status': true,
|
||||
'data': res.data['data'],
|
||||
};
|
||||
} else {
|
||||
return {'status': false, 'data': [], 'msg': res.data['message']};
|
||||
return {
|
||||
'status': false,
|
||||
'code': 1,
|
||||
'data': res.data['data'],
|
||||
'msg': res.data['data']['message'],
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': res.data['message'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -198,13 +198,15 @@ class MemberHttp {
|
||||
|
||||
// 设置分组
|
||||
static Future addUsers(int? fids, String? tagids) async {
|
||||
var res = await Request().post(Api.addUsers, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.addUsers,
|
||||
data: {
|
||||
'fids': fids,
|
||||
'tagids': tagids ?? '0',
|
||||
'csrf': await Request.getCsrf(),
|
||||
}, data: {
|
||||
'cross_domain': true
|
||||
});
|
||||
},
|
||||
queryParameters: {'cross_domain': true},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': [], 'msg': '操作成功'};
|
||||
} else {
|
||||
@ -422,11 +424,14 @@ class MemberHttp {
|
||||
static Future cookieToKey() async {
|
||||
var authCodeRes = await getTVCode();
|
||||
if (authCodeRes['status']) {
|
||||
var res = await Request().post(Api.cookieToKey, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.cookieToKey,
|
||||
data: {
|
||||
'auth_code': authCodeRes['data'],
|
||||
'build': 708200,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
await qrcodePoll(authCodeRes['data']);
|
||||
if (res.data['code'] == 0) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:pilipala/models/msg/like.dart';
|
||||
import 'package:pilipala/models/msg/reply.dart';
|
||||
import 'package:pilipala/models/msg/system.dart';
|
||||
@ -158,9 +157,6 @@ class MsgHttp {
|
||||
'csrf_token': csrf,
|
||||
'csrf': csrf,
|
||||
},
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
|
||||
@ -78,7 +78,7 @@ class ReplyHttp {
|
||||
}) async {
|
||||
var res = await Request().post(
|
||||
Api.likeReply,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'type': type,
|
||||
'oid': oid,
|
||||
'rpid': rpid,
|
||||
|
||||
@ -154,7 +154,7 @@ class UserHttp {
|
||||
// 暂停switchStatus传true 否则false
|
||||
var res = await Request().post(
|
||||
Api.pauseHistory,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'switch': switchStatus,
|
||||
'jsonp': 'jsonp',
|
||||
'csrf': await Request.getCsrf(),
|
||||
@ -173,7 +173,7 @@ class UserHttp {
|
||||
static Future clearHistory() async {
|
||||
var res = await Request().post(
|
||||
Api.clearHistory,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'jsonp': 'jsonp',
|
||||
'csrf': await Request.getCsrf(),
|
||||
},
|
||||
@ -191,7 +191,7 @@ class UserHttp {
|
||||
}
|
||||
var res = await Request().post(
|
||||
Api.toViewLater,
|
||||
queryParameters: data,
|
||||
data: data,
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'msg': 'yeah!稍后再看'};
|
||||
@ -210,7 +210,7 @@ class UserHttp {
|
||||
params[aid != null ? 'aid' : 'viewed'] = aid ?? true;
|
||||
var res = await Request().post(
|
||||
Api.toViewDel,
|
||||
queryParameters: params,
|
||||
data: params,
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'msg': 'yeah!成功移除'};
|
||||
@ -242,7 +242,7 @@ class UserHttp {
|
||||
static Future toViewClear() async {
|
||||
var res = await Request().post(
|
||||
Api.toViewClear,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'jsonp': 'jsonp',
|
||||
'csrf': await Request.getCsrf(),
|
||||
},
|
||||
@ -258,7 +258,7 @@ class UserHttp {
|
||||
static Future delHistory(kid) async {
|
||||
var res = await Request().post(
|
||||
Api.delHistory,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'kid': kid,
|
||||
'jsonp': 'jsonp',
|
||||
'csrf': await Request.getCsrf(),
|
||||
@ -407,7 +407,7 @@ class UserHttp {
|
||||
static Future cancelSub({required int seasonId}) async {
|
||||
var res = await Request().post(
|
||||
Api.cancelSub,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'platform': 'web',
|
||||
'season_id': seasonId,
|
||||
'csrf': await Request.getCsrf(),
|
||||
@ -424,7 +424,7 @@ class UserHttp {
|
||||
static Future delFavFolder({required int mediaIds}) async {
|
||||
var res = await Request().post(
|
||||
Api.delFavFolder,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'media_ids': mediaIds,
|
||||
'platform': 'web',
|
||||
'csrf': await Request.getCsrf(),
|
||||
|
||||
@ -243,7 +243,7 @@ class VideoHttp {
|
||||
static Future coinVideo({required String bvid, required int multiply}) async {
|
||||
var res = await Request().post(
|
||||
Api.coinVideo,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'bvid': bvid,
|
||||
'multiply': multiply,
|
||||
'select_like': 0,
|
||||
@ -271,7 +271,7 @@ class VideoHttp {
|
||||
static Future oneThree({required String bvid}) async {
|
||||
var res = await Request().post(
|
||||
Api.oneThree,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'bvid': bvid,
|
||||
'csrf': await Request.getCsrf(),
|
||||
},
|
||||
@ -287,7 +287,7 @@ class VideoHttp {
|
||||
static Future likeVideo({required String bvid, required bool type}) async {
|
||||
var res = await Request().post(
|
||||
Api.likeVideo,
|
||||
queryParameters: {
|
||||
data: {
|
||||
'bvid': bvid,
|
||||
'like': type ? 1 : 2,
|
||||
'csrf': await Request.getCsrf(),
|
||||
@ -303,13 +303,16 @@ class VideoHttp {
|
||||
// (取消)收藏
|
||||
static Future favVideo(
|
||||
{required int aid, String? addIds, String? delIds}) async {
|
||||
var res = await Request().post(Api.favVideo, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.favVideo,
|
||||
data: {
|
||||
'rid': aid,
|
||||
'type': 2,
|
||||
'add_media_ids': addIds ?? '',
|
||||
'del_media_ids': delIds ?? '',
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
@ -347,14 +350,17 @@ class VideoHttp {
|
||||
if (message == '') {
|
||||
return {'status': false, 'data': [], 'msg': '请输入评论内容'};
|
||||
}
|
||||
var res = await Request().post(Api.replyAdd, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.replyAdd,
|
||||
data: {
|
||||
'type': type.index,
|
||||
'oid': oid,
|
||||
'root': root == null || root == 0 ? '' : root,
|
||||
'parent': parent == null || parent == 0 ? '' : parent,
|
||||
'message': message,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
log(res.toString());
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
@ -376,12 +382,15 @@ class VideoHttp {
|
||||
// 操作用户关系
|
||||
static Future relationMod(
|
||||
{required int mid, required int act, required int reSrc}) async {
|
||||
var res = await Request().post(Api.relationMod, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.relationMod,
|
||||
data: {
|
||||
'fid': mid,
|
||||
'act': act,
|
||||
're_src': reSrc,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
if (act == 5) {
|
||||
List<int> blackMidsList =
|
||||
@ -397,7 +406,9 @@ class VideoHttp {
|
||||
|
||||
// 视频播放进度
|
||||
static Future heartBeat({bvid, cid, progress, realtime}) async {
|
||||
await Request().post(Api.heartBeat, queryParameters: {
|
||||
await Request().post(
|
||||
Api.heartBeat,
|
||||
data: {
|
||||
// 'aid': aid,
|
||||
'bvid': bvid,
|
||||
'cid': cid,
|
||||
@ -409,15 +420,19 @@ class VideoHttp {
|
||||
// 'type': '',
|
||||
// 'sub_type': '',
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// 添加追番
|
||||
static Future bangumiAdd({int? seasonId}) async {
|
||||
var res = await Request().post(Api.bangumiAdd, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.bangumiAdd,
|
||||
data: {
|
||||
'season_id': seasonId,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'msg': res.data['result']['toast']};
|
||||
} else {
|
||||
@ -427,10 +442,13 @@ class VideoHttp {
|
||||
|
||||
// 取消追番
|
||||
static Future bangumiDel({int? seasonId}) async {
|
||||
var res = await Request().post(Api.bangumiDel, queryParameters: {
|
||||
var res = await Request().post(
|
||||
Api.bangumiDel,
|
||||
data: {
|
||||
'season_id': seasonId,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'msg': res.data['result']['toast']};
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
// 内容
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/widgets/badge.dart';
|
||||
@ -166,31 +165,6 @@ class _ContentState extends State<Content> {
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: picList,
|
||||
initIndex: initIndex,
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: picList[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
),
|
||||
),
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/constants.dart';
|
||||
@ -12,31 +11,6 @@ void onPreviewImg(currentUrl, picList, initIndex, context) {
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: picList,
|
||||
initIndex: initIndex,
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: picList[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
),
|
||||
),
|
||||
|
||||
@ -79,7 +79,21 @@ class _FavPageState extends State<FavPage> {
|
||||
const SizedBox(width: 14),
|
||||
],
|
||||
),
|
||||
body: FutureBuilder(
|
||||
body: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_favController.hasMore.value = true;
|
||||
_favController.currentPage = 1;
|
||||
setState(() {
|
||||
_futureBuilderFuture = _favController.queryFavFolder(type: 'init');
|
||||
});
|
||||
},
|
||||
child: _buildBody(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
@ -109,8 +123,7 @@ class _FavPageState extends State<FavPage> {
|
||||
RoutePush.loginRedirectPush();
|
||||
} else {
|
||||
setState(() {
|
||||
_futureBuilderFuture =
|
||||
_favController.queryFavFolder();
|
||||
_futureBuilderFuture = _favController.queryFavFolder();
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -128,7 +141,6 @@ class _FavPageState extends State<FavPage> {
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:pilipala/utils/utils.dart';
|
||||
|
||||
class FavDetailController extends GetxController {
|
||||
FavFolderItemData? item;
|
||||
RxString title = ''.obs;
|
||||
|
||||
int? mediaId;
|
||||
late String heroTag;
|
||||
@ -24,6 +25,7 @@ class FavDetailController extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
item = Get.arguments;
|
||||
title.value = item!.title!;
|
||||
if (Get.parameters.keys.isNotEmpty) {
|
||||
mediaId = int.parse(Get.parameters['mediaId']!);
|
||||
heroTag = Get.parameters['heroTag']!;
|
||||
@ -117,16 +119,18 @@ class FavDetailController extends GetxController {
|
||||
}
|
||||
|
||||
onEditFavFolder() async {
|
||||
Get.toNamed(
|
||||
var res = await Get.toNamed(
|
||||
'/favEdit',
|
||||
arguments: {
|
||||
'mediaId': mediaId.toString(),
|
||||
'title': item!.title,
|
||||
'intro': item!.intro,
|
||||
'cover': item!.cover,
|
||||
'privacy': item!.attr,
|
||||
'privacy': [23, 1].contains(item!.attr) ? 1 : 0,
|
||||
},
|
||||
);
|
||||
title.value = res['title'];
|
||||
print(title);
|
||||
}
|
||||
|
||||
Future toViewPlayAll() async {
|
||||
|
||||
@ -80,10 +80,12 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_favDetailController.item!.title!,
|
||||
Obx(
|
||||
() => Text(
|
||||
_favDetailController.title.value,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'共${_favDetailController.mediaCount}条视频',
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
@ -156,8 +158,9 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.item!.title!,
|
||||
Obx(
|
||||
() => Text(
|
||||
_favDetailController.title.value,
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
@ -165,6 +168,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
.fontSize,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_favDetailController.item!.upper!.name!,
|
||||
|
||||
@ -56,7 +56,7 @@ class FavEditController extends GetxController {
|
||||
);
|
||||
if (res['status']) {
|
||||
SmartDialog.showToast('编辑成功');
|
||||
Get.back();
|
||||
Get.back(result: {'title': title});
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ class LoginPageController extends GetxController {
|
||||
RxInt validSeconds = 180.obs;
|
||||
Timer? validTimer;
|
||||
late String qrcodeKey;
|
||||
RxBool passwordVisible = false.obs;
|
||||
|
||||
// 监听pageView切换
|
||||
void onPageChange(int index) {
|
||||
@ -128,7 +129,14 @@ class LoginPageController extends GetxController {
|
||||
if (res['status']) {
|
||||
await LoginUtils.confirmLogin('', null);
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
await SmartDialog.showToast(res['msg']);
|
||||
if (res.containsKey('code') && res['code'] == 1) {
|
||||
Get.toNamed('/webview', parameters: {
|
||||
'url': res['data']['data']['url'],
|
||||
'type': 'url',
|
||||
'pageTitle': '登录验证',
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SmartDialog.showToast(webKeyRes['msg']);
|
||||
|
||||
@ -269,25 +269,46 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 38, bottom: 15),
|
||||
child: TextFormField(
|
||||
controller: _loginPageCtr.passwordTextController,
|
||||
focusNode: _loginPageCtr.passwordTextFieldNode,
|
||||
child: Obx(() => TextFormField(
|
||||
controller:
|
||||
_loginPageCtr.passwordTextController,
|
||||
focusNode:
|
||||
_loginPageCtr.passwordTextFieldNode,
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
obscureText:
|
||||
_loginPageCtr.passwordVisible.value,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
labelText: '输入密码',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
_loginPageCtr.passwordVisible.value
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary,
|
||||
),
|
||||
onPressed: () {
|
||||
_loginPageCtr.passwordVisible.value =
|
||||
!_loginPageCtr
|
||||
.passwordVisible.value;
|
||||
},
|
||||
),
|
||||
),
|
||||
// 校验用户名
|
||||
validator: (v) {
|
||||
return v!.trim().isNotEmpty ? null : "密码不能为空";
|
||||
return v!.trim().isNotEmpty
|
||||
? null
|
||||
: "密码不能为空";
|
||||
},
|
||||
onSaved: (val) {
|
||||
print(val);
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
|
||||
@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/http/read.dart';
|
||||
import 'package:pilipala/models/read/opus.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:pilipala/plugin/pl_gallery/hero_dialog_route.dart';
|
||||
import 'package:pilipala/plugin/pl_gallery/interactiveviewer_gallery.dart';
|
||||
|
||||
@ -39,6 +38,7 @@ class OpusController extends GetxController {
|
||||
'articleType': 'cv',
|
||||
});
|
||||
} else {
|
||||
title.value = res['data'].detail!.basic!.title!;
|
||||
opusData.value = res['data'];
|
||||
}
|
||||
}
|
||||
@ -60,37 +60,21 @@ class OpusController extends GetxController {
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: picList,
|
||||
initIndex: initIndex,
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: picList[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 跳转webview
|
||||
void onJumpWebview() {
|
||||
Get.toNamed('/webview', parameters: {
|
||||
'url': url,
|
||||
'type': 'webview',
|
||||
'pageTitle': title.value,
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.removeListener(_scrollListener);
|
||||
|
||||
@ -60,9 +60,14 @@ class _OpusPageState extends State<OpusPage> {
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.more_vert_rounded),
|
||||
onPressed: () {},
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.more_vert_outlined),
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||
PopupMenuItem(
|
||||
onTap: controller.onJumpWebview,
|
||||
child: const Text('查看原网页'),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
],
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/http/read.dart';
|
||||
@ -22,6 +21,7 @@ class ReadPageController extends GetxController {
|
||||
title.value = Get.parameters['title'] ?? '';
|
||||
id = Get.parameters['id']!;
|
||||
articleType = Get.parameters['articleType']!;
|
||||
url = 'https://www.bilibili.com/read/cv$id';
|
||||
scrollController.addListener(_scrollListener);
|
||||
fetchViewInfo();
|
||||
}
|
||||
@ -50,31 +50,6 @@ class ReadPageController extends GetxController {
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: picList,
|
||||
initIndex: initIndex,
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: picList[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
),
|
||||
),
|
||||
@ -85,6 +60,15 @@ class ReadPageController extends GetxController {
|
||||
ReadHttp.getViewInfo(id: id);
|
||||
}
|
||||
|
||||
// 跳转webview
|
||||
void onJumpWebview() {
|
||||
Get.toNamed('/webview', parameters: {
|
||||
'url': url,
|
||||
'type': 'webview',
|
||||
'pageTitle': title.value,
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.removeListener(_scrollListener);
|
||||
|
||||
@ -72,9 +72,14 @@ class _ReadPageState extends State<ReadPage> {
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.more_vert_rounded),
|
||||
onPressed: () {},
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.more_vert_outlined),
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||
PopupMenuItem(
|
||||
onTap: controller.onJumpWebview,
|
||||
child: const Text('查看原网页'),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
],
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:appscheme/appscheme.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -583,34 +582,6 @@ InlineSpan buildContent(
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: picList,
|
||||
initIndex: initIndex,
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
final MainController mainController =
|
||||
Get.find<MainController>();
|
||||
mainController.imgPreviewStatus = false;
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: picList[index] + randomInt,
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
onDismissed: (int value) {
|
||||
print('onDismissed');
|
||||
|
||||
@ -1,18 +1,8 @@
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/init.dart';
|
||||
import 'package:pilipala/http/user.dart';
|
||||
import 'package:pilipala/pages/home/index.dart';
|
||||
import 'package:pilipala/utils/cookie.dart';
|
||||
import 'package:pilipala/utils/event_bus.dart';
|
||||
import 'package:pilipala/utils/id_utils.dart';
|
||||
import 'package:pilipala/utils/login.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class WebviewController extends GetxController {
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
import 'dart:convert';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
@ -170,31 +169,6 @@ class ChatItem extends StatelessWidget {
|
||||
builder: (BuildContext context) => InteractiveviewerGallery(
|
||||
sources: ctr.picList,
|
||||
initIndex: ctr.picList.indexOf(content['url']),
|
||||
itemBuilder: (
|
||||
BuildContext context,
|
||||
int index,
|
||||
bool isFocus,
|
||||
bool enablePageView,
|
||||
) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: ctr.picList[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: ctr.picList[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onPageChanged: (int pageIndex) {},
|
||||
),
|
||||
),
|
||||
|
||||
@ -2,10 +2,12 @@ library interactiveviewer_gallery;
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:pilipala/utils/download.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
@ -32,7 +34,7 @@ class InteractiveviewerGallery<T> extends StatefulWidget {
|
||||
const InteractiveviewerGallery({
|
||||
required this.sources,
|
||||
required this.initIndex,
|
||||
required this.itemBuilder,
|
||||
this.itemBuilder,
|
||||
this.maxScale = 4.5,
|
||||
this.minScale = 1.0,
|
||||
this.onPageChanged,
|
||||
@ -47,7 +49,7 @@ class InteractiveviewerGallery<T> extends StatefulWidget {
|
||||
final int initIndex;
|
||||
|
||||
/// The item content
|
||||
final IndexedFocusedWidgetBuilder itemBuilder;
|
||||
final IndexedFocusedWidgetBuilder? itemBuilder;
|
||||
|
||||
final double maxScale;
|
||||
|
||||
@ -246,12 +248,15 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
_doubleTapLocalPosition = details.localPosition;
|
||||
},
|
||||
onDoubleTap: onDoubleTap,
|
||||
child: widget.itemBuilder(
|
||||
onLongPress: onLongPress,
|
||||
child: widget.itemBuilder != null
|
||||
? widget.itemBuilder!(
|
||||
context,
|
||||
index,
|
||||
index == currentIndex,
|
||||
_enablePageView,
|
||||
),
|
||||
)
|
||||
: _itemBuilder(widget.sources, index),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -302,17 +307,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
PopupMenuItem(
|
||||
value: 1,
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text:
|
||||
widget.sources[currentIndex!].toString()))
|
||||
.then((value) {
|
||||
SmartDialog.showToast('已复制到粘贴板');
|
||||
}).catchError((err) {
|
||||
SmartDialog.showNotify(
|
||||
msg: err.toString(),
|
||||
notifyType: NotifyType.error,
|
||||
);
|
||||
});
|
||||
onCopyImg(widget.sources[currentIndex!].toString());
|
||||
},
|
||||
child: const Text("复制图片"),
|
||||
),
|
||||
@ -350,6 +345,41 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
Share.shareXFiles([XFile(path)], subject: imgUrl);
|
||||
}
|
||||
|
||||
// 复制图片
|
||||
void onCopyImg(String imgUrl) {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: widget.sources[currentIndex!].toString()))
|
||||
.then((value) {
|
||||
SmartDialog.showToast('已复制到粘贴板');
|
||||
}).catchError((err) {
|
||||
SmartDialog.showNotify(
|
||||
msg: err.toString(),
|
||||
notifyType: NotifyType.error,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _itemBuilder(sources, index) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (_enablePageView) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: sources[index],
|
||||
child: CachedNetworkImage(
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
imageUrl: sources[index],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onDoubleTap() {
|
||||
Matrix4 matrix = _transformationController!.value.clone();
|
||||
double currentScale = matrix.row0.x;
|
||||
@ -396,4 +426,61 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
.forward(from: 0)
|
||||
.whenComplete(() => _onScaleChanged(targetScale));
|
||||
}
|
||||
|
||||
onLongPress() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
useRootNavigator: true,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
padding:
|
||||
EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => Get.back(),
|
||||
child: Container(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 3,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(3))),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
onShareImg(widget.sources[currentIndex!]);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: const Text('分享图片'),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
onCopyImg(widget.sources[currentIndex!].toString());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: const Text('复制图片'),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
DownloadUtils.downloadImg(widget.sources[currentIndex!]);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: const Text('保存图片'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ class PiliSchame {
|
||||
case 'opus':
|
||||
if (path.startsWith('/detail')) {
|
||||
var opusId = path.split('/').last;
|
||||
Get.toNamed('/opus', arguments: {
|
||||
Get.toNamed('/opus', parameters: {
|
||||
'title': '',
|
||||
'id': opusId,
|
||||
'articleType': 'opus',
|
||||
|
||||
Reference in New Issue
Block a user