Skip to content
This repository has been archived by the owner on Apr 14, 2024. It is now read-only.

Commit

Permalink
feat: 添加视频投币&分享
Browse files Browse the repository at this point in the history
  • Loading branch information
lucinhu committed Mar 24, 2023
1 parent 4eeb459 commit f6ebf0f
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Flutter action
uses: subosito/flutter-action@v2
with:
flutter-version: 3.9.0-12.0.pre.18
flutter-version: 3.9.0-17.0.pre.6
channel: master

- name: Decode keystore
Expand Down
4 changes: 3 additions & 1 deletion lib/common/api/video_info_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class VideoInfoApi {
ownerMid: response.data!.owner?.mid ?? 0,
ownerName: response.data!.owner?.name ?? "",
parts: parts,
hasLike: await VideoOperationApi.hasLike(bvid: bvid));
hasLike: await VideoOperationApi.hasLike(bvid: bvid),
hasAddCoin: await VideoOperationApi.hasAddCoin(bvid: bvid),
hasFavourite: await VideoOperationApi.hasFavourite(bvid: bvid));
}

static Future<VideoPartsResponse> _requestVideoParts(
Expand Down
73 changes: 60 additions & 13 deletions lib/common/api/video_operation_api.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:bili_you/common/api/index.dart';
import 'package:bili_you/common/models/local/video/click_add_coin_result.dart';
import 'package:bili_you/common/models/local/video/click_add_share_result.dart';
import 'package:bili_you/common/models/local/video/click_like_result.dart';
import 'package:bili_you/common/utils/cookie_util.dart';
import 'package:bili_you/common/utils/index.dart';
import 'package:dio/dio.dart';

Expand All @@ -11,20 +14,11 @@ class VideoOperationApi {
//点赞还是取消赞
required bool likeOrCancelLike,
}) async {
String csrf = "";
//从cookie中获取csrf需要的数据
for (var i in (await MyDio.cookieManager.cookieJar
.loadForRequest(Uri.parse(ApiConstants.bilibiliBase)))) {
if (i.name == 'bili_jct') {
csrf = i.value;
break;
}
}
var response = await MyDio.dio.post(ApiConstants.like,
queryParameters: {
'bvid': bvid,
'like': likeOrCancelLike ? 1 : 2,
'csrf': csrf
'csrf': await CookieUtils.getCsrf()
},
options: Options(responseType: ResponseType.json));
return ClickLikeResult(
Expand All @@ -38,9 +32,62 @@ class VideoOperationApi {
///true已点赞
///false未点赞
static Future<bool> hasLike({required String bvid}) async {
var response = await MyDio.dio.get(ApiConstants.hasLike,
queryParameters: {'bvid': bvid},
options: Options(responseType: ResponseType.json));
var response = await MyDio.dio.get(
ApiConstants.hasLike,
queryParameters: {'bvid': bvid},
);
return response.data['data'] == 1;
}

///判断是否已投币
static Future<bool> hasAddCoin({required String bvid}) async {
var response = await MyDio.dio
.get(ApiConstants.hasAddCoin, queryParameters: {'bvid': bvid});
return (response.data?['data']?['multiply'] ?? 0) > 0;
}

///投币
static Future<ClickAddCoinResult> addCoin(
{required String bvid, int? num}) async {
var response = await MyDio.dio.post(ApiConstants.addCoin, queryParameters: {
'bvid': bvid,
'multiply': num ?? 1,
'csrf': await CookieUtils.getCsrf()
});
if (response.data['code'] == 0) {
return ClickAddCoinResult(isSuccess: true, error: '');
} else {
return ClickAddCoinResult(
isSuccess: false, error: response.data['message']);
}
}

///判断是否已收藏
static Future<bool> hasFavourite({required String bvid}) async {
var response = await MyDio.dio
.get(ApiConstants.hasFavourite, queryParameters: {'bvid': bvid});
return response.data?['data']?['favoured'] == true;
}

///收藏
// static Future<> addFavourite({required String rid}) async{

// }

///分享
static Future<ClickAddShareResult> share({required String bvid}) async {
var response = await MyDio.dio.post(ApiConstants.share,
queryParameters: {'bvid': bvid, 'csrf': await CookieUtils.getCsrf()});
if (response.data['code'] == 0) {
return ClickAddShareResult(
isSuccess: true,
error: '',
currentShareNum: response.data['data'] ?? 0);
} else {
return ClickAddShareResult(
isSuccess: false,
error: response.data['message'],
currentShareNum: response.data['data'] ?? 0);
}
}
}
7 changes: 7 additions & 0 deletions lib/common/models/local/video/click_add_coin_result.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class ClickAddCoinResult {
ClickAddCoinResult({required this.isSuccess, required this.error});
static ClickAddCoinResult get zero =>
ClickAddCoinResult(isSuccess: false, error: '');
bool isSuccess;
String error;
}
11 changes: 11 additions & 0 deletions lib/common/models/local/video/click_add_share_result.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ClickAddShareResult {
ClickAddShareResult(
{required this.isSuccess,
required this.error,
required this.currentShareNum});
static ClickAddShareResult get zero =>
ClickAddShareResult(isSuccess: false, error: '', currentShareNum: 0);
bool isSuccess;
String error;
int currentShareNum;
}
10 changes: 8 additions & 2 deletions lib/common/models/local/video/video_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class VideoInfo {
required this.ownerMid,
required this.ownerName,
required this.parts,
required this.hasLike});
required this.hasLike,
required this.hasAddCoin,
required this.hasFavourite});
static VideoInfo get zero => VideoInfo(
title: "",
describe: "",
Expand All @@ -36,7 +38,9 @@ class VideoInfo {
ownerMid: 0,
ownerName: "",
parts: [],
hasLike: false);
hasLike: false,
hasAddCoin: false,
hasFavourite: false);
String title;
String describe;
String bvid;
Expand All @@ -54,4 +58,6 @@ class VideoInfo {
int ownerMid;
List<PartInfo> parts;
bool hasLike;
bool hasAddCoin;
bool hasFavourite;
}
16 changes: 16 additions & 0 deletions lib/common/utils/cookie_util.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:bili_you/common/api/api_constants.dart';

