提交 ea72baed authored 作者: 岳维路's avatar 岳维路

合并分支 'test' 到 'sim'

Test 查看合并请求 kiwitap/zijing-app!14
...@@ -595,9 +595,11 @@ class SearchAllModel { ...@@ -595,9 +595,11 @@ class SearchAllModel {
class PopBackModel { class PopBackModel {
PopBackModel({ PopBackModel({
required this.chapterId, required this.chapterId,
required this.back required this.back,
required this.chapterName
}); });
String chapterId; String chapterId;
String chapterName;
bool back; bool back;
} }
...@@ -144,7 +144,7 @@ class _BuildItemState extends State<BuildItem> { ...@@ -144,7 +144,7 @@ class _BuildItemState extends State<BuildItem> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text(chapterModel.name??'',style: TextStyle(fontSize: 14.w,color: chapterModel.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.medium,height: 2),), Text(chapterModel.name??'',style: TextStyle(fontSize: 14.w,color: chapterModel.currentRead?AppTheme.primary:chapterModel.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.medium,height: 2),),
Gaps.hGaps5, Gaps.hGaps5,
chapterModel.isReading == 1? Container( chapterModel.isReading == 1? Container(
margin: const EdgeInsets.fromLTRB(0, 6, 0, 0), margin: const EdgeInsets.fromLTRB(0, 6, 0, 0),
......
...@@ -5,7 +5,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -5,7 +5,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
final String bookId; final String bookId;
BookDetailController(this.bookId); BookDetailController(this.bookId);
late TabController tabController;
final PageController pageController = PageController(initialPage: 0); final PageController pageController = PageController(initialPage: 0);
List <Widget>tabs = [ List <Widget>tabs = [
const Tab(text: '目录',), const Tab(text: '目录',),
...@@ -13,6 +13,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -13,6 +13,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
const Tab(text: '简介',), const Tab(text: '简介',),
const Tab(text: '本书信息',), const Tab(text: '本书信息',),
]; ];
late TabController tabController = TabController(length: tabs.length, vsync: this);
num currentChapterId = 0; num currentChapterId = 0;
...@@ -24,7 +25,6 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -24,7 +25,6 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
@override @override
void onInit() { void onInit() {
tabController = TabController(length: tabs.length, vsync: this);
super.onInit(); super.onInit();
} }
...@@ -50,26 +50,61 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -50,26 +50,61 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
} }
} }
/// 设置当前读的章节id void writeCurrentReadChapterIdToData(List<ChapterModel> data) {
void setCurrentReadChapterId(){ for(ChapterModel cModel in data){
for(ChapterModel chapterModel in chapters){
writeCurrentReadChapterIdToData(chapterModel);
}
}
void writeCurrentReadChapterIdToData(ChapterModel chapterModel){
for(ChapterModel cModel in chapterModel.children!){
cModel.currentRead = false; cModel.currentRead = false;
if(cModel.id == currentChapterId){ if(cModel.id == currentChapterId){
cModel.currentRead = true; cModel.currentRead = true;
cModel.selected = true; cModel.selected = true;
chapterModel.selected = true;
} }
writeCurrentReadChapterIdToData(chapterModel); else{
writeCurrentReadChapterIdToData(cModel.children!);
}
}
ChapterModel? tModel = findChapterById(chapters, currentChapterId);
if(tModel != null){
updateParentsStatus(chapters, tModel!);
}
}
ChapterModel? findChapterById(List<ChapterModel> data,num id){
for (ChapterModel cModel in data){
if(cModel.id == id){
return cModel;
}
ChapterModel? tModel = findChapterById(cModel.children!, id);
if(tModel !=null){
return tModel;
}
}
return null;
}
void updateParentsStatus(List<ChapterModel> data, ChapterModel model) {
ChapterModel? parentNode = findParentChapter(data, model);
while (parentNode != null) {
parentNode.selected = true;
parentNode = findParentChapter(data, parentNode);
}
}
ChapterModel? findParentChapter(List<ChapterModel> data, ChapterModel model){
for (ChapterModel tModel in data){
if(tModel.id == model.pid){
return tModel;
}
ChapterModel? cModel = findParentChapter(tModel.children!, model);
if(cModel != null) {
return cModel;
}
} }
return null;
} }
/// 写入特定数据 /// 写入特定数据
void writeData(List<ChapterModel> listA, List<ChapterModel> listB){ void writeData(List<ChapterModel> listA, List<ChapterModel> listB){
...@@ -89,7 +124,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt ...@@ -89,7 +124,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
writeData(chapters, result); writeData(chapters, result);
chapters = result; chapters = result;
setCurrentReadChapterId(); writeCurrentReadChapterIdToData(chapters);
update(); update();
} }
......
...@@ -118,6 +118,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -118,6 +118,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
controller.getChapters(); controller.getChapters();
// controller.setCurrentReadChapterId(backModel!.chapterId); // controller.setCurrentReadChapterId(backModel!.chapterId);
controller.currentChapterId = int.parse(backModel!.chapterId); controller.currentChapterId = int.parse(backModel!.chapterId);
controller.getBookDetails();
} }
} }
}, },
...@@ -217,6 +218,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -217,6 +218,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
if (backModel!.back == true){ if (backModel!.back == true){
controller.getChapters(); controller.getChapters();
controller.currentChapterId = int.parse(backModel!.chapterId); controller.currentChapterId = int.parse(backModel!.chapterId);
controller.getBookDetails();
// controller.setCurrentReadChapterId(backModel!.chapterId); // controller.setCurrentReadChapterId(backModel!.chapterId);
} }
} }
...@@ -249,6 +251,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -249,6 +251,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
final PopBackModel? backModel = await context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': chapterId,'chapter_name':chapterName,'note_id':'0'},extra: controller.bookDetails); final PopBackModel? backModel = await context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': chapterId,'chapter_name':chapterName,'note_id':'0'},extra: controller.bookDetails);
if (backModel!.back == true){ if (backModel!.back == true){
controller.getChapters(); controller.getChapters();
controller.getBookDetails();
controller.currentChapterId = int.parse(backModel!.chapterId); controller.currentChapterId = int.parse(backModel!.chapterId);
// controller.setCurrentReadChapterId(backModel!.chapterId); // controller.setCurrentReadChapterId(backModel!.chapterId);
} }
...@@ -263,6 +266,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -263,6 +266,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
if (backModel!.back == true){ if (backModel!.back == true){
controller.getChapters(); controller.getChapters();
controller.currentChapterId = int.parse(backModel!.chapterId); controller.currentChapterId = int.parse(backModel!.chapterId);
controller.getBookDetails();
// controller.setCurrentReadChapterId(backModel!.chapterId); // controller.setCurrentReadChapterId(backModel!.chapterId);
} }
......
...@@ -88,7 +88,7 @@ class LoginController extends GetxController { ...@@ -88,7 +88,7 @@ class LoginController extends GetxController {
}); });
/// 测试账号 /// 测试账号
if (kDebugMode) { if (kDebugMode) {
phoneInput.text = '13521054068'; phoneInput.text = '18810760819';
passwordInput.text = '12345678'; passwordInput.text = '12345678';
// phoneInput.text = '17311837355'; // phoneInput.text = '17311837355';
// passwordInput.text = '12345678'; // passwordInput.text = '12345678';
...@@ -151,9 +151,8 @@ class LoginController extends GetxController { ...@@ -151,9 +151,8 @@ class LoginController extends GetxController {
// UserStore.to.profile(), // UserStore.to.profile(),
// ]); // ]);
if (!context.mounted) return; if (context.mounted){
if (context.canPop()){ context.goNamed(Routes.main);
context.pop();
}else { }else {
context.goNamed(Routes.main); context.goNamed(Routes.main);
} }
......
...@@ -157,12 +157,13 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -157,12 +157,13 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
update(); update();
} }
// 设置 chapterId 和 chapterName // // 设置 chapterId 和 chapterName
void setChapterInfo({required String id,required String name}){ // void setChapterInfo({required String id,required String name}){
chapterId = id; // chapterId = id;
chapterName = name; // chapterName = name;
update(); // writeCurrentReadChapterIdToData(chapters);
} // update();
// }
void setShow(bool value) { void setShow(bool value) {
_show = !value; _show = !value;
update(); update();
...@@ -180,6 +181,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -180,6 +181,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
void selectChapter(ChapterModel model) { void selectChapter(ChapterModel model) {
chapterName = model.name??''; chapterName = model.name??'';
chapterId = model.id.toString(); chapterId = model.id.toString();
writeCurrentReadChapterIdToData(chapters);
update(); update();
} }
...@@ -455,8 +457,21 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -455,8 +457,21 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 图片链接数组 // 图片链接数组
List<String> images = []; List<String> images = [];
final status = await Tools.checkCurrentNetStatus(); final status = await Tools.checkCurrentNetStatus();
if(chatType == 0){
if(contentInput.text.isEmpty && discussInputImages.isEmpty){
Toast.show('话题必须填写内容或选择图片');
return false;
}
}
else if(chatType == 1){
if(contentInput.text.isEmpty && discussInputImages.isEmpty && discussInputAudios.isEmpty){
Toast.show('笔记必须填写内容或选择图片或音频');
}
return false;
}
// 有网情况下 先直传oss 获取到url // 有网情况下 先直传oss 获取到url
if (status){ if (status){
CustomToast.loading(); CustomToast.loading();
...@@ -841,9 +856,62 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -841,9 +856,62 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
/// 获取目录信息 /// 获取目录信息
void _getChapters() async { void _getChapters() async {
chapters = await LibraryAPI.chapters(bookId: bookId); chapters = await LibraryAPI.chapters(bookId: bookId);
writeCurrentReadChapterIdToData(chapters);
update(); update();
} }
void writeCurrentReadChapterIdToData(List<ChapterModel> data) {
for(ChapterModel cModel in data){
cModel.currentRead = false;
if(cModel.id == int.parse(chapterId)){
cModel.currentRead = true;
cModel.selected = true;
}
else{
writeCurrentReadChapterIdToData(cModel.children!);
}
}
ChapterModel? tModel = findChapterById(chapters, int.parse(chapterId));
if(tModel != null){
updateParentsStatus(chapters, tModel!);
}
}
ChapterModel? findChapterById(List<ChapterModel> data,num id){
for (ChapterModel cModel in data){
if(cModel.id == id){
return cModel;
}
ChapterModel? tModel = findChapterById(cModel.children!, id);
if(tModel !=null){
return tModel;
}
}
return null;
}
void updateParentsStatus(List<ChapterModel> data, ChapterModel model) {
ChapterModel? parentNode = findParentChapter(data, model);
while (parentNode != null) {
parentNode.selected = true;
parentNode = findParentChapter(data, parentNode);
}
}
ChapterModel? findParentChapter(List<ChapterModel> data, ChapterModel model){
for (ChapterModel tModel in data){
if(tModel.id == model.pid){
return tModel;
}
ChapterModel? cModel = findParentChapter(tModel.children!, model);
if(cModel != null) {
return cModel;
}
}
return null;
}
/// 添加阅读时长 /// 添加阅读时长
void _addReadTime({required type}) async{ void _addReadTime({required type}) async{
......
...@@ -27,328 +27,341 @@ class _ReadPageState extends State<ReadPage> { ...@@ -27,328 +27,341 @@ class _ReadPageState extends State<ReadPage> {
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
PopBackModel backModel = PopBackModel(chapterId: widget.chapterId,back: true); return GetBuilder(
return WillPopScope(
onWillPop: () async {
context.pop(backModel);
CustomToast.dismiss();
return false;
},
child: GetBuilder<ReadController>(
init: ReadController(bookId: widget.bookId, chapterId: widget.chapterId,chapterName: widget.chapterName,bookDetailModel: widget.bookDetailModel,noteId: widget.noteId), init: ReadController(bookId: widget.bookId, chapterId: widget.chapterId,chapterName: widget.chapterName,bookDetailModel: widget.bookDetailModel,noteId: widget.noteId),
builder: (readController) => Scaffold( builder: (readController) => WillPopScope(
appBar: CustomAppBar( onWillPop: () async {
titleSpacing: 0, PopBackModel backModel = PopBackModel(chapterId: readController.chapterId,back: true,chapterName: readController.chapterId);
title: Align( context.pop(backModel);
alignment: Alignment.centerLeft, CustomToast.dismiss();
child: Text(readController.chapterName), return false;
), },
centerTitle: false, child:Scaffold(
actions: [ appBar: CustomAppBar(
GestureDetector( titleSpacing: 0,
onTap: () { title: Align(
readController.getBookDown(); alignment: Alignment.centerLeft,
child: Text(readController.chapterName),
),
centerTitle: false,
actions: [
GestureDetector(
onTap: () {
readController.getBookDown();
},
child: Text(
readController.existDownFile == true?'':'离线阅读',
style: TextStyle(
fontSize: 14.w, color: Colours.c3),
))
],
),
resizeToAvoidBottomInset: false,
floatingActionButton: readController.show&& !readController.toolModel.selected?GestureDetector(
onTap: (){
readController.setShowChat(true);
readController.setChatType(0);
}, },
child: Text( child: Image.asset('assets/images/chat.png'),
readController.existDownFile == true?'':'离线阅读', ):null,
style: TextStyle( // floatingActionButtonAnimator: const NoAnimationFabAnimator(),
fontSize: 14.w, color: Colours.c3), floatingActionButtonLocation:MyFloatingActionButtonLocation(),
)) body: Container(
], color: Colors.white,
child: Stack(
children: [
InAppWebView(
initialUrlRequest:URLRequest(
// url: Uri.parse(kReadBook),
url: readController.localHtml5Path.isNotEmpty?WebUri.uri(Uri.parse(readController.localHtml5Path)): WebUri.uri(Uri.parse(kReadBook))
// url: Uri.parse("/storage/emulated/0/Android/data/com.zijin.book.flutter_book/files/174/7-325.html"),
),
initialSettings:InAppWebViewSettings(
clearCache:true,
),
// initialOptions: InAppWebViewGroupOptions(
// crossPlatform: InAppWebViewOptions(
// clearCache: true
// )
// ),
contextMenu: ContextMenu(
// options: ContextMenuOptions(hideDefaultSystemContextMenuItems: true),
settings: ContextMenuSettings(
hideDefaultSystemContextMenuItems: true
)
),
onWebViewCreated: (InAppWebViewController controller){
CustomToast.loading();
readController.webViewController = controller;
},
onConsoleMessage: (controller, consoleMessage) {
// 接收从 WebView 发送的消息
Console.log("Received message from WebView-----------------------------: ${consoleMessage.message}");
},
onLoadStop: (controller, url) {
CustomToast.dismiss();
// flutter 主动给 js 传参数
Map<String, dynamic> param = {
'book_id': readController.bookId,
'chapter_id': readController.chapterId,
'token':UserStore.to.token
};
String str = '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId},${readController.sModel.bookId =='0'?'':readController.sModel.combinedContent}';
Console.log('传给前端的参数--------------------------------$str');
controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
// // 添加单击事件
// controller.evaluateJavascript(source: '''
// document.addEventListener('click', function() {
// window.flutter_inappwebview.callHandler('onTap');
// });
// ''');
//
// // 监听js单击回调
// controller.addJavaScriptHandler(handlerName: 'onTap', callback: (args){
// readController.setShow(readController.show);
//
// });
// 监听笔记回调
controller.addJavaScriptHandler(handlerName: 'noteCallBack', callback: (args){
Console.log('监听笔记回调------------------------------------------------$args');
readController.noteTitle = args.first;
readController.setShowChat(true);
readController.setChatType(1);
// readController.titleInput.text = args.toString();
});
// 监听百科回调
controller.addJavaScriptHandler(handlerName: 'baikeCallBack', callback: (args){
Console.log('监听百科回调------------------------------------------------$args');
context.pushNamed(Routes.baiKe,queryParameters: {'keyword':args.first});
});
// 监听字典回调
controller.addJavaScriptHandler(handlerName: 'dictCallBack', callback: (args){
Console.log('监听百科回调------------------------------------------------$args');
context.pushNamed(Routes.baiDict,queryParameters: {'keyword':args.first});
});
// 监听朗读回调
controller.addJavaScriptHandler(handlerName: 'readCallBack', callback: (args){
Console.log('监听朗读回调------------------------------------------------$args');
readController.speak(args.first.toString());
// readController.speak('中国共产党(英文名:the Communist Party of China,简写CPC),'
// '创建于1921年7月23日,1921年中国共产党成立后,确立了新民主主义革命的正确道路,让灾难深重的中'
// '国人民看到了新的希望、有了新的依靠。我们党探索出农村包围城市、武装夺取政权的正确革命道路,“唤起工'
// '农千百万”“夺过鞭子揍敌人”,经过土地革命战争、抗日战争、解放战争,推翻了压在中国人民头上的帝国主义、'
// '封建主义、官僚资本主义“三座大山”,建立了人民当家作主的中华人民共和国,彻底结束了近代以来中国内忧外患、积贫积弱的悲惨境地,开启了中华民族发展进步的新纪元'
// );
});
// 监听讨论回调
controller.addJavaScriptHandler(handlerName: 'discussCallBack', callback: (args){
Console.log('监听讨论回调------------------------------------------------$args');
readController.setShowChat(true);
readController.setChatType(0);
readController.noteTitle = args.first.toString();
});
controller.addJavaScriptHandler(handlerName: 'answerResultCallBack', callback: (args){
Console.log('监听答题回调------------------------------------------------$args');
String chapterId = args.first[0].toString();
String position = args.first[1].toString();
// 0:未答题 1:答题结果
String type = args.first[2].toString();
// 测评标题
String title = args.first[3].toString();
String url = '';
// 未答题
if(type == '0'){
url = kAnswer;
}
else {
url = kAnswerResult;
}
Map<String,String> params = {
'chapter_id':chapterId,
'position':position,
'url':url,
'book_id':readController.bookId,
'token':UserStore.to.token,
'title':title
};
Console.log('监听答题回调---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.answer,queryParameters: params);
// 跳转知识测评界面
});
// 监听 上一节 下一节
controller.addJavaScriptHandler(handlerName: 'loadChapterCallBack', callback: (args){
String chapterId = args.first[0].toString();
String chapterName = args.first[1].toString();
ChapterModel chapterModel = ChapterModel(id: int.parse(chapterId), name: chapterName);
// readController.setChapterInfo(id: chapterId, name: chapterName ?? '');
readController.selectChapter(chapterModel);
Console.log('监听 上一节 下一节------------------------------------------------$args');
});
// 监听 双击回调
controller.addJavaScriptHandler(handlerName: 'dbClickCallBack', callback: (args){
readController.setShow(readController.show);
});
// 阅读页内容中的 外部链接
controller.addJavaScriptHandler(handlerName: 'openLinkCallback', callback: (args){
Console.log('监听外部链接------------------------------------------------$args');
context.pushNamed(Routes.link,queryParameters: {'url': args.first.toString()});
});
// 画廊 扩展于都
controller.addJavaScriptHandler(handlerName: 'readInfoCallback', callback: (args){
String position = args.first[0].toString();
String type = args.first[1].toString();
String title = args.first[2].toString();
Map<String,String> params = {
'chapter_id':readController.chapterId,
'position':position,
'book_id':readController.bookId,
'token':UserStore.to.token,
'title':title,
'base_url':kServerUrl,
'type':type
};
Console.log('监听画廊 扩展于都---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.readInfo,queryParameters: params);
});
// 图片预览
controller.addJavaScriptHandler(handlerName: 'scaleImageCallback', callback: (args){
String url = args.first[0].toString();
String title = args.first[1].toString();
Map<String,String> params = {
'url':url,
'title':title,
};
Console.log('监听图片预览---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.scaleImage,queryParameters: params);
});
/// 离线需要参数
// //
// Map<String, dynamic> param111 = {
// 'book_id': readController.bookId,
// 'chapter_id': readController.chapterId,
// 'token':UserStore.to.token
// };
// String jsonStr = jsonEncode(param111);
// controller.evaluateJavascript(source: 'offlineCallbackInFlutterComponent($jsonStr)');
// // controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
// 添加高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineAddNoteCallBack', callback: (args){
Map<String, dynamic> data = {};
readController.addLocalNote(data);
});
// 删除高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineDelNoteCallBack', callback: (args){
int id = 0;
readController.delLocalNote(id: id);
});
// 更新高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineUpdateNoteCallBack', callback: (args){
int id = 0;
Map<String, dynamic> data = {};
readController.updateLocalNote(id: id,data: data);
});
// 查询高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineQueryNoteCallBack', callback: (args){
});
// 上一节下一节
controller.addJavaScriptHandler(handlerName: 'offlineReadNoteCallBack', callback: (args){
int type = 0;
// 上一节
if (type == 0){
readController.readChapter(type: 0);
}
// 下一节
else{
readController.readChapter(type: 1);
}
});
},
),
Positioned(
left: 0,
right: 0,
top: 0,
bottom: 69,
child: _showContent(readController,readController.toolModel)
),
/// 底部工具栏布局
Visibility(
visible: readController.show,
child:Positioned(
left: 0,
right: 0,
bottom: 0,
child: SafeArea(
bottom: false,
child: Container(
height: 69,
color: Colors.limeAccent,
alignment: Alignment.center,
child: _createToolBar(readController)
),
),
)
),
/// 悬浮按钮点击发起话题布局
Visibility(
visible: readController.showChat,
child: Positioned(
left: 0,
right: 0,
top: 0,
bottom:0,
child: GestureDetector(
onTap: (){
readController.setShowChat(false);
readController.clearAllDiscussInput();
},
child: Container(
color: const Color(0xFF000000).withOpacity(0.5),
child: SingleChildScrollView(
reverse: true,
child: Container(
color: Colors.white,
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
// alignment:Alignment.bottomCenter,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){},
child: ReadInputDiscuss(controller: readController,)
)
),
),
),
)
),
),
],
),
),
),
), ),
resizeToAvoidBottomInset: false, );
floatingActionButton: readController.show&& !readController.toolModel.selected?GestureDetector(
onTap: (){
readController.setShowChat(true);
readController.setChatType(0);
},
child: Image.asset('assets/images/chat.png'),
):null,
// floatingActionButtonAnimator: const NoAnimationFabAnimator(),
floatingActionButtonLocation:MyFloatingActionButtonLocation(),
body: Container(
color: Colors.white,
child: Stack(
children: [
InAppWebView(
initialUrlRequest:URLRequest(
// url: Uri.parse(kReadBook),
url: readController.localHtml5Path.isNotEmpty?WebUri.uri(Uri.parse(readController.localHtml5Path)): WebUri.uri(Uri.parse(kReadBook))
// url: Uri.parse("/storage/emulated/0/Android/data/com.zijin.book.flutter_book/files/174/7-325.html"),
),
initialSettings:InAppWebViewSettings(
clearCache:true,
),
// initialOptions: InAppWebViewGroupOptions(
// crossPlatform: InAppWebViewOptions(
// clearCache: true
// )
// ),
contextMenu: ContextMenu(
// options: ContextMenuOptions(hideDefaultSystemContextMenuItems: true),
settings: ContextMenuSettings(
hideDefaultSystemContextMenuItems: true
)
),
onWebViewCreated: (InAppWebViewController controller){
CustomToast.loading();
readController.webViewController = controller;
},
onConsoleMessage: (controller, consoleMessage) {
// 接收从 WebView 发送的消息
Console.log("Received message from WebView-----------------------------: ${consoleMessage.message}");
},
onLoadStop: (controller, url) {
CustomToast.dismiss();
// flutter 主动给 js 传参数
Map<String, dynamic> param = {
'book_id': readController.bookId,
'chapter_id': readController.chapterId,
'token':UserStore.to.token
};
String str = '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId},${readController.sModel.bookId =='0'?'':readController.sModel.combinedContent}';
Console.log('传给前端的参数--------------------------------$str');
controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
// // 添加单击事件
// controller.evaluateJavascript(source: '''
// document.addEventListener('click', function() {
// window.flutter_inappwebview.callHandler('onTap');
// });
// ''');
//
// // 监听js单击回调
// controller.addJavaScriptHandler(handlerName: 'onTap', callback: (args){
// readController.setShow(readController.show);
//
// });
// 监听笔记回调
controller.addJavaScriptHandler(handlerName: 'noteCallBack', callback: (args){
Console.log('监听笔记回调------------------------------------------------$args');
readController.noteTitle = args.first;
readController.setShowChat(true);
readController.setChatType(1);
// readController.titleInput.text = args.toString();
});
// 监听百科回调
controller.addJavaScriptHandler(handlerName: 'baikeCallBack', callback: (args){
Console.log('监听百科回调------------------------------------------------$args');
context.pushNamed(Routes.baiKe,queryParameters: {'keyword':args.first});
});
// 监听字典回调
controller.addJavaScriptHandler(handlerName: 'dictCallBack', callback: (args){
Console.log('监听百科回调------------------------------------------------$args');
context.pushNamed(Routes.baiDict,queryParameters: {'keyword':args.first});
});
// 监听朗读回调
controller.addJavaScriptHandler(handlerName: 'readCallBack', callback: (args){
Console.log('监听朗读回调------------------------------------------------$args');
readController.speak(args.first.toString());
// readController.speak('中国共产党(英文名:the Communist Party of China,简写CPC),'
// '创建于1921年7月23日,1921年中国共产党成立后,确立了新民主主义革命的正确道路,让灾难深重的中'
// '国人民看到了新的希望、有了新的依靠。我们党探索出农村包围城市、武装夺取政权的正确革命道路,“唤起工'
// '农千百万”“夺过鞭子揍敌人”,经过土地革命战争、抗日战争、解放战争,推翻了压在中国人民头上的帝国主义、'
// '封建主义、官僚资本主义“三座大山”,建立了人民当家作主的中华人民共和国,彻底结束了近代以来中国内忧外患、积贫积弱的悲惨境地,开启了中华民族发展进步的新纪元'
// );
});
// 监听讨论回调
controller.addJavaScriptHandler(handlerName: 'discussCallBack', callback: (args){
Console.log('监听讨论回调------------------------------------------------$args');
readController.setShowChat(true);
readController.setChatType(0);
readController.noteTitle = args.first.toString();
});
controller.addJavaScriptHandler(handlerName: 'answerResultCallBack', callback: (args){
Console.log('监听答题回调------------------------------------------------$args');
String chapterId = args.first[0].toString();
String position = args.first[1].toString();
// 0:未答题 1:答题结果
String type = args.first[2].toString();
// 测评标题
String title = args.first[3].toString();
String url = '';
// 未答题
if(type == '0'){
url = kAnswer;
}
else {
url = kAnswerResult;
}
Map<String,String> params = {
'chapter_id':chapterId,
'position':position,
'url':url,
'book_id':readController.bookId,
'token':UserStore.to.token,
'title':title
};
Console.log('监听答题回调---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.answer,queryParameters: params);
// 跳转知识测评界面
});
// 监听 上一节 下一节
controller.addJavaScriptHandler(handlerName: 'loadChapterCallBack', callback: (args){
String chapterId = args.first[0].toString();
String chapterName = args.first[1].toString();
readController.setChapterInfo(id: chapterId, name: chapterName ?? '');
Console.log('监听 上一节 下一节------------------------------------------------$args');
});
// 监听 双击回调
controller.addJavaScriptHandler(handlerName: 'dbClickCallBack', callback: (args){
readController.setShow(readController.show);
});
// 阅读页内容中的 外部链接
controller.addJavaScriptHandler(handlerName: 'openLinkCallback', callback: (args){
Console.log('监听外部链接------------------------------------------------$args');
context.pushNamed(Routes.link,queryParameters: {'url': args.first.toString()});
});
// 画廊 扩展于都
controller.addJavaScriptHandler(handlerName: 'readInfoCallback', callback: (args){
String position = args.first[0].toString();
String type = args.first[1].toString();
String title = args.first[2].toString();
Map<String,String> params = {
'chapter_id':readController.chapterId,
'position':position,
'book_id':readController.bookId,
'token':UserStore.to.token,
'title':title,
'base_url':kServerUrl,
'type':type
};
Console.log('监听画廊 扩展于都---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.readInfo,queryParameters: params);
});
/// 离线需要参数
// //
// Map<String, dynamic> param111 = {
// 'book_id': readController.bookId,
// 'chapter_id': readController.chapterId,
// 'token':UserStore.to.token
// };
// String jsonStr = jsonEncode(param111);
// controller.evaluateJavascript(source: 'offlineCallbackInFlutterComponent($jsonStr)');
// // controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
// 添加高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineAddNoteCallBack', callback: (args){
Map<String, dynamic> data = {};
readController.addLocalNote(data);
});
// 删除高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineDelNoteCallBack', callback: (args){
int id = 0;
readController.delLocalNote(id: id);
});
// 更新高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineUpdateNoteCallBack', callback: (args){
int id = 0;
Map<String, dynamic> data = {};
readController.updateLocalNote(id: id,data: data);
});
// 查询高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineQueryNoteCallBack', callback: (args){
});
// 上一节下一节
controller.addJavaScriptHandler(handlerName: 'offlineReadNoteCallBack', callback: (args){
int type = 0;
// 上一节
if (type == 0){
readController.readChapter(type: 0);
}
// 下一节
else{
readController.readChapter(type: 1);
}
});
},
),
Positioned(
left: 0,
right: 0,
top: 0,
bottom: 69,
child: _showContent(readController,readController.toolModel)
),
/// 底部工具栏布局
Visibility(
visible: readController.show,
child:Positioned(
left: 0,
right: 0,
bottom: 0,
child: SafeArea(
bottom: false,
child: Container(
height: 69,
color: Colors.limeAccent,
alignment: Alignment.center,
child: _createToolBar(readController)
),
),
)
),
/// 悬浮按钮点击发起话题布局
Visibility(
visible: readController.showChat,
child: Positioned(
left: 0,
right: 0,
top: 0,
bottom:0,
child: GestureDetector(
onTap: (){
readController.setShowChat(false);
readController.clearAllDiscussInput();
},
child: Container(
color: const Color(0xFF000000).withOpacity(0.5),
child: SingleChildScrollView(
reverse: true,
child: Container(
color: Colors.white,
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
// alignment:Alignment.bottomCenter,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){},
child: ReadInputDiscuss(controller: readController,)
)
),
),
),
)
),
),
],
),
),
),
),
);
} }
...@@ -409,6 +422,7 @@ class _ReadPageState extends State<ReadPage> { ...@@ -409,6 +422,7 @@ class _ReadPageState extends State<ReadPage> {
controller.chooseTool(model); controller.chooseTool(model);
// 选择了新的章节 刷新 webview // 选择了新的章节 刷新 webview
controller.webViewController.reload(); controller.webViewController.reload();
// controller.setCurrentReadChapterId();
}, },
); );
} }
......
...@@ -101,87 +101,106 @@ class _ReadDiscussPageState extends State<ReadDiscussPage> { ...@@ -101,87 +101,106 @@ class _ReadDiscussPageState extends State<ReadDiscussPage> {
searchALlResults: controller.searchALlResults, searchALlResults: controller.searchALlResults,
), ),
)): )):
controller.showSearch?const SizedBox():BuildBook(bookDetailModel: widget.bookDetailModel,), Expanded(child: Stack(
controller.showSearch?const SizedBox():Expanded( children: [
child: Stack( Column(
children: [ children: [
CustomPullScrollView( BuildBook(bookDetailModel: widget.bookDetailModel,),
controller: controller.refreshController, Expanded(child: CustomPullScrollView(
onRefresh: controller.onRefresh, controller: controller.refreshController,
onLoading: controller.onLoading, onRefresh: controller.onRefresh,
child: ListView.builder( onLoading: controller.onLoading,
itemBuilder: (BuildContext context,int index){ child: ListView.builder(
DiscussModel model = controller.discuss[index]; itemBuilder: (BuildContext context,int index){
return BuildDiscuss( DiscussModel model = controller.discuss[index];
model: model, return BuildDiscuss(
controller: controller, model: model,
bookId: widget.bookDetailModel.bookId.toString(), controller: controller,
onTapDel: (DiscussModel dModel){ bookId: widget.bookDetailModel.bookId.toString(),
controller.delComment(discussModel: dModel); onTapDel: (DiscussModel dModel){
}, controller.delComment(discussModel: dModel);
); },
);
},
itemCount: controller.discuss.length,
),
),),
],
),
Visibility(
visible: controller.showReply,
child: Positioned(
bottom:-69,
left: 0,
right: 0,
top: 0,
child: GestureDetector(
onTap: (){
controller.setShow();
}, },
itemCount: controller.discuss.length, child: Container(
), // color: Colors.white,
), color: const Color(0xFF000000).withOpacity(0.5),
Visibility( child: SingleChildScrollView(
visible: controller.showReply, reverse: true,
child: Positioned( child: GestureDetector(
bottom: MediaQuery.of(context).viewInsets.bottom -69 , behavior: HitTestBehavior.opaque,
left: 0, onTap: (){},
right: 0, child: Container(
child: Container( color: Colors.white,
color: Colors.white, padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
child: TextField( child: TextField(
autofocus: true, autofocus: true,
maxLines: null, maxLines: null,
controller: controller.replyInput, controller: controller.replyInput,
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
enabledBorder: InputBorder.none, enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none, focusedBorder: InputBorder.none,
hintText: '请输入内容', hintText: '请输入内容',
hintStyle:TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9,), hintStyle:TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9,),
filled: true, filled: true,
fillColor: Colours.cF8, fillColor: Colours.cF8,
), ),
),
),
Gaps.hGaps10,
GestureDetector(
onTap: (){
controller.submit();
controller.setShow();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w),
color: AppTheme.primary,
gradient: LinearGradient(
colors: [const Color(0xFFD53676).withOpacity(0.9),AppTheme.primary] , // 不可点击时的颜色,透明度为0.7
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
), ),
), ),
padding: EdgeInsets.symmetric(horizontal:13.5.w,vertical: 4.w), Gaps.hGaps10,
child: Text('发表',style: TextStyle(fontSize: 14.w,fontWeight: Fonts.medium,color: Colors.white),), GestureDetector(
), onTap: (){
) controller.submit();
], controller.setShow();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w),
color: AppTheme.primary,
gradient: LinearGradient(
colors: [const Color(0xFFD53676).withOpacity(0.9),AppTheme.primary] , // 不可点击时的颜色,透明度为0.7
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
padding: EdgeInsets.symmetric(horizontal:13.5.w,vertical: 4.w),
child: Text('发表',style: TextStyle(fontSize: 14.w,fontWeight: Fonts.medium,color: Colors.white),),
),
)
],
),
),
), ),
), ),
), ),
), ),
) )
], ),
) )
) ],
),)
], ],
), ),
), ),
......
...@@ -100,6 +100,7 @@ class _BuildItemState extends State<BuildItem> { ...@@ -100,6 +100,7 @@ class _BuildItemState extends State<BuildItem> {
onTap: (){ onTap: (){
if(chapterModel.children!.isEmpty){ if(chapterModel.children!.isEmpty){
widget.onTapChapter(chapterModel); widget.onTapChapter(chapterModel);
chapterModel.currentRead= true;
} }
else{ else{
setState(() { setState(() {
...@@ -130,7 +131,7 @@ class _BuildItemState extends State<BuildItem> { ...@@ -130,7 +131,7 @@ class _BuildItemState extends State<BuildItem> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text(chapterModel.name??'',style: TextStyle(fontSize: 14.w,color: chapterModel.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.medium,height: 2),), Text(chapterModel.name??'',style: TextStyle(fontSize: 14.w,color: chapterModel.currentRead ?AppTheme.primary: chapterModel.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.medium,height: 2),),
Gaps.hGaps5, Gaps.hGaps5,
chapterModel.isReading == 1? Container( chapterModel.isReading == 1? Container(
margin: const EdgeInsets.fromLTRB(0, 6, 0, 0), margin: const EdgeInsets.fromLTRB(0, 6, 0, 0),
......
library scale_image;
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:go_router/go_router.dart';
import '../../utils/index.dart';
part 'view.dart';
\ No newline at end of file
part of scale_image;
class ScaleImagePage extends StatefulWidget {
final Map<String,String> params;
const ScaleImagePage({
Key? key,
required this.params
}) : super(key: key);
@override
State<ScaleImagePage> createState() => _ScaleImagePageState();
}
class _ScaleImagePageState extends State<ScaleImagePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${widget.params['title']}'),
),
body: InAppWebView(
initialUrlRequest: URLRequest(
url: WebUri.uri(Uri.parse(kScaleImage))
),
onLoadStop: (controller, url) {
String jsonStr = jsonEncode(widget.params);
controller.evaluateJavascript(source: 'callbackInFlutterComponent($jsonStr)');
},
onConsoleMessage: (controller, consoleMessage) {
// 接收从 WebView 发送的消息
Console.log("图片预览-------Received message from WebView-----------------------------: ${consoleMessage.message}");
},
)
);
}
}
...@@ -56,6 +56,7 @@ import '../pages/bai_dict/index.dart'; ...@@ -56,6 +56,7 @@ import '../pages/bai_dict/index.dart';
import '../pages/bai_ke/index.dart'; import '../pages/bai_ke/index.dart';
import '../pages/image_view/index.dart'; import '../pages/image_view/index.dart';
import '../pages/read_web/index.dart'; import '../pages/read_web/index.dart';
import '../pages/scale_image/index.dart';
import '../pages/user_edit_note/index.dart'; import '../pages/user_edit_note/index.dart';
import '../pages/user_order/index.dart'; import '../pages/user_order/index.dart';
import '../pages/user_order_cancel_detail/index.dart'; import '../pages/user_order_cancel_detail/index.dart';
......
...@@ -13,6 +13,7 @@ abstract class Routes { ...@@ -13,6 +13,7 @@ abstract class Routes {
static const web = 'read_web'; static const web = 'read_web';
static const answer = 'answer'; static const answer = 'answer';
static const readInfo = 'read_info'; static const readInfo = 'read_info';
static const scaleImage = 'scale_image';
// 支付界面 // 支付界面
static const bookPay = 'book_pay'; static const bookPay = 'book_pay';
...@@ -714,6 +715,17 @@ abstract class Routes { ...@@ -714,6 +715,17 @@ abstract class Routes {
) )
) )
), ),
GoRoute( // 画廊 扩展阅读
path: '/$scaleImage',
name: scaleImage,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: ScaleImagePage(
params: state.uri.queryParameters,
)
)
),
GoRoute( // 图片预览 GoRoute( // 图片预览
path: '/$imageView', path: '/$imageView',
name: imageView, name: imageView,
......
...@@ -2,8 +2,8 @@ part of utils; ...@@ -2,8 +2,8 @@ part of utils;
// 服务器地址 // 服务器地址
// const String kServerUrl = 'http://192.168.11.88:81'; // const String kServerUrl = 'http://192.168.11.88:81';
const String kServerUrl = 'http://8.141.148.247:7421'; // const String kServerUrl = 'http://8.141.148.247:7421';
// const String kServerUrl = 'http://1507.superge.cn:81'; const String kServerUrl = 'http://1507.superge.cn:81';
const String kLocalToken = 'local_token'; const String kLocalToken = 'local_token';
const String kLocalAccessToken = 'local_access_token'; const String kLocalAccessToken = 'local_access_token';
const String kLocalAccount = 'local_account'; const String kLocalAccount = 'local_account';
...@@ -18,17 +18,18 @@ const String kUserPriAgreement = '/html/agreement/pri_agreement.html'; ...@@ -18,17 +18,18 @@ const String kUserPriAgreement = '/html/agreement/pri_agreement.html';
const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html'; const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html';
// 错题详情页 html // 错题详情页 html
const String kUserWrongDes = '$kServerUrl/html/app/evaluating_wrong.html'; const String kUserWrongDes = 'http://150.158.138.40:9200/evaluating_wrong.html';
// 阅读页 html // 阅读页 html
const String kReadTestUnderLineBook = 'http://150.158.138.40:9200/read-unline.html'; const String kReadTestUnderLineBook = 'http://150.158.138.40:9200/read-unline.html';
const String kReadBook = '$kServerUrl/html/app/read.html'; const String kReadBook = 'http://150.158.138.40:9200/read.html';
// 答题页 // 答题页
const String kAnswer = '$kServerUrl/html/app/evaluating.html'; const String kAnswer = 'http://150.158.138.40:9200/evaluating.html';
// 答题结果页 // 答题结果页
const String kAnswerResult = '$kServerUrl/html/app/evaluating_result.html'; const String kAnswerResult = '$kServerUrl/html/app/evaluating_result.html';
// 画廊 扩展阅读 // 画廊 扩展阅读
const String kReadInfo = '$kServerUrl/html/app/read_info.html'; const String kReadInfo = 'http://150.158.138.40:9200/read_info.html';
// 阅读页 图片预览
const String kScaleImage = 'http://150.158.138.40:9200/read_img.html';
abstract class C { abstract class C {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论