plugin-jm-server 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/PKG-INFO +55 -33
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/README.md +54 -32
- plugin_jm_server-0.2.1/src/plugin_jm_server/__init__.py +3 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/app.py +14 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/index_spa.css +87 -6
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/index_spa.js +282 -1
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/index_spa.html +9 -6
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/PKG-INFO +55 -33
- plugin_jm_server-0.2.0/src/plugin_jm_server/__init__.py +0 -3
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/setup.cfg +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/setup.py +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/driver.py +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/files.py +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/all.min.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/bootstrap.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/download_error.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_download_error.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_index.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_login.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_upload.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/normalize.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/index.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/login.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/style_photo.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/upload.css +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/img/bg.jpg +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/img/m_bg.jpeg +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/common.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/h5/m_index.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/h5/m_upload.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/index.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery-3.7.1.min.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery.album-0.2.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery.lazyload-2.0.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery.photo-0.3.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/upload.js +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/webfonts/fa-regular-400.woff2 +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/webfonts/fa-solid-900.woff2 +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/download_error.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/index.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/jm_view.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/login.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_download_error.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_index.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_jm_view.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_login.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_upload.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/upload.html +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/SOURCES.txt +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/dependency_links.txt +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/requires.txt +0 -0
- {plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plugin_jm_server
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: plugin_jm_server, a plugin for jmcomic that can be used to view comics in a web browser.
|
|
5
5
|
Home-page: https://github.com/hect0x7/plugin-jm-server
|
|
6
6
|
Author: hect0x7
|
|
@@ -44,20 +44,33 @@ Dynamic: summary
|
|
|
44
44
|
|
|
45
45
|
* 双页阅读插件:https://sleazyfork.org/zh-CN/scripts/374903-comicread
|
|
46
46
|
|
|
47
|
-
#
|
|
47
|
+
# 效果图(文件浏览、整章看图)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
## 1. 电脑浏览器访问
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
### 登录页
|
|
52
|
+

|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
### 文件夹列表页
|
|
55
|
+

|
|
56
|
+

|
|
54
57
|
|
|
58
|
+
### 看本模式
|
|
59
|
+

|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
### 文件夹&看本 二合一模式
|
|
62
|
+

|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
## 2. 手机浏览器访问
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
### 登录页
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
### 文件夹列表页
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
### 看本模式
|
|
73
|
+

|
|
61
74
|
|
|
62
75
|
|
|
63
76
|
# 使用方式
|
|
@@ -70,7 +83,6 @@ pip install plugin_jm_server
|
|
|
70
83
|
```
|
|
71
84
|
|
|
72
85
|
|
|
73
|
-
|
|
74
86
|
## 2. 运行代码
|
|
75
87
|
|
|
76
88
|
* **HTTP版**
|
|
@@ -135,31 +147,41 @@ op.wait_all_plugins_finish()
|
|
|
135
147
|
```
|
|
136
148
|
|
|
137
149
|
|
|
138
|
-
|
|
150
|
+
## 前端页面与功能介绍
|
|
151
|
+
|
|
152
|
+
本项目提供了一套完整的 Web 前端界面,用于管理和浏览本地图片资源。主要包含以下三个核心页面及其功能:
|
|
153
|
+
|
|
154
|
+
### 1. 登录页
|
|
155
|
+
为了保护个人隐私,系统提供了简单的访问控制。
|
|
156
|
+
* **密码验证**:启动时可配置密码,访问时需校验通过。
|
|
157
|
+
* **设备自适应**:根据访问设备(手机/电脑)自动适配最佳的登录布局。
|
|
158
|
+
|
|
159
|
+
### 2. 文件夹浏览页(主页)
|
|
160
|
+
这是资源管理的核心入口,支持高效的文件查找与导航。目前最新版本采用了 SPA(单页应用)架构进行全面增强:
|
|
161
|
+
* **智能路径导航**:
|
|
162
|
+
* **路径补全**:输入路径时自动联想下级文件夹,支持键盘上下键选择及回车跳转。
|
|
163
|
+
* **层级跳转**:输入框支持“..”快速返回上一级,并提供“确认”按钮进行精准跳转。
|
|
164
|
+
* **可视化展示**:
|
|
165
|
+
* **文件夹预览**:鼠标悬停在文件夹上时,会自动展示该文件夹内的首张图片作为封面预览。
|
|
166
|
+
* **类型区分**:通过文件夹角标(图标)清晰区分普通文件夹与特殊资源文件夹。
|
|
167
|
+
* **辅助功能**:
|
|
168
|
+
* **书签管理**:支持将常看目录加入左侧书签栏,方便下次快速访问。
|
|
169
|
+
* **本地交互**:支持通过网页菜单直接打开服务器端对应的本地文件夹窗口(Explorer)。
|
|
170
|
+
|
|
171
|
+
### 3. 图片阅读页(看本模式)
|
|
172
|
+
专为漫画阅读优化的沉浸式浏览页面。
|
|
173
|
+
* **加载优化**:采用图片懒加载机制,流畅浏览含有数百张图片的大型章节,节省系统资源。
|
|
174
|
+
* **多端适配**:
|
|
175
|
+
* **PC端**:适合大屏浏览,支持浮动工具栏进行页面跳转、全屏切换等。
|
|
176
|
+
* **移动端**:适配触摸操作,提供更好的手机阅读体验。
|
|
177
|
+
* **阅读辅助**:
|
|
178
|
+
* **浮动菜单**:提供“回到顶部”、“加载全部图片”及“在资源管理器打开”等便捷操作。
|
|
179
|
+
* **键盘支持**:支持常用快捷键进行页面滚动和翻页。
|
|
139
180
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
### 登录页
|
|
143
|
-

|
|
144
|
-
|
|
145
|
-
### 文件夹列表页
|
|
146
|
-

|
|
147
|
-

|
|
148
|
-
|
|
149
|
-
### 看本模式
|
|
150
|
-

|
|
151
|
-
|
|
152
|
-
### 文件夹&看本 二合一模式
|
|
153
|
-

|
|
154
|
-
|
|
155
|
-
## 2. 手机浏览器访问
|
|
156
|
-
|
|
157
|
-
### 登录页
|
|
158
|
-

|
|
181
|
+
# 想法起源
|
|
159
182
|
|
|
160
|
-
|
|
161
|
-

|
|
183
|
+
想法起源:https://github.com/hect0x7/JMComic-Crawler-Python/issues/192
|
|
162
184
|
|
|
163
|
-
|
|
164
|
-

|
|
185
|
+
基于原项目:https://github.com/AiCorein/Flask-Files-Server
|
|
165
186
|
|
|
187
|
+
为了方便修改,将原项目中的文件复制到本项目中,然后进行修改
|
|
@@ -8,20 +8,33 @@
|
|
|
8
8
|
|
|
9
9
|
* 双页阅读插件:https://sleazyfork.org/zh-CN/scripts/374903-comicread
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# 效果图(文件浏览、整章看图)
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## 1. 电脑浏览器访问
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
### 登录页
|
|
16
|
+

|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
### 文件夹列表页
|
|
19
|
+

|
|
20
|
+

|
|
18
21
|
|
|
22
|
+
### 看本模式
|
|
23
|
+

|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
### 文件夹&看本 二合一模式
|
|
26
|
+

|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
## 2. 手机浏览器访问
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
### 登录页
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
### 文件夹列表页
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
### 看本模式
|
|
37
|
+

|
|
25
38
|
|
|
26
39
|
|
|
27
40
|
# 使用方式
|
|
@@ -34,7 +47,6 @@ pip install plugin_jm_server
|
|
|
34
47
|
```
|
|
35
48
|
|
|
36
49
|
|
|
37
|
-
|
|
38
50
|
## 2. 运行代码
|
|
39
51
|
|
|
40
52
|
* **HTTP版**
|
|
@@ -99,31 +111,41 @@ op.wait_all_plugins_finish()
|
|
|
99
111
|
```
|
|
100
112
|
|
|
101
113
|
|
|
102
|
-
|
|
114
|
+
## 前端页面与功能介绍
|
|
115
|
+
|
|
116
|
+
本项目提供了一套完整的 Web 前端界面,用于管理和浏览本地图片资源。主要包含以下三个核心页面及其功能:
|
|
117
|
+
|
|
118
|
+
### 1. 登录页
|
|
119
|
+
为了保护个人隐私,系统提供了简单的访问控制。
|
|
120
|
+
* **密码验证**:启动时可配置密码,访问时需校验通过。
|
|
121
|
+
* **设备自适应**:根据访问设备(手机/电脑)自动适配最佳的登录布局。
|
|
122
|
+
|
|
123
|
+
### 2. 文件夹浏览页(主页)
|
|
124
|
+
这是资源管理的核心入口,支持高效的文件查找与导航。目前最新版本采用了 SPA(单页应用)架构进行全面增强:
|
|
125
|
+
* **智能路径导航**:
|
|
126
|
+
* **路径补全**:输入路径时自动联想下级文件夹,支持键盘上下键选择及回车跳转。
|
|
127
|
+
* **层级跳转**:输入框支持“..”快速返回上一级,并提供“确认”按钮进行精准跳转。
|
|
128
|
+
* **可视化展示**:
|
|
129
|
+
* **文件夹预览**:鼠标悬停在文件夹上时,会自动展示该文件夹内的首张图片作为封面预览。
|
|
130
|
+
* **类型区分**:通过文件夹角标(图标)清晰区分普通文件夹与特殊资源文件夹。
|
|
131
|
+
* **辅助功能**:
|
|
132
|
+
* **书签管理**:支持将常看目录加入左侧书签栏,方便下次快速访问。
|
|
133
|
+
* **本地交互**:支持通过网页菜单直接打开服务器端对应的本地文件夹窗口(Explorer)。
|
|
134
|
+
|
|
135
|
+
### 3. 图片阅读页(看本模式)
|
|
136
|
+
专为漫画阅读优化的沉浸式浏览页面。
|
|
137
|
+
* **加载优化**:采用图片懒加载机制,流畅浏览含有数百张图片的大型章节,节省系统资源。
|
|
138
|
+
* **多端适配**:
|
|
139
|
+
* **PC端**:适合大屏浏览,支持浮动工具栏进行页面跳转、全屏切换等。
|
|
140
|
+
* **移动端**:适配触摸操作,提供更好的手机阅读体验。
|
|
141
|
+
* **阅读辅助**:
|
|
142
|
+
* **浮动菜单**:提供“回到顶部”、“加载全部图片”及“在资源管理器打开”等便捷操作。
|
|
143
|
+
* **键盘支持**:支持常用快捷键进行页面滚动和翻页。
|
|
103
144
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
### 登录页
|
|
107
|
-

|
|
108
|
-
|
|
109
|
-
### 文件夹列表页
|
|
110
|
-

|
|
111
|
-

|
|
112
|
-
|
|
113
|
-
### 看本模式
|
|
114
|
-

|
|
115
|
-
|
|
116
|
-
### 文件夹&看本 二合一模式
|
|
117
|
-

|
|
118
|
-
|
|
119
|
-
## 2. 手机浏览器访问
|
|
120
|
-
|
|
121
|
-
### 登录页
|
|
122
|
-

|
|
145
|
+
# 想法起源
|
|
123
146
|
|
|
124
|
-
|
|
125
|
-

|
|
147
|
+
想法起源:https://github.com/hect0x7/JMComic-Crawler-Python/issues/192
|
|
126
148
|
|
|
127
|
-
|
|
128
|
-

|
|
149
|
+
基于原项目:https://github.com/AiCorein/Flask-Files-Server
|
|
129
150
|
|
|
151
|
+
为了方便修改,将原项目中的文件复制到本项目中,然后进行修改
|
|
@@ -187,6 +187,19 @@ class JmServer:
|
|
|
187
187
|
'images': images
|
|
188
188
|
})
|
|
189
189
|
|
|
190
|
+
def api_open_file(self):
|
|
191
|
+
"""
|
|
192
|
+
[New] API: Open file/folder in Explorer
|
|
193
|
+
"""
|
|
194
|
+
if not self.verify():
|
|
195
|
+
return abort(403)
|
|
196
|
+
|
|
197
|
+
path = request.args.get('path', None)
|
|
198
|
+
if not path:
|
|
199
|
+
return jsonify({'error': 'Path required'}), 400
|
|
200
|
+
|
|
201
|
+
return self.open_directory(path) or jsonify({'status': 'ok'})
|
|
202
|
+
|
|
190
203
|
def jm_view(self):
|
|
191
204
|
"""
|
|
192
205
|
以禁漫章节的模式观看指定文件夹下的图片
|
|
@@ -409,6 +422,7 @@ class JmServer:
|
|
|
409
422
|
self.app.add_url_rule("/spa", 'spa_view', self.spa_view, methods=['GET'])
|
|
410
423
|
self.app.add_url_rule("/api/list_files", 'api_list_files', self.api_list_files, methods=['GET'])
|
|
411
424
|
self.app.add_url_rule("/api/album_images", 'api_album_images', self.api_album_images, methods=['GET'])
|
|
425
|
+
self.app.add_url_rule("/api/open_file", 'api_open_file', self.api_open_file, methods=['GET'])
|
|
412
426
|
|
|
413
427
|
def run(self, **kwargs):
|
|
414
428
|
kwargs.setdefault('port', self.DEFAULT_PORT)
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/index_spa.css
RENAMED
|
@@ -70,23 +70,80 @@ a {
|
|
|
70
70
|
.middle-controls {
|
|
71
71
|
flex: 1;
|
|
72
72
|
margin: 0 1rem;
|
|
73
|
-
overflow: hidden;
|
|
73
|
+
/* overflow: hidden; Removed to allow dropdown */
|
|
74
74
|
display: flex;
|
|
75
75
|
align-items: center;
|
|
76
76
|
gap: 10px;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
.path-input-wrapper {
|
|
80
|
+
flex: 1;
|
|
81
|
+
position: relative;
|
|
82
|
+
display: flex;
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
.path-breadcumb {
|
|
80
86
|
background: var(--bg-color);
|
|
81
87
|
padding: 0.25rem 0.75rem;
|
|
82
88
|
border-radius: 4px;
|
|
83
|
-
white-space: nowrap;
|
|
84
|
-
overflow: hidden;
|
|
85
|
-
text-overflow: ellipsis;
|
|
86
89
|
font-size: 0.9rem;
|
|
87
|
-
color: var(--text-
|
|
90
|
+
color: var(--text-main);
|
|
88
91
|
border: 1px solid var(--border-color);
|
|
89
|
-
|
|
92
|
+
width: 100%;
|
|
93
|
+
outline: none;
|
|
94
|
+
transition: box-shadow 0.2s, border-color 0.2s;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.autocomplete-dropdown {
|
|
98
|
+
position: absolute;
|
|
99
|
+
top: 100%;
|
|
100
|
+
left: 0;
|
|
101
|
+
right: 0;
|
|
102
|
+
background: white;
|
|
103
|
+
border: 1px solid var(--border-color);
|
|
104
|
+
border-top: none;
|
|
105
|
+
border-radius: 0 0 4px 4px;
|
|
106
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
107
|
+
max-height: 300px;
|
|
108
|
+
overflow-y: auto;
|
|
109
|
+
z-index: 2000;
|
|
110
|
+
margin-top: 2px;
|
|
111
|
+
padding: 0;
|
|
112
|
+
list-style: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.autocomplete-item {
|
|
116
|
+
padding: 0.5rem 0.75rem;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
font-size: 0.9rem;
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 0.5rem;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.autocomplete-item:hover,
|
|
125
|
+
.autocomplete-item.active {
|
|
126
|
+
background-color: var(--hover-bg);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.autocomplete-item i {
|
|
130
|
+
color: #f59e0b;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.confirm-item {
|
|
134
|
+
border-bottom: 1px solid #f3f4f6;
|
|
135
|
+
color: #059669;
|
|
136
|
+
font-weight: 500;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.confirm-item:hover {
|
|
140
|
+
background-color: #ecfdf5 !important;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.path-breadcumb:focus {
|
|
144
|
+
background: var(--white);
|
|
145
|
+
border-color: var(--primary-color);
|
|
146
|
+
box-shadow: 0 0 0 2px var(--active-bg);
|
|
90
147
|
}
|
|
91
148
|
|
|
92
149
|
.btn {
|
|
@@ -232,6 +289,8 @@ a {
|
|
|
232
289
|
background: #f3f4f6;
|
|
233
290
|
border-radius: 4px;
|
|
234
291
|
overflow: hidden;
|
|
292
|
+
position: relative;
|
|
293
|
+
/* Ensure relative positioning for absolute child */
|
|
235
294
|
}
|
|
236
295
|
|
|
237
296
|
.file-thumb img {
|
|
@@ -240,6 +299,28 @@ a {
|
|
|
240
299
|
object-fit: cover;
|
|
241
300
|
}
|
|
242
301
|
|
|
302
|
+
/* Folder Indicator Badge */
|
|
303
|
+
.file-item[data-type="dir"] .file-thumb::after,
|
|
304
|
+
.file-item[data-type="jm"] .file-thumb::after {
|
|
305
|
+
content: '\f07b';
|
|
306
|
+
/* FontAwesome folder icon */
|
|
307
|
+
font-family: "Font Awesome 5 Free";
|
|
308
|
+
font-weight: 900;
|
|
309
|
+
position: absolute;
|
|
310
|
+
bottom: 0;
|
|
311
|
+
right: 0;
|
|
312
|
+
font-size: 14px;
|
|
313
|
+
color: #f59e0b;
|
|
314
|
+
background-color: white;
|
|
315
|
+
padding: 2px 4px;
|
|
316
|
+
border-top-left-radius: 4px;
|
|
317
|
+
box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.1);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.file-item[data-type="jm"] .file-thumb::after {
|
|
321
|
+
color: #ef4444;
|
|
322
|
+
}
|
|
323
|
+
|
|
243
324
|
.file-thumb i {
|
|
244
325
|
font-size: 1.2rem;
|
|
245
326
|
color: #9ca3af;
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/index_spa.js
RENAMED
|
@@ -30,6 +30,262 @@ $(document).ready(function () {
|
|
|
30
30
|
$('#btn-home').click(() => loadDirectory(DEFAULT_PATH));
|
|
31
31
|
$('#btn-view-album').click(() => loadAlbum(currentPath));
|
|
32
32
|
|
|
33
|
+
// Path Input Navigation & Autocomplete
|
|
34
|
+
const $pathInput = $('#currentPathDisplay');
|
|
35
|
+
const $suggestions = $('#pathSuggestions');
|
|
36
|
+
let suggestionDebounce;
|
|
37
|
+
let cachedDir = null;
|
|
38
|
+
let cachedFiles = [];
|
|
39
|
+
|
|
40
|
+
$pathInput.on('keydown', function (e) {
|
|
41
|
+
const $items = $suggestions.find('li');
|
|
42
|
+
let activeIdx = $items.index($items.filter('.active'));
|
|
43
|
+
|
|
44
|
+
if (e.key === 'ArrowDown') {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
if ($items.length > 0) {
|
|
47
|
+
if (activeIdx < $items.length - 1) activeIdx++;
|
|
48
|
+
else activeIdx = 0; // Cycle to top
|
|
49
|
+
|
|
50
|
+
$items.removeClass('active');
|
|
51
|
+
const $active = $items.eq(activeIdx).addClass('active');
|
|
52
|
+
// Scroll into view if needed
|
|
53
|
+
if ($active.length) {
|
|
54
|
+
$active[0].scrollIntoView({ block: 'nearest' });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} else if (e.key === 'ArrowUp') {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
if ($items.length > 0) {
|
|
60
|
+
if (activeIdx > 0) activeIdx--;
|
|
61
|
+
else activeIdx = $items.length - 1; // Cycle to bottom
|
|
62
|
+
|
|
63
|
+
$items.removeClass('active');
|
|
64
|
+
const $active = $items.eq(activeIdx).addClass('active');
|
|
65
|
+
if ($active.length) {
|
|
66
|
+
$active[0].scrollIntoView({ block: 'nearest' });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else if (e.key === 'Enter') {
|
|
70
|
+
// Check if an item is active
|
|
71
|
+
if (activeIdx !== -1) {
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
// Trigger click on the ACTIVE item
|
|
74
|
+
$items.eq(activeIdx).trigger('click');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const path = $(this).val();
|
|
79
|
+
if (path) {
|
|
80
|
+
$suggestions.hide();
|
|
81
|
+
$(this).blur();
|
|
82
|
+
loadDirectory(path);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
$pathInput.on('input focus', function () {
|
|
88
|
+
const val = $(this).val();
|
|
89
|
+
clearTimeout(suggestionDebounce);
|
|
90
|
+
|
|
91
|
+
suggestionDebounce = setTimeout(() => {
|
|
92
|
+
handleAutocomplete(val);
|
|
93
|
+
}, 300);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Hide when clicking outside
|
|
97
|
+
$(document).on('click', function (e) {
|
|
98
|
+
if (!$.contains($('.path-input-wrapper')[0], e.target)) {
|
|
99
|
+
$suggestions.hide();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
function handleAutocomplete(inputVal) {
|
|
104
|
+
if (!inputVal) {
|
|
105
|
+
$suggestions.hide();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Determine parent dir and query
|
|
110
|
+
// Handle Windows and Unix separators
|
|
111
|
+
const sep = inputVal.includes('/') ? '/' : '\\';
|
|
112
|
+
let parentDir, query;
|
|
113
|
+
|
|
114
|
+
// E.g. "D:\Downloads\Ani"
|
|
115
|
+
const lastSepIndex = Math.max(inputVal.lastIndexOf('/'), inputVal.lastIndexOf('\\'));
|
|
116
|
+
|
|
117
|
+
if (lastSepIndex === -1) {
|
|
118
|
+
// Treat specific drive letters like 'C:'
|
|
119
|
+
if (inputVal.endsWith(':')) {
|
|
120
|
+
parentDir = inputVal + '\\';
|
|
121
|
+
query = '';
|
|
122
|
+
} else {
|
|
123
|
+
// No separator? Maybe root or just typing name?
|
|
124
|
+
// Assume relative to nothing? Hard to say.
|
|
125
|
+
// Let's assume we need to list drives or fail.
|
|
126
|
+
// For safety, if length > 1 and looks like drive:
|
|
127
|
+
if (/^[a-zA-Z]:$/.test(inputVal)) {
|
|
128
|
+
parentDir = inputVal + '\\';
|
|
129
|
+
query = '';
|
|
130
|
+
} else {
|
|
131
|
+
$suggestions.hide();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
parentDir = inputVal.substring(0, lastSepIndex);
|
|
137
|
+
// Handle root case "D:\" -> parent is "D:" which is weird in some APIs,
|
|
138
|
+
// but usually "D:\" is better.
|
|
139
|
+
if (parentDir.endsWith(':')) parentDir += sep;
|
|
140
|
+
|
|
141
|
+
// If input is exactly "D:\" then query is empty
|
|
142
|
+
if (lastSepIndex === inputVal.length - 1) {
|
|
143
|
+
query = '';
|
|
144
|
+
// Fix parentDir to include the slash if it was stripped?
|
|
145
|
+
// Actually substring(0, index) excludes slash.
|
|
146
|
+
// So for "D:\" -> parent "D:", query ""
|
|
147
|
+
parentDir = inputVal.substring(0, lastSepIndex + 1);
|
|
148
|
+
} else {
|
|
149
|
+
query = inputVal.substring(lastSepIndex + 1).toLowerCase();
|
|
150
|
+
parentDir = inputVal.substring(0, lastSepIndex + 1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Fetch if needed
|
|
155
|
+
if (cachedDir !== parentDir) {
|
|
156
|
+
$.ajax({
|
|
157
|
+
url: '/api/list_files',
|
|
158
|
+
data: { path: parentDir },
|
|
159
|
+
method: 'GET',
|
|
160
|
+
success: function (res) {
|
|
161
|
+
cachedDir = parentDir;
|
|
162
|
+
// Filter only dirs
|
|
163
|
+
cachedFiles = (res.files || []).filter(f => f.type === 'dir' || f.type === 'jm');
|
|
164
|
+
renderSuggestions(cachedFiles, query, parentDir);
|
|
165
|
+
},
|
|
166
|
+
error: function () {
|
|
167
|
+
// Fail silently or clear
|
|
168
|
+
cachedFiles = [];
|
|
169
|
+
cachedDir = null;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
} else {
|
|
173
|
+
renderSuggestions(cachedFiles, query, parentDir);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function renderSuggestions(files, query, parentPath) {
|
|
178
|
+
// Files are children of parentPath.
|
|
179
|
+
// If the user has typed a valid path that equals parentPath (so query is empty), we should offer a way to "Confirm/Go" to parentPath.
|
|
180
|
+
// OR if the user is typing, we show children.
|
|
181
|
+
|
|
182
|
+
const matches = files.filter(f => f.name.toLowerCase().startsWith(query));
|
|
183
|
+
|
|
184
|
+
$suggestions.empty();
|
|
185
|
+
|
|
186
|
+
// 1. Confirm Option (Only if we are likely at a valid path or user wants to submit current input)
|
|
187
|
+
// logic: if query is empty, it means input ends with slash (likely a dir).
|
|
188
|
+
// We can add a "Go to <parentPath>" item.
|
|
189
|
+
if (query === '' && parentPath) {
|
|
190
|
+
// Only show confirm if the path in input is NOT different from currentPath (meaning user hasn't moved yet)
|
|
191
|
+
const inputVal = $pathInput.val();
|
|
192
|
+
|
|
193
|
+
// Utility to decode HTML entities (e.g. for paths with special chars)
|
|
194
|
+
const decodeHtml = (html) => {
|
|
195
|
+
const txt = document.createElement("textarea");
|
|
196
|
+
txt.innerHTML = html;
|
|
197
|
+
return txt.value;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// Normalize slashes for comparison
|
|
201
|
+
const normInput = inputVal.replace(/[\\/]+$/, '').replace(/\\/g, '/');
|
|
202
|
+
// Decode currentPath
|
|
203
|
+
const decodedCurrent = decodeHtml(currentPath);
|
|
204
|
+
const normCurrent = decodedCurrent.replace(/[\\/]+$/, '').replace(/\\/g, '/');
|
|
205
|
+
|
|
206
|
+
// console.log(normInput, normCurrent);
|
|
207
|
+
|
|
208
|
+
if (normInput !== normCurrent) {
|
|
209
|
+
const $start = $(`
|
|
210
|
+
<li class="autocomplete-item confirm-item" data-path="${parentPath}">
|
|
211
|
+
<i class="fas fa-check-circle" style="color: #10b981;"></i>
|
|
212
|
+
<span>确认</span>
|
|
213
|
+
</li>
|
|
214
|
+
`);
|
|
215
|
+
$start.on('mousedown click', function (e) {
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
if ($pathInput) $pathInput.blur(); // Focus away
|
|
218
|
+
loadDirectory(parentPath);
|
|
219
|
+
$suggestions.hide();
|
|
220
|
+
});
|
|
221
|
+
$suggestions.append($start);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Always show ".." to go up, if we are not at root (logic could be refined but always showing is safe enough)
|
|
226
|
+
// Only show if query doesn't conflict with it significantly?
|
|
227
|
+
// Actually best to show it if matches is empty OR if query is empty or starts with '.'
|
|
228
|
+
// Let's just prepend it if parentPath has a parent.
|
|
229
|
+
|
|
230
|
+
let parentOfParent = null;
|
|
231
|
+
if (parentPath) {
|
|
232
|
+
const sep = parentPath.includes('/') ? '/' : '\\';
|
|
233
|
+
// parentPath usually ends with slash due to handleAutocomplete logic
|
|
234
|
+
let clean = parentPath;
|
|
235
|
+
if (clean.endsWith(sep)) clean = clean.slice(0, -1);
|
|
236
|
+
|
|
237
|
+
const lastSep = Math.max(clean.lastIndexOf('/'), clean.lastIndexOf('\\'));
|
|
238
|
+
if (lastSep > 0) {
|
|
239
|
+
parentOfParent = clean.substring(0, lastSep + 1);
|
|
240
|
+
} else if (clean.endsWith(':')) {
|
|
241
|
+
// Root drive, no parent usually
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (parentOfParent && (query === '' || '..'.startsWith(query))) {
|
|
246
|
+
const $li = $(`
|
|
247
|
+
<li class="autocomplete-item">
|
|
248
|
+
<i class="fas fa-level-up-alt" style="color: #6b7280;"></i>
|
|
249
|
+
<span>..</span>
|
|
250
|
+
</li>
|
|
251
|
+
`);
|
|
252
|
+
$li.click(function () {
|
|
253
|
+
$pathInput.val(parentOfParent);
|
|
254
|
+
$pathInput.focus();
|
|
255
|
+
$suggestions.hide();
|
|
256
|
+
handleAutocomplete(parentOfParent);
|
|
257
|
+
});
|
|
258
|
+
$suggestions.append($li);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (matches.length === 0 && $suggestions.children().length === 0) {
|
|
262
|
+
$suggestions.hide();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
matches.slice(0, 10).forEach(f => {
|
|
267
|
+
const $li = $(`
|
|
268
|
+
<li class="autocomplete-item">
|
|
269
|
+
<i class="fas fa-folder"></i>
|
|
270
|
+
<span>${f.name}</span>
|
|
271
|
+
</li>
|
|
272
|
+
`);
|
|
273
|
+
|
|
274
|
+
$li.click(function () {
|
|
275
|
+
let newVal = f.path;
|
|
276
|
+
|
|
277
|
+
// Direct navigation as requested
|
|
278
|
+
$pathInput.val(newVal);
|
|
279
|
+
if ($pathInput) $pathInput.blur(); // Focus away
|
|
280
|
+
$suggestions.hide();
|
|
281
|
+
loadDirectory(newVal);
|
|
282
|
+
});
|
|
283
|
+
$suggestions.append($li);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
$suggestions.show();
|
|
287
|
+
}
|
|
288
|
+
|
|
33
289
|
// Bookmark Events
|
|
34
290
|
$('#btn-add-bookmark').click(() => toggleCurrentBookmark());
|
|
35
291
|
$('#btn-show-bookmarks').click(() => showBookmarksDrawer());
|
|
@@ -395,6 +651,9 @@ $(document).ready(function () {
|
|
|
395
651
|
<li style="margin-top: 15px;">
|
|
396
652
|
<a href="javascript:void(0)" id="menuLoadAll"><i class="fas fa-download"></i><span>加载全部</span></a>
|
|
397
653
|
</li>
|
|
654
|
+
<li>
|
|
655
|
+
<a href="javascript:void(0)" id="menuOpenExplorer"><i class="fas fa-folder-open"></i><span>打开文件夹</span></a>
|
|
656
|
+
</li>
|
|
398
657
|
<li>
|
|
399
658
|
<a href="javascript:void(0)" id="menuTop"><i class="far fa-caret-square-up"></i><span>回到顶端</span></a>
|
|
400
659
|
</li>
|
|
@@ -423,6 +682,21 @@ $(document).ready(function () {
|
|
|
423
682
|
// Menu Handlers
|
|
424
683
|
$('#menuToggle').click(() => $menu.hide());
|
|
425
684
|
|
|
685
|
+
$('#menuOpenExplorer').click(() => {
|
|
686
|
+
$.ajax({
|
|
687
|
+
url: '/api/open_file',
|
|
688
|
+
data: { path: currentPath },
|
|
689
|
+
method: 'GET',
|
|
690
|
+
success: function (res) {
|
|
691
|
+
// Feedback?
|
|
692
|
+
// console.log('Opened');
|
|
693
|
+
},
|
|
694
|
+
error: function (err) {
|
|
695
|
+
console.error('Failed to open explorer', err);
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
|
|
426
700
|
$('#menuLoadAll').click(() => {
|
|
427
701
|
// Load all remaining images
|
|
428
702
|
$('#imageContainer img').each(function () {
|
|
@@ -484,7 +758,14 @@ $(document).ready(function () {
|
|
|
484
758
|
|
|
485
759
|
/* Utils */
|
|
486
760
|
function updateBreadcrumb(path) {
|
|
487
|
-
|
|
761
|
+
// Decode entities just in case backend returned them encoded
|
|
762
|
+
const decodeHtml = (html) => {
|
|
763
|
+
const txt = document.createElement("textarea");
|
|
764
|
+
txt.innerHTML = html;
|
|
765
|
+
return txt.value;
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
$('#currentPathDisplay').val(decodeHtml(path));
|
|
488
769
|
}
|
|
489
770
|
|
|
490
771
|
function resetViewer() {
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/index_spa.html
RENAMED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
<!-- Dependencies -->
|
|
13
13
|
<script src="../static/js/jquery-3.7.1.min.js"></script>
|
|
14
14
|
<!-- Lazy load plugin if needed or handle manually -->
|
|
15
|
-
{#
|
|
15
|
+
{#
|
|
16
|
+
<script src="../static/js/common.js"></script> <!-- Reuse common utils if any -->#}
|
|
16
17
|
</head>
|
|
17
18
|
|
|
18
19
|
<body>
|
|
@@ -35,8 +36,10 @@
|
|
|
35
36
|
</div>
|
|
36
37
|
|
|
37
38
|
<div class="middle-controls">
|
|
38
|
-
<div class="path-
|
|
39
|
-
{{ data.currentPath }}
|
|
39
|
+
<div class="path-input-wrapper">
|
|
40
|
+
<input type="text" class="path-breadcumb" id="currentPathDisplay" value="{{ data.currentPath }}"
|
|
41
|
+
autocomplete="off">
|
|
42
|
+
<ul class="autocomplete-dropdown" id="pathSuggestions" style="display:none;"></ul>
|
|
40
43
|
</div>
|
|
41
44
|
<button class="action-icon" id="btn-add-bookmark" title="收藏当前目录">
|
|
42
45
|
<i class="far fa-star"></i>
|
|
@@ -48,7 +51,7 @@
|
|
|
48
51
|
<i class="fas fa-bookmark"></i> 收藏夹
|
|
49
52
|
</button>
|
|
50
53
|
<button class="btn btn-primary" id="btn-view-album" title="以本子模式浏览当前目录">
|
|
51
|
-
|
|
54
|
+
<i class="fas fa-images"></i> 看图
|
|
52
55
|
</button>
|
|
53
56
|
<a href="/" class="btn btn-outline" title="返回旧版">
|
|
54
57
|
<i class="fas fa-undo"></i>
|
|
@@ -109,8 +112,8 @@
|
|
|
109
112
|
|
|
110
113
|
<!-- Init Data -->
|
|
111
114
|
<script>
|
|
112
|
-
const INITIAL_PATH = "{{ data.currentPath|replace('\\', '\\\\') }}";
|
|
113
|
-
const DEFAULT_PATH = "{{ data.defaultPath|replace('\\', '\\\\') }}";
|
|
115
|
+
const INITIAL_PATH = "{{ data.currentPath|replace('\\', '\\\\')|safe }}";
|
|
116
|
+
const DEFAULT_PATH = "{{ data.defaultPath|replace('\\', '\\\\')|safe }}";
|
|
114
117
|
</script>
|
|
115
118
|
<script src="../static/js/index_spa.js?t={{ randomArg }}"></script>
|
|
116
119
|
</body>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plugin_jm_server
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: plugin_jm_server, a plugin for jmcomic that can be used to view comics in a web browser.
|
|
5
5
|
Home-page: https://github.com/hect0x7/plugin-jm-server
|
|
6
6
|
Author: hect0x7
|
|
@@ -44,20 +44,33 @@ Dynamic: summary
|
|
|
44
44
|
|
|
45
45
|
* 双页阅读插件:https://sleazyfork.org/zh-CN/scripts/374903-comicread
|
|
46
46
|
|
|
47
|
-
#
|
|
47
|
+
# 效果图(文件浏览、整章看图)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
## 1. 电脑浏览器访问
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
### 登录页
|
|
52
|
+

|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
### 文件夹列表页
|
|
55
|
+

|
|
56
|
+

|
|
54
57
|
|
|
58
|
+
### 看本模式
|
|
59
|
+

|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
### 文件夹&看本 二合一模式
|
|
62
|
+

|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
## 2. 手机浏览器访问
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
### 登录页
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
### 文件夹列表页
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
### 看本模式
|
|
73
|
+

|
|
61
74
|
|
|
62
75
|
|
|
63
76
|
# 使用方式
|
|
@@ -70,7 +83,6 @@ pip install plugin_jm_server
|
|
|
70
83
|
```
|
|
71
84
|
|
|
72
85
|
|
|
73
|
-
|
|
74
86
|
## 2. 运行代码
|
|
75
87
|
|
|
76
88
|
* **HTTP版**
|
|
@@ -135,31 +147,41 @@ op.wait_all_plugins_finish()
|
|
|
135
147
|
```
|
|
136
148
|
|
|
137
149
|
|
|
138
|
-
|
|
150
|
+
## 前端页面与功能介绍
|
|
151
|
+
|
|
152
|
+
本项目提供了一套完整的 Web 前端界面,用于管理和浏览本地图片资源。主要包含以下三个核心页面及其功能:
|
|
153
|
+
|
|
154
|
+
### 1. 登录页
|
|
155
|
+
为了保护个人隐私,系统提供了简单的访问控制。
|
|
156
|
+
* **密码验证**:启动时可配置密码,访问时需校验通过。
|
|
157
|
+
* **设备自适应**:根据访问设备(手机/电脑)自动适配最佳的登录布局。
|
|
158
|
+
|
|
159
|
+
### 2. 文件夹浏览页(主页)
|
|
160
|
+
这是资源管理的核心入口,支持高效的文件查找与导航。目前最新版本采用了 SPA(单页应用)架构进行全面增强:
|
|
161
|
+
* **智能路径导航**:
|
|
162
|
+
* **路径补全**:输入路径时自动联想下级文件夹,支持键盘上下键选择及回车跳转。
|
|
163
|
+
* **层级跳转**:输入框支持“..”快速返回上一级,并提供“确认”按钮进行精准跳转。
|
|
164
|
+
* **可视化展示**:
|
|
165
|
+
* **文件夹预览**:鼠标悬停在文件夹上时,会自动展示该文件夹内的首张图片作为封面预览。
|
|
166
|
+
* **类型区分**:通过文件夹角标(图标)清晰区分普通文件夹与特殊资源文件夹。
|
|
167
|
+
* **辅助功能**:
|
|
168
|
+
* **书签管理**:支持将常看目录加入左侧书签栏,方便下次快速访问。
|
|
169
|
+
* **本地交互**:支持通过网页菜单直接打开服务器端对应的本地文件夹窗口(Explorer)。
|
|
170
|
+
|
|
171
|
+
### 3. 图片阅读页(看本模式)
|
|
172
|
+
专为漫画阅读优化的沉浸式浏览页面。
|
|
173
|
+
* **加载优化**:采用图片懒加载机制,流畅浏览含有数百张图片的大型章节,节省系统资源。
|
|
174
|
+
* **多端适配**:
|
|
175
|
+
* **PC端**:适合大屏浏览,支持浮动工具栏进行页面跳转、全屏切换等。
|
|
176
|
+
* **移动端**:适配触摸操作,提供更好的手机阅读体验。
|
|
177
|
+
* **阅读辅助**:
|
|
178
|
+
* **浮动菜单**:提供“回到顶部”、“加载全部图片”及“在资源管理器打开”等便捷操作。
|
|
179
|
+
* **键盘支持**:支持常用快捷键进行页面滚动和翻页。
|
|
139
180
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
### 登录页
|
|
143
|
-

|
|
144
|
-
|
|
145
|
-
### 文件夹列表页
|
|
146
|
-

|
|
147
|
-

|
|
148
|
-
|
|
149
|
-
### 看本模式
|
|
150
|
-

|
|
151
|
-
|
|
152
|
-
### 文件夹&看本 二合一模式
|
|
153
|
-

|
|
154
|
-
|
|
155
|
-
## 2. 手机浏览器访问
|
|
156
|
-
|
|
157
|
-
### 登录页
|
|
158
|
-

|
|
181
|
+
# 想法起源
|
|
159
182
|
|
|
160
|
-
|
|
161
|
-

|
|
183
|
+
想法起源:https://github.com/hect0x7/JMComic-Crawler-Python/issues/192
|
|
162
184
|
|
|
163
|
-
|
|
164
|
-

|
|
185
|
+
基于原项目:https://github.com/AiCorein/Flask-Files-Server
|
|
165
186
|
|
|
187
|
+
为了方便修改,将原项目中的文件复制到本项目中,然后进行修改
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/all.min.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/bootstrap.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/download_error.css
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_index.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_login.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/m_upload.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/h5/normalize.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/style_photo.css
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/css/upload.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/h5/m_index.js
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/h5/m_upload.js
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery-3.7.1.min.js
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery.album-0.2.js
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/static/js/jquery.photo-0.3.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/download_error.html
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/jm_view.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_index.html
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_jm_view.html
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_login.html
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/m_upload.html
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server/templates/upload.html
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/requires.txt
RENAMED
|
File without changes
|
{plugin_jm_server-0.2.0 → plugin_jm_server-0.2.1}/src/plugin_jm_server.egg-info/top_level.txt
RENAMED
|
File without changes
|