import 'my_dio.dart';

class CookieUtils {
static Future<String> getCsrf() async {
//从cookie中获取csrf需要的数据
for (var i in (await MyDio.cookieManager.cookieJar
.loadForRequest(Uri.parse(ApiConstants.bilibiliBase)))) {
if (i.name == 'bili_jct') {
return i.value;
}
}
return '';
}
}
60 changes: 55 additions & 5 deletions lib/pages/bili_video/widgets/introduction/controller.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'dart:developer';

import 'package:bili_you/common/api/bangumi_api.dart';
import 'package:bili_you/common/api/related_video_api.dart';
import 'package:bili_you/common/api/video_info_api.dart';
import 'package:bili_you/common/api/index.dart';
import 'package:bili_you/common/api/video_operation_api.dart';
import 'package:bili_you/common/models/local/related_video/related_video_info.dart';
import 'package:bili_you/common/models/local/video/click_add_coin_result.dart';
import 'package:bili_you/common/models/local/video/click_add_share_result.dart';
import 'package:bili_you/common/models/local/video/click_like_result.dart';
import 'package:bili_you/common/models/local/video/video_info.dart';
import 'package:bili_you/common/utils/string_format_utils.dart';
import 'package:bili_you/common/values/cache_keys.dart';
Expand All @@ -13,6 +14,7 @@ import 'package:bili_you/pages/bili_video/view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:get/get.dart';
import 'package:share_plus/share_plus.dart';

