@ -0,0 +1,32 @@ |
|||||||
|
#更新fork |
||||||
|
name: update fork |
||||||
|
|
||||||
|
on: |
||||||
|
schedule: |
||||||
|
- cron: '0 16 * * *' #设置定时任务 |
||||||
|
|
||||||
|
jobs: |
||||||
|
build: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
if: ${{ github.event.repository.owner.id == github.event.sender.id && github.actor != 'gedoor' }} |
||||||
|
steps: |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Install git |
||||||
|
run: | |
||||||
|
sudo apt-get update |
||||||
|
sudo apt-get -y install git |
||||||
|
- name: Set env |
||||||
|
run: | |
||||||
|
git config --global user.email "github-actions@github.com" |
||||||
|
git config --global user.name "github-actions" |
||||||
|
- name: Update fork |
||||||
|
run: | |
||||||
|
git remote add upstream https://github.com/gedoor/legado.git |
||||||
|
git remote -v |
||||||
|
git fetch upstream |
||||||
|
git checkout master |
||||||
|
git merge upstream/master |
||||||
|
git push origin master |
@ -0,0 +1,57 @@ |
|||||||
|
name: Android CI |
||||||
|
|
||||||
|
on: |
||||||
|
release: |
||||||
|
types: [published] |
||||||
|
push: |
||||||
|
branches: |
||||||
|
- master |
||||||
|
# tags: |
||||||
|
# - '3.*' |
||||||
|
# pull_request: |
||||||
|
# branches: |
||||||
|
# - master |
||||||
|
# watch: |
||||||
|
# types: [started] |
||||||
|
# schedule: |
||||||
|
# - cron: '0 4 * * *' |
||||||
|
|
||||||
|
jobs: |
||||||
|
build: |
||||||
|
|
||||||
|
runs-on: ubuntu-latest |
||||||
|
|
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v2 |
||||||
|
- name: set up JDK 1.8 |
||||||
|
uses: actions/setup-java@v1 |
||||||
|
with: |
||||||
|
java-version: 1.8 |
||||||
|
- name: clear 18PlusList.txt |
||||||
|
run: | |
||||||
|
echo "清空18PlusList.txt" |
||||||
|
echo "">$GITHUB_WORKSPACE/app/src/main/assets/18PlusList.txt |
||||||
|
- name: release apk sign |
||||||
|
run: | |
||||||
|
echo "给apk增加签名" |
||||||
|
cp $GITHUB_WORKSPACE/.github/workflows/legado.jks $GITHUB_WORKSPACE/app/legado.jks |
||||||
|
sed '$a\RELEASE_STORE_FILE=./legado.jks' $GITHUB_WORKSPACE/gradle.properties -i |
||||||
|
sed '$a\RELEASE_KEY_ALIAS=legado' $GITHUB_WORKSPACE/gradle.properties -i |
||||||
|
sed '$a\RELEASE_STORE_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i |
||||||
|
sed '$a\RELEASE_KEY_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i |
||||||
|
- name: apk live together |
||||||
|
run: | |
||||||
|
echo "设置apk共存" |
||||||
|
sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i |
||||||
|
sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i |
||||||
|
- name: build with gradle |
||||||
|
run: | |
||||||
|
echo "开始进行release构建" |
||||||
|
chmod +x gradlew |
||||||
|
./gradlew assembleAppRelease |
||||||
|
- name : upload apk |
||||||
|
uses: actions/upload-artifact@master |
||||||
|
if: always() |
||||||
|
with: |
||||||
|
name: legado apk |
||||||
|
path: ${{ github.workspace }}/app/build/outputs/apk/app/release |
@ -0,0 +1,169 @@ |
|||||||
|
# 阅读API |
||||||
|
## 对于Web的配置 |
||||||
|
您需要先在设置中启用"Web 服务"。 |
||||||
|
## 使用 |
||||||
|
### Web |
||||||
|
以下说明假设您的操作在本机进行,且开放端口为1234。 |
||||||
|
如果您要从远程计算机访问[阅读](),请将`127.0.0.1`替换成手机IP。 |
||||||
|
#### 插入单个书源 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/saveSource |
||||||
|
Method = POST |
||||||
|
``` |
||||||
|
|
||||||
|
请求BODY内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt) |
||||||
|
|
||||||
|
#### 插入多个书源 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/saveSources |
||||||
|
Method = POST |
||||||
|
``` |
||||||
|
|
||||||
|
请求BODY内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。 |
||||||
|
|
||||||
|
#### 获取书源 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/getSource?url=xxx |
||||||
|
Method = GET |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定URL对应的书源信息。 |
||||||
|
|
||||||
|
#### 获取所有书源 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/getSources |
||||||
|
Method = GET |
||||||
|
``` |
||||||
|
|
||||||
|
获取APP内的所有书源。 |
||||||
|
|
||||||
|
#### 删除多个书源 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/deleteSources |
||||||
|
Method = POST |
||||||
|
``` |
||||||
|
|
||||||
|
请求BODY内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。 |
||||||
|
|
||||||
|
#### 插入书籍 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/saveBook |
||||||
|
Method = POST |
||||||
|
``` |
||||||
|
|
||||||
|
请求BODY内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/Book.kt)。 |
||||||
|
|
||||||
|
#### 获取所有书籍 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/getBookshelf |
||||||
|
Method = GET |
||||||
|
``` |
||||||
|
|
||||||
|
获取APP内的所有书籍。 |
||||||
|
|
||||||
|
#### 获取书籍章节列表 |
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/getChapterList?url=xxx |
||||||
|
Method = GET |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定图书的章节列表。 |
||||||
|
|
||||||
|
#### 获取书籍内容 |
||||||
|
|
||||||
|
``` |
||||||
|
URL = http://127.0.0.1:1234/getBookContent?url=xxx&index=1 |
||||||
|
Method = GET |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定图书的第`index`章节的文本内容。 |
||||||
|
|
||||||
|
### Content Provider |
||||||
|
* 需声明`io.legado.READ_WRITE`权限 |
||||||
|
* `providerHost`为`包名.readerProvider`, 如`io.legado.app.release.readerProvider`,不同包的地址不同,防止冲突安装失败 |
||||||
|
* 以下出现的`providerHost`请自行替换 |
||||||
|
#### 插入单个书源 |
||||||
|
``` |
||||||
|
URL = content://providerHost/source/insert |
||||||
|
Method = insert |
||||||
|
``` |
||||||
|
|
||||||
|
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt) |
||||||
|
|
||||||
|
#### 插入多个书源 |
||||||
|
``` |
||||||
|
URL = content://providerHost/sources/insert |
||||||
|
Method = insert |
||||||
|
``` |
||||||
|
|
||||||
|
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。 |
||||||
|
|
||||||
|
#### 获取书源 |
||||||
|
``` |
||||||
|
URL = content://providerHost/source/query?url=xxx |
||||||
|
Method = query |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定URL对应的书源信息。 |
||||||
|
用`Cursor.getString(0)`取出返回结果。 |
||||||
|
|
||||||
|
#### 获取所有书源 |
||||||
|
``` |
||||||
|
URL = content://providerHost/sources/query |
||||||
|
Method = query |
||||||
|
``` |
||||||
|
|
||||||
|
获取APP内的所有书源。 |
||||||
|
用`Cursor.getString(0)`取出返回结果。 |
||||||
|
|
||||||
|
#### 删除多个书源 |
||||||
|
``` |
||||||
|
URL = content://providerHost/sources/delete |
||||||
|
Method = delete |
||||||
|
``` |
||||||
|
|
||||||
|
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。 |
||||||
|
|
||||||
|
#### 插入书籍 |
||||||
|
``` |
||||||
|
URL = content://providerHost/book/insert |
||||||
|
Method = insert |
||||||
|
``` |
||||||
|
|
||||||
|
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串, |
||||||
|
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/Book.kt)。 |
||||||
|
|
||||||
|
#### 获取所有书籍 |
||||||
|
``` |
||||||
|
URL = content://providerHost/books/query |
||||||
|
Method = query |
||||||
|
``` |
||||||
|
|
||||||
|
获取APP内的所有书籍。 |
||||||
|
用`Cursor.getString(0)`取出返回结果。 |
||||||
|
|
||||||
|
#### 获取书籍章节列表 |
||||||
|
``` |
||||||
|
URL = content://providerHost/book/chapter/query?url=xxx |
||||||
|
Method = query |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定图书的章节列表。 |
||||||
|
用`Cursor.getString(0)`取出返回结果。 |
||||||
|
|
||||||
|
#### 获取书籍内容 |
||||||
|
|
||||||
|
``` |
||||||
|
URL = content://providerHost/book/content/query?url=xxx&index=1 |
||||||
|
Method = query |
||||||
|
``` |
||||||
|
|
||||||
|
获取指定图书的第`index`章节的文本内容。 |
||||||
|
用`Cursor.getString(0)`取出返回结果。 |
@ -0,0 +1,5 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
<string name="app_name">閲讀.D</string> |
||||||
|
<string name="receiving_shared_label">閲讀·D·搜索</string> |
||||||
|
</resources> |
@ -0,0 +1,5 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
<string name="app_name">閲讀.D</string> |
||||||
|
<string name="receiving_shared_label">閲讀·D·搜索</string> |
||||||
|
</resources> |
@ -0,0 +1,4 @@ |
|||||||
|
<resources> |
||||||
|
<string name="app_name">阅读·D</string> |
||||||
|
<string name="receiving_shared_label">阅读·D·搜索</string> |
||||||
|
</resources> |
@ -1,4 +1,4 @@ |
|||||||
<resources> |
<resources> |
||||||
<string name="app_name">悦读.debug</string> |
<string name="app_name">legado·D</string> |
||||||
<string name="receiving_shared_label">悦读.debug·搜索</string> |
<string name="receiving_shared_label">legado·D·search</string> |
||||||
</resources> |
</resources> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
|
||||||
|
<string name="app_name">阅读Pro</string> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
|
||||||
|
<string name="app_name">閱讀Pro</string> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
|
||||||
|
<string name="app_name">legadoPro</string> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,82 @@ |
|||||||
|
OGN5dS5jb20= |
||||||
|
c2cwMC54eXo= |
||||||
|
aXRyYWZmaWNuZXQuY29t |
||||||
|
eGlhb3FpYW5nNTIw |
||||||
|
MTIzeGlhb3FpYW5n |
||||||
|
eGlhb3FpYW5neHM= |
||||||
|
eGlhb3FpYW5nNTIw |
||||||
|
MzM1eHM= |
||||||
|
eGN4czk= |
||||||
|
eGN4czUyMA== |
||||||
|
c2h1YmFvYW4= |
||||||
|
c2h1YmFvd2FuZzEyMw== |
||||||
|
c2h1YmFvYW4= |
||||||
|
aGFpdGFuZzEyMw== |
||||||
|
eXV6aGFpd3VsYQ== |
||||||
|
cG8xOA== |
||||||
|
Ymwtbm92ZWw= |
||||||
|
NXRucw== |
||||||
|
c2hhb3NodWdl |
||||||
|
amluamlzaHV3dQ== |
||||||
|
NDJ3Zw== |
||||||
|
eWlxdXNodQ== |
||||||
|
c2h1YmFvd2FuZzEyMw== |
||||||
|
M2hlYmFv |
||||||
|
MzNoZWJhbw== |
||||||
|
bHVvcWl1enc= |
||||||
|
bXlzaHVnZQ== |
||||||
|
c3NzeHN3 |
||||||
|
eWl0ZQ== |
||||||
|
Y3Vpd2VpanV1 |
||||||
|
Y3Vpd2VpanV4cw== |
||||||
|
Y3Vpd2VpanV4 |
||||||
|
eGlhb3FpYW5nd3g= |
||||||
|
YXN6dw== |
||||||
|
YXN6dzY= |
||||||
|
c2FuaGFveHM= |
||||||
|
ODdzaHV3dQ== |
||||||
|
NDh3eA== |
||||||
|
bG9uZ3Rlbmcy |
||||||
|
NnF3eA== |
||||||
|
bG9uZ3Rlbmd4cw== |
||||||
|
aGF4ZHU= |
||||||
|
M3R3eA== |
||||||
|
aGF4d3g1 |
||||||
|
NjZsZXdlbg== |
||||||
|
eGJhbnpodQ== |
||||||
|
aGR5cA== |
||||||
|
ZHliejk= |
||||||
|
ZGl5aWJhbnpodTk= |
||||||
|
ZGl5aWJhbnpodQ== |
||||||
|
ZGl5aWJhbnpodTc= |
||||||
|
YnoyMjI= |
||||||
|
d29kZWFwaTAwMQ== |
||||||
|
dGFuZ3poZWthbg== |
||||||
|
YmF4aWFueHM= |
||||||
|
eGlhb3NodW9zaGVuemhhbg== |
||||||
|
ZGFtb2tl |
||||||
|
emh3ZW5wZw== |
||||||
|
eXV6aGFpZ2U= |
||||||
|
d21wOA== |
||||||
|
OXhpYW53ZW4= |
||||||
|
bmFucmVudmlw |
||||||
|
cmV5b28= |
||||||
|
eWZ4aWFvc2h1b2U= |
||||||
|
c2Fuaml1enc= |
||||||
|
N3Fpbmc3 |
||||||
|
cWR4aWFvc2h1bw== |
||||||
|
Y2hpbmVzZXpq |
||||||
|
MzlzaHViYW8= |
||||||
|
a3l4czU= |
||||||
|
NTZtcw== |
||||||
|
bml1c2hh |
||||||
|
bWt4czY= |
||||||
|
MjIyMjJ4cw== |
||||||
|
OTVkdXNodQ== |
||||||
|
YmFuemh1MjI= |
||||||
|
d3JsdHh0 |
||||||
|
dHVkb3V0eHQ= |
||||||
|
cm5neHM= |
||||||
|
OTl3ZW5rdQ== |
||||||
|
bGFvc2lqaXhz |
||||||
|
ZnVzaHV6aGFpMQ== |
@ -0,0 +1,62 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"id": 1598233029304, |
||||||
|
"name": "度小美", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029305, |
||||||
|
"name": "度小宇", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029306, |
||||||
|
"name": "度逍遥", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029307, |
||||||
|
"name": "度丫丫", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029308, |
||||||
|
"name": "度小娇", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029309, |
||||||
|
"name": "度米朵", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029310, |
||||||
|
"name": "度博文", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029311, |
||||||
|
"name": "度小童", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029312, |
||||||
|
"name": "度小萌", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029313, |
||||||
|
"name": "百度骚男", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029314, |
||||||
|
"name": "百度评书", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1598233029315, |
||||||
|
"name": "百度主持", |
||||||
|
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||||
|
} |
||||||
|
] |
@ -0,0 +1,26 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"themeName": "典雅蓝", |
||||||
|
"isNightTheme": false, |
||||||
|
"primaryColor": "#03A9F4", |
||||||
|
"accentColor": "#AD1457", |
||||||
|
"backgroundColor": "#F5F5F5", |
||||||
|
"bottomBackground": "#EEEEEE" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"themeName": "黑白", |
||||||
|
"isNightTheme": true, |
||||||
|
"primaryColor": "#303030", |
||||||
|
"accentColor": "#E0E0E0", |
||||||
|
"backgroundColor": "#424242", |
||||||
|
"bottomBackground": "#424242" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"themeName": "A屏黑", |
||||||
|
"isNightTheme": true, |
||||||
|
"primaryColor": "#000000", |
||||||
|
"accentColor": "#FFFFFF", |
||||||
|
"backgroundColor": "#000000", |
||||||
|
"bottomBackground": "#000000" |
||||||
|
} |
||||||
|
] |
After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 799 B After Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
@ -0,0 +1,3 @@ |
|||||||
|
<!DOCTYPE html><html lang=en style="padding: 0;height:100%"><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="favicon.ico" /><![endif]--><title>Legado Bookshelf</title><link href=css/about.dbe575e1.css rel=prefetch><link href=css/detail.9ba76c69.css rel=prefetch><link href=js/about.59a63964.js rel=prefetch><link href=js/about~detail.1caf6ef5.js rel=prefetch><link href=js/detail.11777eca.js rel=prefetch><link href=css/app.e4c919b7.css rel=preload as=style><link href=css/chunk-vendors.ad4ff18f.css rel=preload as=style><link href=js/app.d7843716.js rel=preload as=script><link href=js/chunk-vendors.8dd9045a.js rel=preload as=script><link href=css/chunk-vendors.ad4ff18f.css rel=stylesheet><link href=css/app.e4c919b7.css rel=stylesheet><link rel=icon type=image/png sizes=32x32 href=img/icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=img/icons/favicon-16x16.png><link rel=manifest href=manifest.json><meta name=theme-color content=#4DBA87><meta name=apple-mobile-web-app-capable content=no><meta name=apple-mobile-web-app-status-bar-style content=default><meta name=apple-mobile-web-app-title content=yd-web-tool><link rel=apple-touch-icon href=img/icons/apple-touch-icon-152x152.png><link rel=mask-icon href=img/icons/safari-pinned-tab.svg color=#4DBA87><meta name=msapplication-TileImage content=img/icons/msapplication-icon-144x144.png><meta name=msapplication-TileColor content=#000000></head><style>body::-webkit-scrollbar { |
||||||
|
display: none; |
||||||
|
}</style><body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.8dd9045a.js></script><script src=js/app.d7843716.js></script></body></html> |
@ -0,0 +1,74 @@ |
|||||||
|
self.__precacheManifest = (self.__precacheManifest || []).concat([ |
||||||
|
{ |
||||||
|
"revision": "a77097c019b699bc81ee", |
||||||
|
"url": "css/about.dbe575e1.css" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "4d729c4b428d537ebd8d", |
||||||
|
"url": "css/app.e4c919b7.css" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "3e91096748e0f4d6bb89", |
||||||
|
"url": "css/chunk-vendors.ad4ff18f.css" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "8f2124417070a994ebbd", |
||||||
|
"url": "css/detail.9ba76c69.css" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "535877f50039c0cb49a6196a5b7517cd", |
||||||
|
"url": "fonts/element-icons.535877f5.woff" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "732389ded34cb9c52dd88271f1345af9", |
||||||
|
"url": "fonts/element-icons.732389de.ttf" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "f9a3fb0e145017e166dd4d91d9280cc4", |
||||||
|
"url": "fonts/iconfont.f9a3fb0e.woff" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "f39ecc1a1d2a1eff3aca8aadd818bb61", |
||||||
|
"url": "fonts/popfont.f39ecc1a.ttf" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "6c094b6d4ae9404dbed273c41b06fae8", |
||||||
|
"url": "fonts/shelffont.6c094b6d.ttf" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "b5c48bc1e1fe73212a31be704875b71f", |
||||||
|
"url": "img/noCover.b5c48bc1.jpeg" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "ad9f43586bb9220e0df71ce8fad92d8b", |
||||||
|
"url": "index.html" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "a77097c019b699bc81ee", |
||||||
|
"url": "js/about.59a63964.js" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "2c81bd893f3a92f018d8", |
||||||
|
"url": "js/about~detail.1caf6ef5.js" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "4d729c4b428d537ebd8d", |
||||||
|
"url": "js/app.d7843716.js" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "3e91096748e0f4d6bb89", |
||||||
|
"url": "js/chunk-vendors.8dd9045a.js" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "8f2124417070a994ebbd", |
||||||
|
"url": "js/detail.11777eca.js" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "b46d04eb43bc31ca0f9f95121646440d", |
||||||
|
"url": "manifest.json" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", |
||||||
|
"url": "robots.txt" |
||||||
|
} |
||||||
|
]); |
@ -0,0 +1,2 @@ |
|||||||
|
User-agent: * |
||||||
|
Disallow: |
@ -0,0 +1,34 @@ |
|||||||
|
/** |
||||||
|
* Welcome to your Workbox-powered service worker! |
||||||
|
* |
||||||
|
* You'll need to register this file in your web app and you should |
||||||
|
* disable HTTP caching for this file too. |
||||||
|
* See https://goo.gl/nhQhGp
|
||||||
|
* |
||||||
|
* The rest of the code is auto-generated. Please don't update this file |
||||||
|
* directly; instead, make changes to your Workbox build configuration |
||||||
|
* and re-run your build process. |
||||||
|
* See https://goo.gl/2aRDsh
|
||||||
|
*/ |
||||||
|
|
||||||
|
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); |
||||||
|
|
||||||
|
importScripts( |
||||||
|
"precache-manifest.78eb8adcb8f052b2a72d462abe0dc498.js" |
||||||
|
); |
||||||
|
|
||||||
|
workbox.core.setCacheNameDetails({prefix: "yd-web-tool"}); |
||||||
|
|
||||||
|
self.addEventListener('message', (event) => { |
||||||
|
if (event.data && event.data.type === 'SKIP_WAITING') { |
||||||
|
self.skipWaiting(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
/** |
||||||
|
* The workboxSW.precacheAndRoute() method efficiently caches and responds to |
||||||
|
* requests for URLs in the manifest. |
||||||
|
* See https://goo.gl/S9QRab
|
||||||
|
*/ |
||||||
|
self.__precacheManifest = [].concat(self.__precacheManifest || []); |
||||||
|
workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); |
@ -0,0 +1,207 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2020 w568w |
||||||
|
*/ |
||||||
|
package io.legado.app.api |
||||||
|
|
||||||
|
import android.content.ContentProvider |
||||||
|
import android.content.ContentResolver |
||||||
|
import android.content.ContentValues |
||||||
|
import android.content.UriMatcher |
||||||
|
import android.database.CharArrayBuffer |
||||||
|
import android.database.ContentObserver |
||||||
|
import android.database.Cursor |
||||||
|
import android.database.DataSetObserver |
||||||
|
import android.net.Uri |
||||||
|
import android.os.Bundle |
||||||
|
import com.google.gson.Gson |
||||||
|
import io.legado.app.web.controller.BookshelfController |
||||||
|
import io.legado.app.web.controller.SourceController |
||||||
|
import io.legado.app.web.utils.ReturnData |
||||||
|
import java.util.* |
||||||
|
|
||||||
|
/** |
||||||
|
* Export book data to other app. |
||||||
|
*/ |
||||||
|
class ReaderProvider : ContentProvider() { |
||||||
|
private enum class RequestCode { |
||||||
|
SaveSource, SaveSources, SaveBook, DeleteSources, GetSource, GetSources, GetBookshelf, GetChapterList, GetBookContent |
||||||
|
} |
||||||
|
|
||||||
|
private val postBodyKey = "json" |
||||||
|
private val sMatcher by lazy { |
||||||
|
UriMatcher(UriMatcher.NO_MATCH).apply { |
||||||
|
"${context?.applicationInfo?.packageName}.readerProvider".also { authority -> |
||||||
|
addURI(authority, "source/insert", RequestCode.SaveSource.ordinal) |
||||||
|
addURI(authority, "sources/insert", RequestCode.SaveSources.ordinal) |
||||||
|
addURI(authority, "book/insert", RequestCode.SaveBook.ordinal) |
||||||
|
addURI(authority, "sources/delete", RequestCode.DeleteSources.ordinal) |
||||||
|
addURI(authority, "source/query", RequestCode.GetSource.ordinal) |
||||||
|
addURI(authority, "sources/query", RequestCode.GetSources.ordinal) |
||||||
|
addURI(authority, "books/query", RequestCode.GetBookshelf.ordinal) |
||||||
|
addURI(authority, "book/chapter/query", RequestCode.GetChapterList.ordinal) |
||||||
|
addURI(authority, "book/content/query", RequestCode.GetBookContent.ordinal) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCreate() = false |
||||||
|
|
||||||
|
override fun delete( |
||||||
|
uri: Uri, |
||||||
|
selection: String?, |
||||||
|
selectionArgs: Array<String>? |
||||||
|
): Int { |
||||||
|
if (sMatcher.match(uri) < 0) return -1 |
||||||
|
when (RequestCode.values()[sMatcher.match(uri)]) { |
||||||
|
RequestCode.DeleteSources -> SourceController.deleteSources(selection) |
||||||
|
else -> throw IllegalStateException( |
||||||
|
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name |
||||||
|
) |
||||||
|
} |
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
override fun getType(uri: Uri) = throw UnsupportedOperationException("Not yet implemented") |
||||||
|
|
||||||
|
override fun insert(uri: Uri, values: ContentValues?): Uri? { |
||||||
|
if (sMatcher.match(uri) < 0) return null |
||||||
|
when (RequestCode.values()[sMatcher.match(uri)]) { |
||||||
|
RequestCode.SaveSource -> values?.let { |
||||||
|
SourceController.saveSource(values.getAsString(postBodyKey)) |
||||||
|
} |
||||||
|
RequestCode.SaveBook -> values?.let { |
||||||
|
BookshelfController.saveBook(values.getAsString(postBodyKey)) |
||||||
|
} |
||||||
|
RequestCode.SaveSources -> values?.let { |
||||||
|
SourceController.saveSources(values.getAsString(postBodyKey)) |
||||||
|
} |
||||||
|
else -> throw IllegalStateException( |
||||||
|
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name |
||||||
|
) |
||||||
|
} |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
override fun query( |
||||||
|
uri: Uri, projection: Array<String>?, selection: String?, |
||||||
|
selectionArgs: Array<String>?, sortOrder: String? |
||||||
|
): Cursor? { |
||||||
|
val map: MutableMap<String, ArrayList<String>> = HashMap() |
||||||
|
uri.getQueryParameter("url")?.let { |
||||||
|
map["url"] = arrayListOf(it) |
||||||
|
} |
||||||
|
uri.getQueryParameter("index")?.let { |
||||||
|
map["index"] = arrayListOf(it) |
||||||
|
} |
||||||
|
return if (sMatcher.match(uri) < 0) null else when (RequestCode.values()[sMatcher.match(uri)]) { |
||||||
|
RequestCode.GetSource -> SimpleCursor(SourceController.getSource(map)) |
||||||
|
RequestCode.GetSources -> SimpleCursor(SourceController.sources) |
||||||
|
RequestCode.GetBookshelf -> SimpleCursor(BookshelfController.bookshelf) |
||||||
|
RequestCode.GetBookContent -> SimpleCursor(BookshelfController.getBookContent(map)) |
||||||
|
RequestCode.GetChapterList -> SimpleCursor(BookshelfController.getChapterList(map)) |
||||||
|
else -> throw IllegalStateException( |
||||||
|
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun update( |
||||||
|
uri: Uri, values: ContentValues?, selection: String?, |
||||||
|
selectionArgs: Array<String>? |
||||||
|
) = throw UnsupportedOperationException("Not yet implemented") |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Simple inner class to deliver json callback data. |
||||||
|
* |
||||||
|
* Only getString() makes sense. |
||||||
|
*/ |
||||||
|
private class SimpleCursor(data: ReturnData?) : Cursor { |
||||||
|
|
||||||
|
private val mData: String = Gson().toJson(data) |
||||||
|
|
||||||
|
override fun getCount() = 1 |
||||||
|
|
||||||
|
override fun getPosition() = 0 |
||||||
|
|
||||||
|
override fun move(i: Int) = true |
||||||
|
|
||||||
|
override fun moveToPosition(i: Int) = true |
||||||
|
|
||||||
|
override fun moveToFirst() = true |
||||||
|
|
||||||
|
override fun moveToLast() = true |
||||||
|
|
||||||
|
override fun moveToNext() = true |
||||||
|
|
||||||
|
override fun moveToPrevious() = true |
||||||
|
|
||||||
|
override fun isFirst() = true |
||||||
|
|
||||||
|
override fun isLast() = true |
||||||
|
|
||||||
|
override fun isBeforeFirst() = true |
||||||
|
|
||||||
|
override fun isAfterLast() = true |
||||||
|
|
||||||
|
override fun getColumnIndex(s: String) = 0 |
||||||
|
|
||||||
|
@Throws(IllegalArgumentException::class) |
||||||
|
override fun getColumnIndexOrThrow(s: String): Int { |
||||||
|
throw UnsupportedOperationException("Not yet implemented") |
||||||
|
} |
||||||
|
|
||||||
|
override fun getColumnName(i: Int) = null as String? |
||||||
|
|
||||||
|
override fun getColumnNames() = arrayOf<String>() |
||||||
|
|
||||||
|
override fun getColumnCount() = 0 |
||||||
|
|
||||||
|
override fun getBlob(i: Int) = ByteArray(0) |
||||||
|
|
||||||
|
override fun getString(i: Int) = mData |
||||||
|
|
||||||
|
override fun copyStringToBuffer( |
||||||
|
i: Int, |
||||||
|
charArrayBuffer: CharArrayBuffer |
||||||
|
) { |
||||||
|
} |
||||||
|
|
||||||
|
override fun getShort(i: Int) = 0.toShort() |
||||||
|
|
||||||
|
|
||||||
|
override fun getInt(i: Int) = 0 |
||||||
|
|
||||||
|
override fun getLong(i: Int) = 0L |
||||||
|
|
||||||
|
override fun getFloat(i: Int) = 0F |
||||||
|
|
||||||
|
override fun getDouble(i: Int) = 0.toDouble() |
||||||
|
|
||||||
|
override fun getType(i: Int) = 0 |
||||||
|
|
||||||
|
override fun isNull(i: Int) = false |
||||||
|
|
||||||
|
override fun deactivate() {} |
||||||
|
override fun requery() = false |
||||||
|
|
||||||
|
override fun close() {} |
||||||
|
override fun isClosed() = false |
||||||
|
|
||||||
|
override fun registerContentObserver(contentObserver: ContentObserver) {} |
||||||
|
override fun unregisterContentObserver(contentObserver: ContentObserver) {} |
||||||
|
override fun registerDataSetObserver(dataSetObserver: DataSetObserver) {} |
||||||
|
override fun unregisterDataSetObserver(dataSetObserver: DataSetObserver) {} |
||||||
|
override fun setNotificationUri(contentResolver: ContentResolver, uri: Uri) {} |
||||||
|
|
||||||
|
override fun getNotificationUri() = null as Uri? |
||||||
|
|
||||||
|
override fun getWantsAllOnMoveCalls() = false |
||||||
|
|
||||||
|
override fun setExtras(bundle: Bundle) {} |
||||||
|
override fun getExtras() = null as Bundle? |
||||||
|
|
||||||
|
override fun respond(bundle: Bundle) = null as Bundle? |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package io.legado.app.base |
||||||
|
|
||||||
|
import android.annotation.SuppressLint |
||||||
|
import androidx.fragment.app.DialogFragment |
||||||
|
import androidx.preference.* |
||||||
|
import io.legado.app.ui.widget.prefs.EditTextPreferenceDialog |
||||||
|
import io.legado.app.ui.widget.prefs.ListPreferenceDialog |
||||||
|
import io.legado.app.ui.widget.prefs.MultiSelectListPreferenceDialog |
||||||
|
|
||||||
|
abstract class BasePreferenceFragment : PreferenceFragmentCompat() { |
||||||
|
|
||||||
|
private val dialogFragmentTag = "androidx.preference.PreferenceFragment.DIALOG" |
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi") |
||||||
|
override fun onDisplayPreferenceDialog(preference: Preference) { |
||||||
|
|
||||||
|
var handled = false |
||||||
|
if (callbackFragment is OnPreferenceDisplayDialogCallback) { |
||||||
|
handled = |
||||||
|
(callbackFragment as OnPreferenceDisplayDialogCallback) |
||||||
|
.onPreferenceDisplayDialog(this, preference) |
||||||
|
} |
||||||
|
if (!handled && activity is OnPreferenceDisplayDialogCallback) { |
||||||
|
handled = (activity as OnPreferenceDisplayDialogCallback) |
||||||
|
.onPreferenceDisplayDialog(this, preference) |
||||||
|
} |
||||||
|
|
||||||
|
if (handled) { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// check if dialog is already showing |
||||||
|
if (parentFragmentManager.findFragmentByTag(dialogFragmentTag) != null) { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
val f: DialogFragment = when (preference) { |
||||||
|
is EditTextPreference -> { |
||||||
|
EditTextPreferenceDialog.newInstance(preference.getKey()) |
||||||
|
} |
||||||
|
is ListPreference -> { |
||||||
|
ListPreferenceDialog.newInstance(preference.getKey()) |
||||||
|
} |
||||||
|
is MultiSelectListPreference -> { |
||||||
|
MultiSelectListPreferenceDialog.newInstance(preference.getKey()) |
||||||
|
} |
||||||
|
else -> { |
||||||
|
throw IllegalArgumentException( |
||||||
|
"Cannot display dialog for an unknown Preference type: " |
||||||
|
+ preference.javaClass.simpleName |
||||||
|
+ ". Make sure to implement onPreferenceDisplayDialog() to handle " |
||||||
|
+ "displaying a custom dialog for this Preference." |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
f.setTargetFragment(this, 0) |
||||||
|
f.show(parentFragmentManager, dialogFragmentTag) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -1,15 +1,19 @@ |
|||||||
package io.legado.app.constant |
package io.legado.app.constant |
||||||
|
|
||||||
import io.legado.app.help.AppConfig |
import io.legado.app.help.AppConfig |
||||||
|
import io.legado.app.utils.ColorUtils |
||||||
|
|
||||||
enum class Theme { |
enum class Theme { |
||||||
Dark, Light, Auto; |
Dark, Light, Auto, Transparent; |
||||||
|
|
||||||
companion object { |
companion object { |
||||||
fun getTheme(): Theme { |
fun getTheme() = |
||||||
return if (AppConfig.isNightTheme) { |
if (AppConfig.isNightTheme) Dark |
||||||
Dark |
else Light |
||||||
} else Light |
|
||||||
} |
fun getTheme(backgroundColor: Int) = |
||||||
|
if (ColorUtils.isColorLight(backgroundColor)) Light |
||||||
|
else Dark |
||||||
|
|
||||||
} |
} |
||||||
} |
} |
@ -0,0 +1,31 @@ |
|||||||
|
package io.legado.app.data.dao |
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData |
||||||
|
import androidx.room.* |
||||||
|
import io.legado.app.data.entities.HttpTTS |
||||||
|
|
||||||
|
@Dao |
||||||
|
interface HttpTTSDao { |
||||||
|
|
||||||
|
@get:Query("select * from httpTTS order by name") |
||||||
|
val all: List<HttpTTS> |
||||||
|
|
||||||
|
@Query("select * from httpTTS order by name") |
||||||
|
fun observeAll(): LiveData<List<HttpTTS>> |
||||||
|
|
||||||
|
@get:Query("select count(*) from httpTTS") |
||||||
|
val count: Int |
||||||
|
|
||||||
|
@Query("select * from httpTTS where id = :id") |
||||||
|
fun get(id: Long): HttpTTS? |
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||||
|
fun insert(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
@Delete |
||||||
|
fun delete(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
@Update |
||||||
|
fun update(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package io.legado.app.data.dao |
||||||
|
|
||||||
|
import androidx.room.* |
||||||
|
import io.legado.app.data.entities.ReadRecord |
||||||
|
import io.legado.app.data.entities.ReadRecordShow |
||||||
|
|
||||||
|
@Dao |
||||||
|
interface ReadRecordDao { |
||||||
|
|
||||||
|
@get:Query("select * from readRecord") |
||||||
|
val all: List<ReadRecord> |
||||||
|
|
||||||
|
@get:Query("select bookName, sum(readTime) as readTime from readRecord group by bookName order by bookName") |
||||||
|
val allShow: List<ReadRecordShow> |
||||||
|
|
||||||
|
@get:Query("select sum(readTime) from readRecord") |
||||||
|
val allTime: Long |
||||||
|
|
||||||
|
@Query("select sum(readTime) from readRecord where bookName = :bookName") |
||||||
|
fun getReadTime(bookName: String): Long? |
||||||
|
|
||||||
|
@Query("select readTime from readRecord where androidId = :androidId and bookName = :bookName") |
||||||
|
fun getReadTime(androidId: String, bookName: String): Long? |
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||||
|
fun insert(vararg readRecord: ReadRecord) |
||||||
|
|
||||||
|
@Update |
||||||
|
fun update(vararg record: ReadRecord) |
||||||
|
|
||||||
|
@Delete |
||||||
|
fun delete(vararg record: ReadRecord) |
||||||
|
|
||||||
|
@Query("delete from readRecord") |
||||||
|
fun clear() |
||||||
|
|
||||||
|
@Query("delete from readRecord where bookName = :bookName") |
||||||
|
fun deleteByName(bookName: String) |
||||||
|
} |