提交 10e54730 authored 作者: yueweilu's avatar yueweilu

目录标识当前读到的章节

上级 8b08f2b4
......@@ -595,9 +595,11 @@ class SearchAllModel {
class PopBackModel {
PopBackModel({
required this.chapterId,
required this.back
required this.back,
required this.chapterName
});
String chapterId;
String chapterName;
bool back;
}
......@@ -144,7 +144,7 @@ class _BuildItemState extends State<BuildItem> {
Row(
crossAxisAlignment: CrossAxisAlignment.center,
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,
chapterModel.isReading == 1? Container(
margin: const EdgeInsets.fromLTRB(0, 6, 0, 0),
......
......@@ -5,7 +5,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
final String bookId;
BookDetailController(this.bookId);
late TabController tabController;
final PageController pageController = PageController(initialPage: 0);
List <Widget>tabs = [
const Tab(text: '目录',),
......@@ -13,6 +13,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
const Tab(text: '简介',),
const Tab(text: '本书信息',),
];
late TabController tabController = TabController(length: tabs.length, vsync: this);
num currentChapterId = 0;
......@@ -24,7 +25,6 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
@override
void onInit() {
tabController = TabController(length: tabs.length, vsync: this);
super.onInit();
}
......@@ -53,6 +53,11 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
/// 设置当前读的章节id
void setCurrentReadChapterId(){
for(ChapterModel chapterModel in chapters){
chapterModel.currentRead = false;
if(chapterModel.id == currentChapterId){
chapterModel.currentRead = true;
chapterModel.selected = true;
}
writeCurrentReadChapterIdToData(chapterModel);
}
......@@ -66,7 +71,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
cModel.selected = true;
chapterModel.selected = true;
}
writeCurrentReadChapterIdToData(chapterModel);
writeCurrentReadChapterIdToData(cModel);
}
}
......
......@@ -27,328 +27,328 @@ class _ReadPageState extends State<ReadPage> {
}
@override
Widget build(BuildContext context) {
PopBackModel backModel = PopBackModel(chapterId: widget.chapterId,back: true);
return WillPopScope(
onWillPop: () async {
context.pop(backModel);
CustomToast.dismiss();
return false;
},
child: GetBuilder<ReadController>(
return GetBuilder(
init: ReadController(bookId: widget.bookId, chapterId: widget.chapterId,chapterName: widget.chapterName,bookDetailModel: widget.bookDetailModel,noteId: widget.noteId),
builder: (readController) => Scaffold(
appBar: CustomAppBar(
titleSpacing: 0,
title: Align(
alignment: Alignment.centerLeft,
child: Text(readController.chapterName),
),
centerTitle: false,
actions: [
GestureDetector(
onTap: () {
readController.getBookDown();
builder: (readController) => WillPopScope(
onWillPop: () async {
PopBackModel backModel = PopBackModel(chapterId: readController.chapterId,back: true,chapterName: readController.chapterId);
context.pop(backModel);
CustomToast.dismiss();
return false;
},
child:Scaffold(
appBar: CustomAppBar(
titleSpacing: 0,
title: Align(
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(
readController.existDownFile == true?'':'离线阅读',
style: TextStyle(
fontSize: 14.w, color: Colours.c3),
))
],
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,)
)
),
),
),
)
),
),
],
),
),
),
),
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 +409,7 @@ class _ReadPageState extends State<ReadPage> {
controller.chooseTool(model);
// 选择了新的章节 刷新 webview
controller.webViewController.reload();
controller.setCurrentReadChapterId();
},
);
}
......
......@@ -100,6 +100,7 @@ class _BuildItemState extends State<BuildItem> {
onTap: (){
if(chapterModel.children!.isEmpty){
widget.onTapChapter(chapterModel);
chapterModel.currentRead= true;
}
else{
setState(() {
......@@ -130,7 +131,7 @@ class _BuildItemState extends State<BuildItem> {
Row(
crossAxisAlignment: CrossAxisAlignment.center,
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,
chapterModel.isReading == 1? Container(
margin: const EdgeInsets.fromLTRB(0, 6, 0, 0),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论