class IntroductionController extends GetxController {
IntroductionController(
Expand Down Expand Up @@ -150,8 +152,18 @@ class IntroductionController extends GetxController {

///点赞按钮点击时
Future<void> onLikePressed() async {
var result = await VideoOperationApi.clickLike(
bvid: videoInfo.bvid, likeOrCancelLike: !videoInfo.hasLike);
late ClickLikeResult result;
try {
result = await VideoOperationApi.clickLike(
bvid: videoInfo.bvid, likeOrCancelLike: !videoInfo.hasLike);
} catch (e) {
Get.showSnackbar(GetSnackBar(
message: "失败:${result.error}",
duration: const Duration(milliseconds: 1000),
));
return;
}

if (result.isSuccess) {
videoInfo.hasLike = result.haslike;
if (result.haslike) {
Expand All @@ -175,6 +187,44 @@ class IntroductionController extends GetxController {
// ));
}

Future<void> onAddCoinPressed() async {
late ClickAddCoinResult result;
try {
result = await VideoOperationApi.addCoin(bvid: bvid);
if (result.isSuccess) {
videoInfo.hasAddCoin = result.isSuccess;
videoInfo.coinNum++;
refreshOperationButton!.call();
} else {
Get.showSnackbar(GetSnackBar(
message: "失败:${result.error}",
duration: const Duration(milliseconds: 1000),
));
}
} catch (e) {
log('onAddCoinPressed$e');
Get.showSnackbar(GetSnackBar(
message: "失败:${result.error}",
duration: const Duration(milliseconds: 1000),
));
}
}

Future<void> onAddSharePressed() async {
try {
ClickAddShareResult result = await VideoOperationApi.share(bvid: bvid);
if (result.isSuccess) {
Share.share('${ApiConstants.bilibiliBase}/video/$bvid');
videoInfo.shareNum = result.currentShareNum;
} else {
Get.rawSnackbar(message: '分享失败:${result.error}');
}
} catch (e) {
Get.rawSnackbar(message: '分享失败:$e');
}
refreshOperationButton!.call();
}

// @override
// void onInit() {
// super.onInit();
Expand Down
17 changes: 9 additions & 8 deletions lib/pages/bili_video/widgets/introduction/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,19 @@ class _IntroductionPageState extends State<IntroductionPage>
width: buttonWidth,
height: buttonHeight,
child: IconTextButton(
icon: const Icon(Icons.circle_rounded),
text: Text(
StringFormatUtils.numFormat(
controller.videoInfo.coinNum),
style: operationButtonTextStyle),
onPressed: () {},
)),
selected: controller.videoInfo.hasAddCoin,
icon: const Icon(Icons.circle_rounded),
text: Text(
StringFormatUtils.numFormat(
controller.videoInfo.coinNum),
style: operationButtonTextStyle),
onPressed: controller.onAddCoinPressed)),
const Spacer(),
SizedBox(
width: buttonWidth,
height: buttonHeight,
child: IconTextButton(
selected: controller.videoInfo.hasFavourite,
icon: const Icon(Icons.star_rounded),
text: Text(
StringFormatUtils.numFormat(
Expand All @@ -233,7 +234,7 @@ class _IntroductionPageState extends State<IntroductionPage>
StringFormatUtils.numFormat(
controller.videoInfo.shareNum),
style: operationButtonTextStyle),
onPressed: () {},
onPressed: controller.onAddSharePressed,
)),
const Spacer(),
],
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import device_info_plus
import dynamic_color
import package_info_plus
import path_provider_foundation
import share_plus
import sqflite
import url_launcher_macos
import wakelock_macos
Expand All @@ -18,6 +19,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))
Expand Down
24 changes: 24 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.6.3"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
crypto:
dependency: transitive
description:
Expand Down Expand Up @@ -761,6 +769,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.27.7"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: "8c6892037b1824e2d7e8f59d54b3105932899008642e6372e5079c6939b4b625"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "82ddd4ab9260c295e6e39612d4ff00390b9a7a21f1bb1da771e2f232d80ab8a1"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
shelf:
dependency: transitive
description:
Expand Down
11 changes: 7 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.6
version: 1.0.7

environment:
sdk: '>=2.19.0-444.2<4.0.0'
Expand Down Expand Up @@ -65,8 +65,11 @@ dependencies:
git:
url: https://github.com/xiaoyaocz/flutter_ns_danmaku.git
cached_network_image: ^3.2.3
photo_view: ^0.14.0

# webview
webview_cookie_manager: ^2.0.6
webview_flutter: ^4.0.7

# 保持常亮
wakelock: ^0.6.2
Expand All @@ -81,9 +84,9 @@ dependencies:
# hive
hive: ^2.2.3
hive_flutter: ^1.1.0
webview_cookie_manager: ^2.0.6
webview_flutter: ^4.0.7
photo_view: ^0.14.0

# 分享
share_plus: ^6.3.1



Expand Down
Loading

0 comments on commit f6ebf0f

Please sign in to comment.