reason

修改上传视频逻辑

......@@ -280,7 +280,7 @@ class AccountPageState extends State<AccountPage> {
bottomNavigationBar: Consumer(
builder: (_, provider, __) {
return BottomAppBar(
color: Colors.grey,
color: Colors.black54,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
......
......@@ -18,6 +18,7 @@ import 'package:Parlando/membership/models/order_entity.dart';
import 'package:Parlando/membership/models/pay_entity.dart';
import 'package:Parlando/models/upload_entity.dart';
import 'package:Parlando/poem/models/lang_sort_entity.dart';
import 'package:Parlando/poem/models/poem_entity.dart';
import 'package:Parlando/poem/models/search_entity.dart';
import 'package:Parlando/timeline/models/friend_entity.dart';
......@@ -76,6 +77,9 @@ class JsonConvert {
(UploadData).toString(): UploadData.fromJson,
(UploadError).toString(): UploadError.fromJson,
(LangSortEntity).toString(): LangSortEntity.fromJson,
(PoemEntity).toString(): PoemEntity.fromJson,
(PoemData).toString(): PoemData.fromJson,
(PoemError).toString(): PoemError.fromJson,
(SearchEntity).toString(): SearchEntity.fromJson,
(SearchItems).toString(): SearchItems.fromJson,
(SearchItemsOwner).toString(): SearchItemsOwner.fromJson,
......@@ -424,6 +428,21 @@ class JsonConvert {
(Map<String, dynamic> e) => LangSortEntity.fromJson(e))
.toList() as M;
}
if (<PoemEntity>[] is M) {
return data
.map<PoemEntity>((Map<String, dynamic> e) => PoemEntity.fromJson(e))
.toList() as M;
}
if (<PoemData>[] is M) {
return data
.map<PoemData>((Map<String, dynamic> e) => PoemData.fromJson(e))
.toList() as M;
}
if (<PoemError>[] is M) {
return data
.map<PoemError>((Map<String, dynamic> e) => PoemError.fromJson(e))
.toList() as M;
}
if (<SearchEntity>[] is M) {
return data
.map<SearchEntity>(
......
import 'package:Parlando/generated/json/base/json_convert_content.dart';
import 'package:Parlando/poem/models/poem_entity.dart';
PoemEntity $PoemEntityFromJson(Map<String, dynamic> json) {
final PoemEntity poemEntity = PoemEntity();
final String? status = jsonConvert.convert<String>(json['status']);
if (status != null) {
poemEntity.status = status;
}
final int? code = jsonConvert.convert<int>(json['code']);
if (code != null) {
poemEntity.code = code;
}
final String? message = jsonConvert.convert<String>(json['message']);
if (message != null) {
poemEntity.message = message;
}
final PoemData? data = jsonConvert.convert<PoemData>(json['data']);
if (data != null) {
poemEntity.data = data;
}
final PoemError? error = jsonConvert.convert<PoemError>(json['error']);
if (error != null) {
poemEntity.error = error;
}
return poemEntity;
}
Map<String, dynamic> $PoemEntityToJson(PoemEntity entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = entity.status;
data['code'] = entity.code;
data['message'] = entity.message;
data['data'] = entity.data?.toJson();
data['error'] = entity.error?.toJson();
return data;
}
PoemData $PoemDataFromJson(Map<String, dynamic> json) {
final PoemData poemData = PoemData();
final int? id = jsonConvert.convert<int>(json['id']);
if (id != null) {
poemData.id = id;
}
final String? title = jsonConvert.convert<String>(json['title']);
if (title != null) {
poemData.title = title;
}
final String? author = jsonConvert.convert<String>(json['author']);
if (author != null) {
poemData.author = author;
}
final String? content = jsonConvert.convert<String>(json['content']);
if (content != null) {
poemData.content = content;
}
final String? annotate = jsonConvert.convert<String>(json['annotate']);
if (annotate != null) {
poemData.annotate = annotate;
}
final dynamic? spelling = jsonConvert.convert<dynamic>(json['spelling']);
if (spelling != null) {
poemData.spelling = spelling;
}
final dynamic? en = jsonConvert.convert<dynamic>(json['en']);
if (en != null) {
poemData.en = en;
}
final int? state = jsonConvert.convert<int>(json['state']);
if (state != null) {
poemData.state = state;
}
final String? createdAt = jsonConvert.convert<String>(json['created_at']);
if (createdAt != null) {
poemData.createdAt = createdAt;
}
final String? updatedAt = jsonConvert.convert<String>(json['updated_at']);
if (updatedAt != null) {
poemData.updatedAt = updatedAt;
}
return poemData;
}
Map<String, dynamic> $PoemDataToJson(PoemData entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = entity.id;
data['title'] = entity.title;
data['author'] = entity.author;
data['content'] = entity.content;
data['annotate'] = entity.annotate;
data['spelling'] = entity.spelling;
data['en'] = entity.en;
data['state'] = entity.state;
data['created_at'] = entity.createdAt;
data['updated_at'] = entity.updatedAt;
return data;
}
PoemError $PoemErrorFromJson(Map<String, dynamic> json) {
final PoemError poemError = PoemError();
return poemError;
}
Map<String, dynamic> $PoemErrorToJson(PoemError entity) {
final Map<String, dynamic> data = <String, dynamic>{};
return data;
}
......@@ -10,7 +10,7 @@ import 'error_handle.dart';
/// 默认dio配置
int _connectTimeout = 15000;
int _receiveTimeout = 15000;
int _sendTimeout = 10000;
int _sendTimeout = 100000;
String _baseUrl = '';
List<Interceptor> _interceptors = [];
......
......@@ -17,6 +17,7 @@ class HttpApi {
static const String collect = '/collect';
static const String order = '/order';
static const String pay = '/pay';
static const String poem = '/poem';
static const String search = 'search/repositories';
static const String subscriptions = 'users/simplezhli/subscriptions';
static const String upload = 'uuc/upload-inco';
......
......@@ -281,7 +281,7 @@ class VideoSlidesState extends State<VideoSlides> {
onPress: () {
eventBus.fire(TransEvent());
String url =
'${PoemRouter.poemRecordVideoPage}?id=${widget.videoId}&type=${widget.poemType}';
'${PoemRouter.poemRecordVideoPage}?id=${widget.videoId}&poem=${widget.poemId}&type=${widget.poemType}';
NavigatorUtils.push(
context,
url,
......@@ -294,7 +294,7 @@ class VideoSlidesState extends State<VideoSlides> {
eventBus.fire(TransEvent());
NavigatorUtils.push(
context,
'${PoemRouter.poemRecordAudioPage}?id=${widget.videoId}&type=${widget.poemType}',
'${PoemRouter.poemRecordAudioPage}?id=${widget.videoId}&poem=${widget.poemId}&type=${widget.poemType}',
);
}),
],
......
import 'package:Parlando/generated/json/base/json_field.dart';
import 'package:Parlando/generated/json/poem_entity.g.dart';
import 'dart:convert';
@JsonSerializable()
class PoemEntity {
String? status;
int? code;
String? message;
PoemData? data;
PoemError? error;
PoemEntity();
factory PoemEntity.fromJson(Map<String, dynamic> json) =>
$PoemEntityFromJson(json);
Map<String, dynamic> toJson() => $PoemEntityToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class PoemData {
int? id;
String? title;
String? author;
String? content;
String? annotate;
dynamic spelling;
dynamic en;
int? state;
@JSONField(name: "created_at")
String? createdAt;
@JSONField(name: "updated_at")
String? updatedAt;
PoemData();
factory PoemData.fromJson(Map<String, dynamic> json) =>
$PoemDataFromJson(json);
Map<String, dynamic> toJson() => $PoemDataToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class PoemError {
PoemError();
factory PoemError.fromJson(Map<String, dynamic> json) =>
$PoemErrorFromJson(json);
Map<String, dynamic> toJson() => $PoemErrorToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
......@@ -94,7 +94,7 @@ class _PoemCompletePageState extends State<PoemCompletePage> {
}
Future<bool> _isExit() async {
NavigatorUtils.push(context, Routes.home, clearStack: true);
NavigatorUtils.push(context, Routes.navBarPage, clearStack: true);
return Future.value(false);
}
}
......
......@@ -31,14 +31,16 @@ class PoemPublish extends StatefulWidget {
final String data;
@override
_PoemPublishState createState() => _PoemPublishState();
PoemPublishState createState() => PoemPublishState();
}
class _PoemPublishState extends State<PoemPublish> {
class PoemPublishState extends State<PoemPublish> {
bool isPublishing = false;
String _langSortName = "普通话";
int _langSortId = 1; //TODO 传入服务器的口音ID
String _address = '我在此地';
String _longitude = "";
String _latitude = "";
final LangSortProvider _provider = LangSortProvider();
final TextEditingController _msgController = TextEditingController();
......@@ -106,6 +108,8 @@ class _PoemPublishState extends State<PoemPublish> {
context, PoemRouter.addressSelectPage, (result) {
setState(() {
final PoiSearch model = result as PoiSearch;
_longitude = model.longitude!;
_latitude = model.latitude!;
_address =
'${model.provinceName!} ${model.cityName!} ${model.adName!} ${model.title!}';
});
......@@ -246,13 +250,16 @@ class _PoemPublishState extends State<PoemPublish> {
params: formData,
onSuccess: (data) {
String path = data!.data!.relativePath!;
String videoId = '${widget.id}'; //TODO 临时用video id
String videoId = '${widget.id}';
Map<String, String> params = <String, String>{
"item_id": videoId,
"item_url": path,
"content": msg,
"type": '${widget.type}',
"longitude": _longitude,
"latitude": _latitude,
"location": _address,
};
DioUtils.instance.asyncRequestNetwork(
Method.post,
......@@ -273,6 +280,7 @@ class _PoemPublishState extends State<PoemPublish> {
);
},
onError: (code, msg) {
Toast.show(msg.toString());
isPublishing = false;
setState(() {});
},
......@@ -301,7 +309,8 @@ class _PoemPublishState extends State<PoemPublish> {
TextButton(
child: const Text("残忍放弃"),
onPressed: () {
NavigatorUtils.push(context, Routes.home, clearStack: true);
NavigatorUtils.push(context, Routes.navBarPage,
clearStack: true);
},
),
],
......
import 'dart:async';
import 'dart:io';
import 'package:Parlando/net/dio_utils.dart';
import 'package:Parlando/net/http_api.dart';
import 'package:Parlando/poem/models/poem_entity.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
......@@ -18,12 +21,14 @@ import '../poem_router.dart';
class PoemRecordVideoPage extends StatefulWidget {
final int id;
final int poemId;
final int type;
const PoemRecordVideoPage({
Key? key,
required this.id,
required this.type,
required this.poemId,
}) : super(key: key);
@override
......@@ -36,7 +41,7 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
VideoPlayerController? videoController;
File? _videoFile; // 保存的视频文件位置,用于上传视频的时候用!
PoemData? _poem;
final bool _isVideoCameraSelected = true;
bool _isCameraInitialized = false;
bool _isRearCameraSelected = true;
......@@ -69,6 +74,8 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
}
});
fetchPoemDetail();
_timer = PausableTimer(
const Duration(milliseconds: 100),
() {
......@@ -85,6 +92,19 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
super.initState();
}
Future<void> fetchPoemDetail() async {
DioUtils.instance.asyncRequestNetwork<PoemEntity>(
Method.get,
"${HttpApi.poem}/${widget.poemId}",
params: [],
onSuccess: (data) {
_poem = data!.data!;
setState(() {});
},
onError: (code, msg) {},
);
}
Future<List<CameraDescription>?> initCameras() async {
try {
WidgetsFlutterBinding.ensureInitialized();
......@@ -262,14 +282,17 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
);
// TODO why pause!直接使用cancel()会出现问题,暂时这么解决
_timer.pause();
_gotoNext(currentUnix, fileFormat);
} catch (e) {
// print(e);
}
}
void _gotoNext(int currentUnix, String fileFormat) {
NavigatorUtils.push(
context,
'${PoemRouter.poemVideoPlayer}?url=$currentUnix.$fileFormat&id=${widget.id}&type=${widget.type}',
'${PoemRouter.poemVideoPlayer}?url=$currentUnix.$fileFormat&id=${widget.id}&poemId=${widget.poemId}&type=${widget.type}',
);
} catch (e) {
// print(e);
}
}
@override
......@@ -290,7 +313,7 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"题破山寺后禅院",
_poem != null ? _poem!.title.toString() : "",
style: TextStyle(
color: Colors.white,
fontSize: 28.px,
......@@ -298,7 +321,7 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
),
Gaps.vGap10,
Text(
"常建",
_poem != null ? _poem!.author.toString() : "",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
......@@ -306,7 +329,7 @@ class PoemRecordVideoPageState extends State<PoemRecordVideoPage>
),
Gaps.vGap5,
Text(
"清晨入古寺,\n初日照高林。\n曲径通幽处,\n禅房花木深。\n山光悦鸟性,\n潭影空人心。\n万籁此都寂,\n但余钟磬音。\n",
_poem != null ? _poem!.content.toString() : "",
style: TextStyle(
color: Colors.white,
fontFamily: "ZCOOLXiaoWei",
......
......@@ -6,6 +6,9 @@ import 'package:Parlando/widgets/my_app_bar.dart';
import 'package:Parlando/extension/int_extension.dart';
import 'package:path_provider/path_provider.dart';
import '../../net/dio_utils.dart';
import '../../net/http_api.dart';
import '../models/poem_entity.dart';
import '../poem_router.dart';
class PoemVideoPlayer extends StatefulWidget {
......@@ -13,6 +16,7 @@ class PoemVideoPlayer extends StatefulWidget {
final String? title;
final int id;
final int type;
final int poemId;
const PoemVideoPlayer({
Key? key,
......@@ -20,16 +24,18 @@ class PoemVideoPlayer extends StatefulWidget {
this.title,
required this.id,
required this.type,
required this.poemId,
}) : super(key: key);
@override
_PoemVideoPlayerState createState() => _PoemVideoPlayerState();
PoemVideoPlayerState createState() => PoemVideoPlayerState();
}
class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
class PoemVideoPlayerState extends State<PoemVideoPlayer> {
final FijkPlayer player = FijkPlayer();
PoemData? _poem;
_PoemVideoPlayerState();
PoemVideoPlayerState();
Future<String> _getDir() async {
final directory = await getApplicationDocumentsDirectory();
......@@ -40,13 +46,28 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
void initState() {
super.initState();
_getDir().then((value) {
String path = "$value/" + widget.url;
String path = "$value/${widget.url}";
player.setDataSource(
path,
autoPlay: true,
);
player.setLoop(0);
});
fetchPoemDetail();
}
Future<void> fetchPoemDetail() async {
DioUtils.instance.asyncRequestNetwork<PoemEntity>(
Method.get,
"${HttpApi.poem}/${widget.poemId}",
params: [],
onSuccess: (data) {
_poem = data!.data!;
setState(() {});
},
onError: (code, msg) {},
);
}
@override
......@@ -76,7 +97,7 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"题破山寺后禅院",
_poem != null ? _poem!.title.toString() : "",
style: TextStyle(
color: Colors.white,
fontSize: 28.px,
......@@ -84,7 +105,7 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
),
Gaps.vGap10,
Text(
"常建",
_poem != null ? _poem!.author.toString() : "",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
......@@ -92,7 +113,7 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
),
Gaps.vGap5,
Text(
"清晨入古寺,\n初日照高林。\n曲径通幽处,\n禅房花木深。\n山光悦鸟性,\n潭影空人心。\n万籁此都寂,\n但余钟磬音。\n",
_poem != null ? _poem!.content.toString() : "",
style: TextStyle(
color: Colors.white,
fontFamily: "ZCOOLXiaoWei",
......
......@@ -62,10 +62,12 @@ class PoemRouter implements IRouterProvider {
handler: Handler(
handlerFunc: (_, Map<String, List<String>> params) {
String? id = params['id']?.first;
int? poem = int.parse(params['poem']!.first);
String? type = params['type']?.first;
return PoemRecordVideoPage(
id: int.parse(id!),
type: int.parse(type!),
poemId: poem,
);
},
),
......@@ -78,10 +80,12 @@ class PoemRouter implements IRouterProvider {
String? url = params['url']?.first;
String? id = params['id']?.first;
String? type = params['type']?.first;
int? poem = int.parse(params['poemId']!.first);
return PoemVideoPlayer(
url: url!,
id: int.parse(id!),
type: int.parse(type!),
poemId: poem,
);
},
),
......