Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
book-app
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
book-app
Commits
df962514
提交
df962514
authored
3月 25, 2024
作者:
yueweilu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
离线文件
上级
fca1f622
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
523 行增加
和
0 行删除
+523
-0
index.dart
lib/pages/read_web/index.dart
+2
-0
view_offline.dart
lib/pages/read_web/view_offline.dart
+521
-0
没有找到文件。
lib/pages/read_web/index.dart
浏览文件 @
df962514
...
@@ -51,3 +51,4 @@ part 'discuss_controller.dart';
...
@@ -51,3 +51,4 @@ part 'discuss_controller.dart';
part
'widgets/input_discuss.dart'
;
part
'widgets/input_discuss.dart'
;
part
'widgets/item.dart'
;
part
'widgets/item.dart'
;
part
'widgets/search_all.dart'
;
part
'widgets/search_all.dart'
;
part
'view_offline.dart'
;
\ No newline at end of file
lib/pages/read_web/view_offline.dart
0 → 100644
浏览文件 @
df962514
part of
web
;
class
ReadOfflinePage
extends
StatefulWidget
{
final
String
bookId
;
final
String
chapterId
;
final
String
chapterName
;
final
String
noteId
;
final
BookDetailModel
bookDetailModel
;
const
ReadOfflinePage
({
Key
?
key
,
required
this
.
bookId
,
required
this
.
chapterId
,
required
this
.
chapterName
,
required
this
.
bookDetailModel
,
required
this
.
noteId
})
:
super
(
key:
key
);
@override
State
<
ReadPage
>
createState
()
=>
_ReadPageState
();
}
class
_ReadOfflinePageState
extends
State
<
ReadPage
>
{
@override
void
initState
()
{
super
.
initState
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
GetBuilder
(
init:
ReadController
(
bookId:
widget
.
bookId
,
chapterId:
widget
.
chapterId
,
chapterName:
widget
.
chapterName
,
bookDetailModel:
widget
.
bookDetailModel
,
noteId:
widget
.
noteId
),
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:
const
[
// 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: 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
,
// http的请求也不做限制
mixedContentMode:
MixedContentMode
.
MIXED_CONTENT_ALWAYS_ALLOW
),
// 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
);
});
// 前端 token过去回调
controller
.
addJavaScriptHandler
(
handlerName:
'refreshTokenCallback'
,
callback:
(
args
)
async
{
final
result
=
await
readController
.
refreshToken
();
Map
<
String
,
dynamic
>
param
=
{
'token'
:
result
,
};
String
jsonStr
=
jsonEncode
(
param
);
controller
.
evaluateJavascript
(
source
:
'refreshTokenSuccess(
$jsonStr
)'
);
});
/// 离线需要参数
// //
// 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
,)
)
),
),
),
)
),
),
],
),
),
),
),
);
}
/// 目录 笔记 讨论 工具栏
Widget
_createToolBar
(
ReadController
controller
){
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
children:
controller
.
tools
.
map
((
model
){
return
Expanded
(
child:
GestureDetector
(
onTap:
(){
controller
.
chooseTool
(
model
);
},
child:
Container
(
color:
Colors
.
white
,
padding:
EdgeInsets
.
only
(
bottom:
15
.
w
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisSize:
MainAxisSize
.
max
,
children:
[
SizedBox
(
width:
25
,
height:
25
,
child:
Image
.
asset
(
model
.
selected
?
model
.
activeIcon
:
model
.
icon
,
fit:
BoxFit
.
cover
,)
),
SizedBox
(
height:
2.5
.
w
,),
model
.
selected
?
Text
(
model
.
name
,
style:
TextStyle
(
fontSize:
12
.
w
,
height:
1.4
,
fontWeight:
Fonts
.
boldSemi
,
color:
AppTheme
.
primary
),)
:
Text
(
model
.
name
,
style:
TextStyle
(
fontSize:
12
.
w
,
height:
1.4
,
fontWeight:
Fonts
.
medium
,
color:
Colours
.
c6
))
],
),
),
),
);
}).
toList
()
);
}
Widget
detail
(
ReadController
controller
,
ToolModel
model
){
if
(
model
.
tag
==
0
){
return
ReadCategoryPage
(
controller:
controller
,
// 点 x 事件
onTap:
(){
controller
.
chooseTool
(
model
);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem:
(
SearchAllModel
sModel
){
controller
.
chooseTool
(
model
);
// 加载阅读界面 参数:chapter_id text
controller
.
sModel
=
sModel
;
controller
.
selectChapter
(
ChapterModel
(
id:
sModel
.
chapterId
,
name:
sModel
.
chapterName
));
controller
.
webViewController
.
reload
();
},
onTapChapter:
(
ChapterModel
chapterModel
){
// 配置选择的章节
controller
.
selectChapter
(
chapterModel
);
// 取消选中 tool
controller
.
chooseTool
(
model
);
// 选择了新的章节 刷新 webview
controller
.
webViewController
.
reload
();
// controller.setCurrentReadChapterId();
},
);
}
else
if
(
model
.
tag
==
1
){
return
ReadNotePage
(
// 点 x 事件
onTap:
(){
controller
.
chooseTool
(
model
);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem:
(
SearchAllModel
sModel
){
controller
.
chooseTool
(
model
);
// 重新加载阅读界面 参数:chapter_id text
controller
.
sModel
=
sModel
;
controller
.
selectChapter
(
ChapterModel
(
id:
sModel
.
chapterId
,
name:
sModel
.
chapterName
));
controller
.
webViewController
.
reload
();
},
// 删除笔记后 重新刷新web页
delTapCallBack:
(){
controller
.
webViewController
.
reload
();
},
bookDetailModel:
controller
.
bookDetailModel
,
chapterId:
controller
.
chapterId
,
);
}
else
if
(
model
.
tag
==
2
){
return
ReadDiscussPage
(
// 点 x 事件
onTap:
(){
controller
.
chooseTool
(
model
);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem:
(
SearchAllModel
sModel
){
controller
.
chooseTool
(
model
);
controller
.
sModel
=
sModel
;
// 重新加载阅读界面 参数:chapter_id text
controller
.
selectChapter
(
ChapterModel
(
id:
sModel
.
chapterId
,
name:
sModel
.
chapterName
));
controller
.
webViewController
.
reload
();
},
bookDetailModel:
controller
.
bookDetailModel
,
chapterId:
controller
.
chapterId
,
);
}
return
const
SizedBox
();
}
/// 目录、评论、笔记 背景
Widget
_showContent
(
ReadController
controller
,
ToolModel
model
)
{
if
(
controller
.
show
){
if
(
model
.
selected
){
return
GestureDetector
(
onTap:
(){
controller
.
chooseTool
(
model
);
},
child:
Container
(
color:
const
Color
(
0xFF000000
).
withOpacity
(
0.5
),
padding:
EdgeInsets
.
only
(
top:
MediaQuery
.
of
(
context
).
size
.
height
*
0.2
),
child:
ClipRRect
(
borderRadius:
BorderRadius
.
only
(
topRight:
Radius
.
circular
(
8
.
w
),
topLeft:
Radius
.
circular
(
8
.
w
)),
child:
Container
(
color:
Colors
.
white
,
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
(){},
child:
detail
(
controller
,
model
),
)
),
),
// child: ReadCategoryPage(),
),
);
}
else
{
return
const
SizedBox
();
}
}
return
const
SizedBox
();
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论