├── .gitignore
├── .metadata
├── LICENSE
├── README-zh.md
├── README.md
├── android.iml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── cn
│ │ │ └── yotaku
│ │ │ └── light
│ │ │ └── MainActivity.java
│ │ └── res
│ │ ├── drawable
│ │ └── launch_background.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── lightlogo_dark20_color_132x44.png
│ │ └── product_logo_translate_color_144.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── lightlogo_dark20_color_132x44.png
│ │ └── product_logo_translate_color_144.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── lightlogo_dark20_color_132x44.png
│ │ └── product_logo_translate_color_144.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── lightlogo_dark20_color_132x44.png
│ │ └── product_logo_translate_color_144.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── lightlogo_dark20_color_132x44.png
│ │ └── product_logo_translate_color_144.png
│ │ └── values
│ │ ├── dimens.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── assets
├── background
│ ├── bg1.png
│ ├── bg10.png
│ ├── bg11.png
│ ├── bg2.png
│ ├── bg3.png
│ ├── bg4.png
│ ├── bg5.png
│ ├── bg6.png
│ ├── bg7.jpg
│ ├── bg8.png
│ └── bg9.png
├── config.ini
├── default_cover.jpg
├── font
│ ├── Avenir.ttf
│ ├── FZYouH.ttf
│ ├── HYQH.ttf
│ ├── Lora-Regular.ttf
│ └── Noto Serif.ttf
└── light.db
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── main.m
├── lib
├── main.dart
└── src
│ ├── app.dart
│ ├── model
│ ├── book.dart
│ ├── message.dart
│ ├── read_mode.dart
│ ├── selected_list_model.dart
│ ├── tieba_post.dart
│ └── tieba_topic.dart
│ ├── service
│ ├── app_service.dart
│ ├── baidu_service.dart
│ ├── book_service.dart
│ ├── config.dart
│ ├── db.dart
│ ├── file_service.dart
│ ├── initial.dart
│ ├── local.dart
│ ├── mock_book.dart
│ ├── search.dart
│ └── tieba.dart
│ ├── utils
│ ├── custom_text_painter.dart
│ └── page_calculator.dart
│ ├── view
│ ├── chat
│ │ └── chat_screen.dart
│ ├── explore
│ │ └── explore.dart
│ ├── home.dart
│ ├── profile
│ │ └── profile.dart
│ ├── reader
│ │ ├── mask.dart
│ │ ├── menu.dart
│ │ ├── page.dart
│ │ ├── reader.dart
│ │ ├── setting_list.dart
│ │ └── setting_pannel.dart
│ ├── search
│ │ ├── search.dart
│ │ ├── search_item.dart
│ │ └── tieba
│ │ │ ├── detail.dart
│ │ │ ├── search_tieba.dart
│ │ │ └── tieba.dart
│ ├── shelf
│ │ ├── book_item.dart
│ │ ├── entity_item.dart
│ │ ├── import_book.dart
│ │ └── shelf.dart
│ └── web
│ │ ├── page.dart
│ │ └── select_items.dart
│ └── widgets
│ ├── custom_button.dart
│ ├── custom_indicator.dart
│ ├── custom_page_route.dart
│ ├── custom_slider.dart
│ ├── dialog_item.dart
│ ├── image_view.dart
│ ├── item_button.dart
│ ├── label.dart
│ └── select_bottom_bar.dart
├── light.iml
├── light_android.iml
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .atom/
3 | .idea
4 | .vscode/
5 | .packages
6 | .pub/
7 | pubspec.lock
8 | build/
9 | ios/.generated/
10 | packages
11 | .flutter-plugins
12 |
13 | key.properties
14 | *.log
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 3ea4d06340a97a1e9d7cae97567c64e0569dcaa2
8 | channel: beta
9 |
--------------------------------------------------------------------------------
/README-zh.md:
--------------------------------------------------------------------------------
1 | # Light
2 |
3 | 
4 |
5 | Light是一个用Flutter开发的轻小说阅读器。
6 |
7 | 作为学习Flutter期间编写的软件,存在很多不足之处,现在已不再维护。
8 |
9 | 如果你对重构的Light感兴趣,请点击[https://github.com/creatint/light](https://github.com/creatint/light),欢迎提出建议。
10 |
11 |
12 |
13 | ## Features
14 | - [x] 支持ePub2、ePub3文件
15 | - [x] 支持utf-8编码
16 | - [x] 支持latin-1编码
17 | - [x] 支持扫描、导入本地文件
18 | - [x] 自定义字高
19 | - [x] 自定义行高
20 | - [x] 多主题
21 | - [ ] 日、夜间模式切换
22 | - [ ] 搜索、关注、阅读贴吧
23 | - [ ] 剩余页数
24 | - [ ] 垂直、水平滚动
25 | - [ ] 解析ePub文件封面
26 | - [ ] 添加、删除、搜索标签
27 | - [ ] 处理内、外链
28 | - [ ] 贴吧优化阅读
29 | - [ ] 贴吧离线阅读
30 | - [ ] 在线搜索
31 | - [ ] Wifi导书
32 | - [ ] 好友、聊天
33 | - [ ] 书籍分享
34 | - [ ] 文字语音朗读
35 | - [ ] 用户设置
36 |
37 | ## 截屏
38 | 分页显示 | 本地导入
39 | :-------------------------:|:-------------------------:
40 |  | 
41 |
42 | 搜索贴吧 | 浏览帖子
43 | :-------------------------:|:-------------------------:
44 |  | 
45 |
46 | ## 用法
47 | ```
48 | git clone https://github.com/creatint/light
49 | flutter packages get
50 | flutter run
51 | flutter build apk --release
52 | ```
53 | 想要开始使用Flutter框架请浏览在线文档[documentation](https://flutter.io/).
54 |
55 |
56 | ## 联系我
57 | Email: creatint@163.com
58 |
59 | QQ: 565864175
60 |
61 | 编程交流群: [](//shang.qq.com/wpa/qunwpa?idkey=b34e5d3956950dc053efdd7aef63ef75151c01cfff48a951c8fc53d6349b454a)
62 |
63 | 二次元交流群: [](//shang.qq.com/wpa/qunwpa?idkey=2fea46b70c9a73fcbfedd08ee64ed9d6d8c554baa63dc2402082226675e825e7)
64 |
65 | ## License
66 | Light使用GPL-3.0开源许可证,查看[证书](https://github.com/creatint/light/blob/master/LICENSE)。
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Light
2 |
3 | 
4 |
5 | Light is a light novel e-reader build with [Flutter](https://flutter.io).
6 |
7 | As an app written in the study of Flutter, it has many defects.
8 | Confirmed habits are hard to get rid of, so this repository has been no longer maintained.
9 |
10 | If you are interested in my new [Light](https://github.com/creatint/light), please click this [https://github.com/creatint/light](https://github.com/creatint/light), welcome your advice.
11 |
12 | [中文版](README-zh.md)
13 |
14 | ## Features
15 | - [x] ePub 2 and ePub 3 support.
16 | - [x] Utf-8 support.
17 | - [x] Latin-1 support.
18 | - [x] Scan and Import Local Files.
19 | - [x] Custom Text Size.
20 | - [x] Custom Line Height.
21 | - [x] Multi Themes.
22 | - [ ] Day mode / Night mode.
23 | - [ ] Search / Mark / Reading Tieba.
24 | - [ ] Reading Pages left.
25 | - [ ] Vertical or/and Horizontal scrolling.
26 | - [ ] Parse epub cover image.
27 | - [ ] Add / Delete / Search Mark.
28 | - [ ] Handle Internal and External Links.
29 | - [ ] Tieba Optimize reading.
30 | - [ ] Tieba Offline Reading.
31 | - [ ] Book Search Online.
32 | - [ ] Import Book from Wifi.
33 | - [ ] Friend / Chat.
34 | - [ ] Book Share.
35 | - [ ] TTS - Text to Speech Support.
36 | - [ ] User Profile.
37 |
38 | ## Screeshot
39 | Paging | Import
40 | :-------------------------:|:-------------------------:
41 |  | 
42 |
43 | Tieba.baidu.com | Posts
44 | :-------------------------:|:-------------------------:
45 |  | 
46 |
47 | ## Usage
48 | ```
49 | git clone https://github.com/creatint/light
50 | flutter packages get
51 | flutter run
52 | flutter build apk --release
53 | ```
54 | For help getting started with Flutter, view our online
55 | [documentation](https://flutter.io/).
56 |
57 |
58 | ## Contact
59 | Email: creatint@163.com
60 |
61 | QQ: 565864175
62 |
63 | QQ Group for Coding: [](//shang.qq.com/wpa/qunwpa?idkey=b34e5d3956950dc053efdd7aef63ef75151c01cfff48a951c8fc53d6349b454a)
64 |
65 | QQ Group for ACGN: [](//shang.qq.com/wpa/qunwpa?idkey=2fea46b70c9a73fcbfedd08ee64ed9d6d8c554baa63dc2402082226675e825e7)
66 |
67 | ## License
68 |
69 | Light is available under the GPL-3.0 license. See the [LICENSE](https://github.com/creatint/light/blob/master/LICENSE) file.
--------------------------------------------------------------------------------
/android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | apply plugin: 'com.android.application'
15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
16 |
17 | def keystorePropertiesFile = rootProject.file("key.properties")
18 | def keystoreProperties = new Properties()
19 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
20 |
21 | android {
22 | compileSdkVersion 27
23 |
24 | lintOptions {
25 | disable 'InvalidPackage'
26 | }
27 |
28 | defaultConfig {
29 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
30 | applicationId "cn.yotaku.light"
31 | minSdkVersion 16
32 | targetSdkVersion 27
33 | versionCode 1
34 | versionName "1.0"
35 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
36 | }
37 |
38 | signingConfigs {
39 | release {
40 | keyAlias keystoreProperties['keyAlias']
41 | keyPassword keystoreProperties['keyPassword']
42 | storeFile file(keystoreProperties['storeFile'])
43 | storePassword keystoreProperties['storePassword']
44 | }
45 | }
46 | buildTypes {
47 | release {
48 | signingConfig signingConfigs.release
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
61 | }
62 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
17 |
21 |
28 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/java/cn/yotaku/light/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cn.yotaku.light;
2 |
3 | import android.content.ContextWrapper;
4 | import android.content.Intent;
5 | import android.content.IntentFilter;
6 | import android.net.Uri;
7 | import android.os.BatteryManager;
8 | import android.os.Build.VERSION;
9 | import android.os.Build.VERSION_CODES;
10 | import android.os.Bundle;
11 | import android.provider.Settings;
12 |
13 | import io.flutter.app.FlutterActivity;
14 | import io.flutter.plugins.GeneratedPluginRegistrant;
15 | import io.flutter.plugin.common.MethodCall;
16 | import io.flutter.plugin.common.MethodChannel;
17 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
18 | import io.flutter.plugin.common.MethodChannel.Result;
19 |
20 | import java.io.BufferedReader;
21 | import java.io.File;
22 | import java.io.FileInputStream;
23 | import java.io.InputStreamReader;
24 |
25 | public class MainActivity extends FlutterActivity {
26 | private static final String CHANNEL = "light.yotaku.cn/system";
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | GeneratedPluginRegistrant.registerWith(this);
32 |
33 | new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
34 | new MethodCallHandler() {
35 | @Override
36 | public void onMethodCall(MethodCall call, Result result) {
37 | try {
38 | if (call.method.equals("getBatteryLevel")) {
39 | int batteryLevel = getBatteryLevel();
40 |
41 | if (batteryLevel != -1) {
42 | result.success(batteryLevel);
43 | } else {
44 | result.error("UNAVAILABLE", "Battery level not available.", null);
45 | }
46 | } else if (call.method.equals("openApplicationSettings")) {
47 | boolean res = openApplicationSettings();
48 | result.success(res);
49 | } else if (call.method.equals("readFile")) {
50 | // result.success(decodeGbkFile(call.argument("path")));
51 | // String str = decodeGbkFile(call.argument("path"));
52 | // String str = readFile("hahahaha");
53 | // System.out.print(call.argument("path").toString());
54 | String path = call.argument("path");
55 | String res = readFile(path);
56 | result.success(res);
57 | // result.success("hahaha");
58 | } else {
59 | result.notImplemented();
60 | }
61 | } catch (Exception e) {
62 | System.out.println("Error: " + e.getMessage());
63 | }
64 | }
65 | }
66 |
67 | );
68 | }
69 |
70 | private int getBatteryLevel() {
71 | int batteryLevel = -1;
72 | if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
73 | BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
74 | batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
75 | } else {
76 | Intent intent = new ContextWrapper(getApplicationContext()).
77 | registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
78 | batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
79 | intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
80 | }
81 |
82 | return batteryLevel;
83 | }
84 |
85 | private String readFile(String path) {
86 |
87 | String result = null;
88 | // result = path;
89 | // return result;
90 | try {
91 | File f=new File(path);
92 | int length=(int)f.length();
93 | byte[] buff=new byte[length];
94 | FileInputStream fin=new FileInputStream(f);
95 | int flength = fin.read(buff);
96 | fin.close();
97 | result=new String(buff,"gbk");
98 | }catch (Exception e){
99 | return e.getMessage();
100 | }
101 | return result;
102 | }
103 |
104 |
105 | private boolean openApplicationSettings() {
106 | Uri packageURI = Uri.parse("package:" + "cn.yotaku.light");
107 | Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
108 | startActivity(intent);
109 | return true;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 | -
13 |
16 |
17 |
18 | -
20 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/lightlogo_dark20_color_132x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-hdpi/lightlogo_dark20_color_132x44.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/product_logo_translate_color_144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-hdpi/product_logo_translate_color_144.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/lightlogo_dark20_color_132x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-mdpi/lightlogo_dark20_color_132x44.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/product_logo_translate_color_144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-mdpi/product_logo_translate_color_144.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/lightlogo_dark20_color_132x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xhdpi/lightlogo_dark20_color_132x44.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/product_logo_translate_color_144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xhdpi/product_logo_translate_color_144.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/lightlogo_dark20_color_132x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxhdpi/lightlogo_dark20_color_132x44.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/product_logo_translate_color_144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxhdpi/product_logo_translate_color_144.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/lightlogo_dark20_color_132x44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxxhdpi/lightlogo_dark20_color_132x44.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/product_logo_translate_color_144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/app/src/main/res/mipmap-xxxhdpi/product_logo_translate_color_144.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 100.0dip
4 | -4.0dip
5 | 60.0dip
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.0.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/assets/background/bg1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg1.png
--------------------------------------------------------------------------------
/assets/background/bg10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg10.png
--------------------------------------------------------------------------------
/assets/background/bg11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg11.png
--------------------------------------------------------------------------------
/assets/background/bg2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg2.png
--------------------------------------------------------------------------------
/assets/background/bg3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg3.png
--------------------------------------------------------------------------------
/assets/background/bg4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg4.png
--------------------------------------------------------------------------------
/assets/background/bg5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg5.png
--------------------------------------------------------------------------------
/assets/background/bg6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg6.png
--------------------------------------------------------------------------------
/assets/background/bg7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg7.jpg
--------------------------------------------------------------------------------
/assets/background/bg8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg8.png
--------------------------------------------------------------------------------
/assets/background/bg9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/background/bg9.png
--------------------------------------------------------------------------------
/assets/config.ini:
--------------------------------------------------------------------------------
1 | version=0.0.1
2 | database=light.db
3 | storage=Yotaku
--------------------------------------------------------------------------------
/assets/default_cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/default_cover.jpg
--------------------------------------------------------------------------------
/assets/font/Avenir.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/font/Avenir.ttf
--------------------------------------------------------------------------------
/assets/font/FZYouH.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/font/FZYouH.ttf
--------------------------------------------------------------------------------
/assets/font/HYQH.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/font/HYQH.ttf
--------------------------------------------------------------------------------
/assets/font/Lora-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/font/Lora-Regular.ttf
--------------------------------------------------------------------------------
/assets/font/Noto Serif.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/font/Noto Serif.ttf
--------------------------------------------------------------------------------
/assets/light.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/assets/light.db
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | *.pbxuser
16 | *.mode1v3
17 | *.mode2v3
18 | *.perspectivev3
19 |
20 | !default.pbxuser
21 | !default.mode1v3
22 | !default.mode2v3
23 | !default.perspectivev3
24 |
25 | xcuserdata
26 |
27 | *.moved-aside
28 |
29 | *.pyc
30 | *sync/
31 | Icon?
32 | .tags*
33 |
34 | /Flutter/app.flx
35 | /Flutter/app.zip
36 | /Flutter/flutter_assets/
37 | /Flutter/App.framework
38 | /Flutter/Flutter.framework
39 | /Flutter/Generated.xcconfig
40 | /ServiceDefinitions.json
41 |
42 | Pods/
43 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | UIRequiredDeviceCapabilities
24 |
25 | arm64
26 |
27 | MinimumOSVersion
28 | 8.0
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
7 | [GeneratedPluginRegistrant registerWithRegistry:self];
8 | // Override point for customization after application launch.
9 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
10 | }
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creatint/light-old/68d5a8cef1a1090ce4d051df156c4d720a3f973c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | light
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | arm64
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UIViewControllerBasedStatusBarAppearance
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/material.dart';
3 | import 'package:shared_preferences/shared_preferences.dart';
4 |
5 | import 'package:light/src/service/initial.dart';
6 | import 'package:light/src/service/config.dart';
7 | import 'package:light/src/service/db.dart';
8 | import 'package:light/src/app.dart';
9 |
10 | Future prefs;
11 |
12 | void main() async {
13 | SharedPreferences prefs = await initial();
14 | Config config = await Config.getInstance1();
15 | DB db = await DB.getInstance(config);
16 | runApp(new App(prefs: prefs, config: config, db: db,));
17 | // return;
18 | // initial().then((SharedPreferences prefs) {
19 | // Config.getInstance1().then((Config config){
20 | // DB.getInstance(config).then((DB db) {
21 | // runApp(new App(
22 | // prefs: prefs,
23 | // config: config,
24 | // db: db,
25 | // ));
26 | // });
27 | // });
28 | // });
29 | }
30 |
--------------------------------------------------------------------------------
/lib/src/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/foundation.dart';
3 | import 'package:flutter/services.dart';
4 | //import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
5 | import 'package:shared_preferences/shared_preferences.dart';
6 |
7 | import 'package:light/src/service/config.dart';
8 | import 'package:light/src/service/db.dart';
9 | //import 'package:light/src/service/initial.dart';
10 | import 'package:light/src/view/home.dart';
11 | //import 'package:light/src/view/search/tieba/tieba.dart';
12 | //import 'package:light/src/view/search/tieba/detail.dart';
13 | //import 'package:light/src/model/tieba_topic.dart';
14 | //import 'package:light/src/view/chat/chat_screen.dart';
15 | //import 'package:light/src/view/shelf/import_book.dart';
16 |
17 | final ThemeData _kGalleryLightTheme = new ThemeData(
18 | brightness: Brightness.light,
19 | primarySwatch: Colors.blue,
20 | );
21 |
22 | final ThemeData _kGalleryDarkTheme = new ThemeData(
23 | brightness: Brightness.dark,
24 | primarySwatch: Colors.blue,
25 | );
26 |
27 | class App extends StatefulWidget {
28 | final SharedPreferences prefs;
29 | final Config config;
30 | final DB db;
31 |
32 | App({@required this.config, @required this.prefs, @required this.db});
33 |
34 | @override
35 | _AppState createState() => new _AppState();
36 | }
37 |
38 | class _AppState extends State {
39 | bool _useLightTheme = true;
40 |
41 | @override
42 | void initState() {
43 | super.initState();
44 | print('init app');
45 | SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return new MaterialApp(
51 | title: 'Light',
52 | debugShowCheckedModeBanner: false,
53 | theme: _useLightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme,
54 | routes: {
55 | // '/': (BuildContext context) => new ImportBook(
56 | // key: new Key('start'),
57 | // isRoot: true,
58 | // path: '/storage/emulated/0/DuoKan/Downloads/MiCloudBooks',
59 | //// path: '/storage/emulated/0/DuoKan',
60 | // ),
61 | '/': (BuildContext context) => new Home(
62 | useLightTheme: _useLightTheme,
63 | prefs: widget.prefs,
64 | onThemeChanged: (bool value) {
65 | setState(() {
66 | print('set _useLightTheme to $value');
67 | _useLightTheme = value;
68 | });
69 | },
70 | ),
71 | // '/': (BuildContext context) => new Tieba(fname: '爱书的下克上'),
72 | // '/': (BuildContext context) => new ChatScreen(
73 | // appAccount: '13244414819',
74 | // username: 'Creaty',
75 | // ),
76 | // '/': (BuildContext context) => new Tieba(fname: '爆肝工程师的异世界狂想曲'),
77 | // '/': (BuildContext context) => new Detail(
78 | // topic: new TiebaTopic(title: 'VRchat,科普一下VR平台最火的二次元游戏',
79 | // url: 'http://tieba.baidu.com/mo/q---0C6E0C5D10B08D2558E1AF076714E837%3AFG%3D1--1-3-0--2--wapp_1521603526919_731/m?kz=5561118240&new_word=&pinf=1_2_60&pn=0&lp=6005',
80 | // tiebaUrl: 'http://tieba.baidu.com',
81 | // clickTimes: 12,
82 | // replyTimes: 384),
83 | // ),
84 | // "/": (_) => new WebviewScaffold(
85 | // url: 'http://tieba.baidu.com/mo/q---0C6E0C5D10B08D2558E1AF076714E837%3AFG%3D1--1-3-0--2--wapp_1521603526919_731/m?kz=5608792899&is_bakan=0&lp=5010&pinf=1_2_0',
86 | // appBar: new AppBar(
87 | // title: new Text("Widget webview"),
88 | // ),
89 | // withZoom: true,
90 | // )
91 | },
92 | );
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/lib/src/model/book.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'dart:io';
3 | import 'dart:async';
4 | import 'package:light/src/service/file_service.dart';
5 | import 'package:light/src/service/book_service.dart';
6 |
7 | ///book数据可能是从线上获取,也可能是本地存储
8 | ///无论从线上线下获取到的book数据,封面不一定存在
9 | /// 225 130 101 599
10 | enum BookType { txt, epub, pdf, url, urls }
11 |
12 | class Book {
13 | Book(
14 | {@required this.title,
15 | this.description,
16 | this.coverUri,
17 | this.uri,
18 | this.type,
19 | this.createAt,
20 | this.updateAt});
21 |
22 | Book.fromEntity({@required FileSystemEntity entity})
23 | : assert(null != entity),
24 | title =
25 | new RegExp(r'([^/]+)\.[^./]+$').firstMatch(entity.path).group(1),
26 | description = null,
27 | coverUri = null,
28 | uri = entity.path,
29 | type = getSuffix(entity),
30 | createAt = new DateTime.now().toIso8601String(),
31 | updateAt = new DateTime.now().toIso8601String();
32 |
33 | final String title;
34 | final String description;
35 | final String coverUri;
36 | final String uri;
37 | final String type;
38 | final String createAt;
39 | final String updateAt;
40 | BookService bookService;
41 |
42 | Book.fromMap({@required Map map})
43 | : assert(null != map),
44 | title = map['title'],
45 | description = map['description'],
46 | coverUri = map['cover_uri'],
47 | uri = map['uri'],
48 | type = map['type'],
49 | createAt = map['create_at'],
50 | updateAt = map['update_at'];
51 |
52 | @override
53 | String toString() => '{title: $title, type: $type, uri: $uri}\n';
54 |
55 | // BookType get bookType => BookType.values.firstWhere((t) => t.toString() == this.type);
56 | BookType get bookType => BookType.values.firstWhere((t) {
57 | // print(t.toString());
58 | // print(this.type);
59 | return t.toString() == 'BookType.' + this.type;
60 | });
61 |
62 | Map getMap() {
63 | return {
64 | 'title': title,
65 | 'description': description,
66 | 'cover_uri': coverUri,
67 | 'type': type,
68 | 'uri': uri,
69 | 'create_at': createAt
70 | };
71 | }
72 |
73 | /// 用于记录分页数据
74 | String get recordsName => title + '_records';
75 |
76 | /// 用于纪录阅读进度
77 | String get processName => title + '_process';
78 |
79 | Future delete() async {
80 | if (null == bookService) {
81 | bookService = new BookService();
82 | }
83 | return await bookService.deleteBook(this);
84 | }
85 | }
86 |
87 | /// 章节数据
88 | class Chapter {
89 | Chapter(
90 | {@required this.id,
91 | @required this.title,
92 | @required this.offset,
93 | @required this.length});
94 |
95 | List subChapters = [];
96 |
97 | final int id;
98 | final String title;
99 | final int offset;
100 | final int length;
101 |
102 | @override
103 | String toString() {
104 | return 'Chapter{id: $id, title: $title, offset: $offset, length: $length}';
105 | }
106 | }
107 |
108 | BookType getBookType(FileSystemEntity entity) {
109 | String suffix = getSuffix(entity);
110 | return BookType.values
111 | .firstWhere((t) => t.toString() == 'BookType.' + suffix);
112 | }
113 |
--------------------------------------------------------------------------------
/lib/src/model/message.dart:
--------------------------------------------------------------------------------
1 | //import 'dart:convert';
2 |
3 | ///ping:ping/pong
4 | ///事件:event
5 | ///文件:file
6 | ///文本:text
7 | ///图片:image
8 | ///语音:voice
9 | ///视频:video
10 | ///位置:location
11 | ///链接:link
12 | enum MessageType {
13 | ping,
14 | pong,
15 | event,
16 | file,
17 | text,
18 | image,
19 | voice,
20 | video,
21 | location,
22 | link
23 | }
24 |
25 | class Message {
26 | Message(
27 | {this.version,
28 | this.topicId,
29 | this.toAccount,
30 | this.toUsername,
31 | this.fromAccount,
32 | this.fromUsername,
33 | this.msgId,
34 | this.msgType,
35 | this.timestamp,
36 | this.data});
37 |
38 | final double version;
39 | final String topicId;
40 | final String msgId;
41 | final String toAccount;
42 | final String toUsername;
43 | final String fromAccount;
44 | final String fromUsername;
45 | final MessageType msgType;
46 | final int timestamp;
47 | final String data;
48 |
49 | String getContent() {
50 | return data;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/src/model/read_mode.dart:
--------------------------------------------------------------------------------
1 | //import 'dart:io';
2 | //import 'dart:convert';
3 | import 'package:flutter/material.dart';
4 | //import 'package:light/src/service/file_service.dart';
5 |
6 | ///閲讀主題類型
7 | ///[color]純色背景
8 | ///[image]圖片背景
9 | ///[texture]通過reapeat填充的背景
10 | enum ReadModeType { color, image, texture }
11 |
12 |
13 | class ReadMode {
14 | ReadMode({
15 | this.id,
16 | this.type,
17 | this.fontColor,
18 | this.backgroundColor,
19 | this.imageUri,
20 | });
21 |
22 | ///用於解析從數據庫讀取的數據
23 | ReadMode.fromMap(Map map)
24 | : this.id = int.parse(map['id']),
25 | this.type = ReadModeType.values
26 | .firstWhere((v) => v.toString() == 'ReadModeType.' + map['type']),
27 | this.fontColor = new Color(int.parse(map['font_color'])),
28 | this.backgroundColor = map['background_color'],
29 | this.imageUri = map['image_uri'];
30 |
31 | final int id;
32 | final ReadModeType type;
33 | final Color fontColor;
34 | final Color backgroundColor;
35 | final String imageUri;
36 |
37 | BoxFit get fit => type == ReadModeType.image
38 | ? BoxFit.cover
39 | : type == ReadModeType.texture ? BoxFit.none : null;
40 |
41 | ImageRepeat get repeat => type == ReadModeType.image
42 | ? ImageRepeat.noRepeat
43 | : type == ReadModeType.texture ? ImageRepeat.repeat : null;
44 |
45 | DecorationImage get image => null != imageUri
46 | ? new DecorationImage(
47 | fit: fit, repeat: repeat, image: new AssetImage(imageUri))
48 | : null;
49 | DecorationImage get buttonImage => null != imageUri
50 | ? new DecorationImage(
51 | fit: fit, repeat: ImageRepeat.repeat, image: new AssetImage(imageUri))
52 | : null;
53 | }
54 |
--------------------------------------------------------------------------------
/lib/src/model/selected_list_model.dart:
--------------------------------------------------------------------------------
1 | //import 'dart:io';
2 | import 'package:flutter/foundation.dart';
3 |
4 | typedef void SetterCallback(T element, List list);
5 | typedef E GetterCallback(T element, List list);
6 |
7 | class SelectedListModel {
8 | SelectedListModel({
9 | @required handleRemove(T element, List list),
10 | @required handleIndexOf(T element, List list)
11 | })
12 | : _handleIndexOf = handleIndexOf,
13 | _handleRemove = handleRemove;
14 |
15 | final SetterCallback _handleRemove;
16 | final GetterCallback _handleIndexOf;
17 | List _list = [];
18 |
19 | List get list => _list;
20 |
21 | void addAll(List list) {
22 | list.forEach((T ele) {
23 | add(ele);
24 | });
25 | }
26 |
27 | void add(T ele) {
28 | remove(ele);
29 | _list.add(ele);
30 | }
31 |
32 | void remove(T ele) => _handleRemove(ele, _list);
33 |
34 | T operator [](int index) => _list[index];
35 |
36 | int get length => _list.length;
37 |
38 | int indexOf(T ele) => _handleIndexOf(ele, _list);
39 |
40 | void clear() {
41 | _list.clear();
42 | }
43 |
44 | void forEach(ValueChanged call) => _list.forEach(call);
45 |
46 | bool get isEmpty => _list.isEmpty;
47 | bool get isNotEmpty => _list.isNotEmpty;
48 | }
49 |
--------------------------------------------------------------------------------
/lib/src/model/tieba_post.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/foundation.dart';
4 | import 'package:html/parser.dart';
5 | import 'package:html/dom.dart';
6 |
7 | import 'package:light/src/service/baidu_service.dart';
8 |
9 | class TiebaPost {
10 | TiebaPost({
11 | this.data,
12 | }) {
13 | document = parse(data);
14 | }
15 |
16 | TiebaPost.json(
17 | {@required this.raw, this.datetime, this.avatarUrl, this.referer}) {
18 | data = json.decode(raw);
19 | author = data['author'];
20 | content = data['content']['content'];
21 | flour = data['content']['post_no'];
22 | commentNum = data['content']['comment_num'];
23 | }
24 |
25 | String referer;
26 | String raw;
27 | Map data;
28 | Document document;
29 |
30 | String avatarUrl;
31 | Map author;
32 | int commentNum;
33 | String content;
34 | String datetime;
35 | int flour;
36 | RegExp regFlour = new RegExp(r'^(\d+)楼\.');
37 |
38 | String getFlour() {
39 | return flour.toString();
40 | // flour = regFlour.firstMatch(data).group(1);
41 | // return flour;
42 | }
43 |
44 | String getNormalUrl(String url) {
45 | if (new RegExp(r'^//').hasMatch(url)) {
46 | return 'https:' + url;
47 | }
48 | return url;
49 | }
50 |
51 | Image getAvatar() {
52 | return getImage(getNormalUrl(avatarUrl), getAuthor(), referer);
53 | }
54 |
55 | String getAuthor() {
56 | return author['user_name'];
57 | // author = document.querySelector('span.g>a').innerHtml;
58 | // return author;
59 | }
60 |
61 | String getDatetime() {
62 | return datetime;
63 | // datetime = document.querySelector('span.b').innerHtml;
64 | // return datetime;
65 | }
66 |
67 | String getContent() {
68 | return content;
69 | // content = document.firstChild.text.replaceFirst(regFlour, '').split('\n');
70 | // content.removeAt(content.length - 1);
71 | // return content.join('\n');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/lib/src/model/tieba_topic.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 |
3 | class TiebaTopic{
4 | TiebaTopic({
5 | @required this.id,
6 | @required this.title,
7 | @required this.url,
8 | @required this.tiebaUrl,
9 | @required this.clickTimes,
10 | @required this.replyTimes
11 | });
12 |
13 | final int id;
14 | final String title;
15 | final String url;
16 | final String tiebaUrl;
17 | final int clickTimes;
18 | final int replyTimes;
19 | }
--------------------------------------------------------------------------------
/lib/src/service/app_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:shared_preferences/shared_preferences.dart';
3 | import 'package:flutter/foundation.dart' show required;
4 |
5 | class AppService {
6 | static AppService _cache;
7 |
8 | AppService._internal({@required this.prefs})
9 | : streamController = new StreamController.broadcast();
10 |
11 | factory AppService({SharedPreferences prefs}) {
12 | if (null == _cache) {
13 | _cache = new AppService._internal(prefs: prefs);
14 | }
15 | return _cache;
16 | }
17 |
18 | /// SharedPreferences实例
19 | final SharedPreferences prefs;
20 |
21 | /// 流控制器
22 | final StreamController streamController;
23 |
24 | /// 获得stream
25 | Stream get stream => streamController.stream;
26 |
27 | /// 发送事件
28 | void add(value) => streamController.add(value);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/lib/src/service/baidu_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | //import 'package:http/http.dart';
3 |
4 | Map cache = {};
5 |
6 | getImage(String url, String key, [String referer]) {
7 | if (cache[key] != null) {
8 | print('有缓存');
9 | return cache[key];
10 | }
11 | print('无缓存 name = $key \n url = $url \n referer = $referer');
12 | cache[key] = new Image.network(url, headers: {'referer': referer});
13 | return cache[key];
14 | }
15 |
--------------------------------------------------------------------------------
/lib/src/service/config.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:async';
3 | //import 'dart:convert';
4 | //import 'dart:typed_data';
5 | import 'package:path/path.dart';
6 | //import 'package:flutter/services.dart';
7 | import 'package:path_provider/path_provider.dart';
8 | import 'package:options_file/options_file.dart';
9 |
10 | class Config {
11 | static Config _instance;
12 | static OptionsFile _optionFile;
13 |
14 | static Future getInstance1() async {
15 | try {
16 | if (null == _optionFile) {
17 | Directory dir = await getApplicationDocumentsDirectory();
18 |
19 | String path = join(dir.path, 'config.ini');
20 | if (!(new File(path).existsSync())) {
21 | // throw new FileSystemException('config.ini不存在 $path');
22 | print('config.ini不存在 $path');
23 | return null;
24 | }
25 | _optionFile = new OptionsFile(path);
26 | }
27 | if (null == _instance) {
28 | _instance = new Config._();
29 | return _instance;
30 | }
31 | return _instance;
32 | } catch(e) {
33 | print('Config加载异常:$e');
34 | return null;
35 | }
36 | }
37 |
38 | Config._();
39 |
40 | String getString(String key) {
41 | return _optionFile.getString(key);
42 | }
43 |
44 | int getInt(String key) {
45 | return _optionFile.getInt(key);
46 | }
47 |
48 | bool getBool(String key) {
49 | return getString(key) == 'true';
50 | }
51 |
52 | double getDouble(String key) {
53 | return double.parse(getString(key));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/src/service/db.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:async';
3 | import 'package:path/path.dart';
4 | import 'package:sqflite/sqflite.dart';
5 | import 'package:path_provider/path_provider.dart';
6 |
7 | import 'package:light/src/service/config.dart';
8 |
9 | class DB {
10 | static DB _instance;
11 | static Config _config;
12 | static Database _database;
13 |
14 | DB._();
15 |
16 | factory DB([String name = 'default']) {
17 | if (null != _instance)
18 | return _instance;
19 | else
20 | return null;
21 | }
22 |
23 | static Future getInstance([Config config]) async {
24 | try {
25 | if (null == _config) {
26 | _config = config;
27 | }
28 | if (null == _database) {
29 | if (null == _config) {
30 | return null;
31 | }
32 | Directory dir = await getApplicationDocumentsDirectory();
33 | String path = join(dir.path, _config.getString('database'));
34 | if (new File(path).existsSync()) {
35 | _database = await openDatabase(path, version: 3,
36 | onCreate: (Database db, int version) async {
37 | // When creating the db, create the table
38 | print('数据库连接成功 version: $version, path: $path');
39 | });
40 | } else {
41 | return null;
42 | }
43 | }
44 | if (null == _instance) {
45 | _instance = new DB._();
46 | return _instance;
47 | }
48 | return _instance;
49 | } catch (e) {
50 | print('DB加载异常:$e');
51 | return null;
52 | }
53 | }
54 |
55 | ///INSERT data
56 | Future insert(String table, Map values,
57 | {String nullColumnHack, ConflictAlgorithm conflictAlgorithm}) {
58 | return _database.insert(table, values,
59 | nullColumnHack: nullColumnHack, conflictAlgorithm: conflictAlgorithm);
60 | }
61 |
62 | ///SELECT data
63 | Future>> query(String table,
64 | {bool distinct,
65 | List columns,
66 | String where,
67 | List whereArgs,
68 | String groupBy,
69 | String having,
70 | String orderBy,
71 | int limit,
72 | int offset}) {
73 | return _database.query(table,
74 | distinct: distinct,
75 | columns: columns,
76 | where: where,
77 | whereArgs: whereArgs,
78 | groupBy: groupBy,
79 | having: having,
80 | orderBy: orderBy,
81 | limit: limit,
82 | offset: offset);
83 | }
84 |
85 | Future> rawQuery(String query) {
86 | return _database.rawQuery(query);
87 | }
88 |
89 | Future rawDelete(String sql, List arguments) {
90 | return _database.rawDelete(sql, arguments);
91 | }
92 |
93 | Future execute(String query, List arguments) {
94 | return _database.execute(query, arguments);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/lib/src/service/file_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:async';
3 | import 'package:path/path.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:path_provider/path_provider.dart';
6 |
7 | enum FileType { TEXT, EPUB, PDF, OTHER, NOT_FOUND, DIRECTORY }
8 |
9 | RegExp _regFileType = new RegExp(r'([^.\\/]+)$');
10 | RegExp _regTXT = new RegExp(r'txt');
11 | RegExp _regPDF = new RegExp(r'pdf');
12 | RegExp _regEPUB = new RegExp(r'epub');
13 | RegExp _regName = new RegExp(r'(.+)[^.]+$');
14 | RegExp _regSuffix = new RegExp(r'.*\.([^.\\/]+)$');
15 | RegExp _regBasename = new RegExp(r'[^/\\]+$');
16 |
17 | FileType getType(FileSystemEntity entity) {
18 | if (entity.existsSync()) {
19 | if (FileSystemEntity.isDirectorySync(entity.path)) {
20 | return FileType.DIRECTORY;
21 | } else {
22 | String name = getBasename(entity.path);
23 | FileType type;
24 | if (name == null || name.isEmpty) {
25 | type = FileType.OTHER;
26 | }
27 | String suffix = _regFileType.firstMatch(name)?.group(1);
28 | if (null == suffix || suffix.isEmpty) {
29 | type = FileType.OTHER;
30 | } else if (_regTXT.hasMatch(suffix))
31 | type = FileType.TEXT;
32 | else if (_regPDF.hasMatch(suffix))
33 | type = FileType.PDF;
34 | else if (_regEPUB.hasMatch(suffix))
35 | type = FileType.EPUB;
36 | else
37 | type = FileType.OTHER;
38 | return type;
39 | }
40 | }
41 | return FileType.NOT_FOUND;
42 | }
43 |
44 | String getBasename(var file) {
45 | if (file is String) {
46 | return _regBasename.firstMatch(file)?.group(0);
47 | } else if (file is Directory || file is FileSystemEntity) {
48 | return _regBasename.firstMatch(file.path)?.group(0);
49 | } else {
50 | return '';
51 | }
52 | }
53 |
54 | String getName(var file) {
55 | String baseName = getBasename(file);
56 | // print('baseName: $baseName');
57 | String name = _regName.firstMatch(baseName)?.group(1);
58 | // print(_regName.firstMatch(baseName));
59 | return name;
60 | // return _regName.firstMatch(baseName)?.group(1);
61 | }
62 |
63 | String getSuffix(var file) {
64 | String baseName = getBasename(file);
65 | String suffix = _regSuffix.firstMatch(baseName)?.group(1);
66 | // print(_regSuffix.firstMatch(baseName).group(0));
67 | // print(_regSuffix.firstMatch(baseName).group(1));
68 | return suffix;
69 | }
70 |
71 | Future writeFile(String content, String name) async {
72 | Directory dir = await getExternalStorageDirectory();
73 | String path = join(dir.path, 'Yotaku', name);
74 | try {
75 | print('写入文件 path=$path\ncontent=$content');
76 | File file = new File(path);
77 | file.writeAsStringSync(content);
78 | return null;
79 | } catch (e) {
80 | print('文件写入失败:$e');
81 | if (dir.existsSync()) {
82 | print('文件夹存在:${dir.path}');
83 | } else {
84 | print('文件夹不存在:${dir.path}');
85 | }
86 | return null;
87 | }
88 | }
89 |
90 | bool isDirectory(FileSystemEntity entity) {
91 | return FileSystemEntity.isDirectorySync(entity.path);
92 | }
93 |
94 | class FileService {
95 | static final Map _cache = {};
96 | static final Future external = getExternalStorageDirectory();
97 |
98 | factory FileService([String name = 'default']) {
99 | if (_cache.containsKey(name)) {
100 | return _cache[name];
101 | } else {
102 | _cache[name] = new FileService._internal();
103 | return _cache[name];
104 | }
105 | }
106 |
107 | FileService._internal();
108 |
109 | Future readFile(String name) async {
110 | try {
111 | return external.then((Directory dir) {
112 | String path = join(dir.path, 'Yotaku', name);
113 | print(path);
114 | File file = new File(path);
115 | print('flag');
116 | return file.readAsStringSync() as T;
117 | });
118 | } catch (e) {
119 | print('文件读取失败:$e');
120 | return null;
121 | }
122 | }
123 | }
124 |
125 | Image getImage(String uri) {
126 | RegExp regasset = new RegExp(r'^asset');
127 | RegExp regurl = new RegExp(r'^http');
128 | RegExp regfile = new RegExp(r'^/storage');
129 | if (regasset.hasMatch(uri)) {
130 | return new Image.asset(uri);
131 | } else if (regurl.hasMatch(uri)) {
132 | return new Image.network(uri);
133 | } else if (regfile.hasMatch(uri)) {
134 | return new Image.file(new File(uri));
135 | }
136 | return null;
137 | }
138 |
139 | String charsetDetector(RandomAccessFile file) {
140 | String charset;
141 | List bytes = file.readSync(3);
142 | int length = file.lengthSync();
143 | bool isLatin1 = true;
144 | bool isUtf8 = true;
145 | if (null != bytes &&
146 | bytes.length == 3 &&
147 | bytes[0] == 0xEF &&
148 | bytes[1] == 0xBB &&
149 | bytes[2] == 0xBF) {
150 | isLatin1 = false;
151 | } else if (null != bytes && bytes.isNotEmpty) {
152 | //不带bom头,可能是gbk,latin1,utf8,big5
153 | bytes = file.readSync(100 > length ? length : 100);
154 | int i = 0;
155 | do {
156 | if (bytes[i] > 127) {
157 | isLatin1 = false;
158 | }
159 | if ((bytes[i] & 0xC0) != 0x80) {
160 | isUtf8 = false;
161 | }
162 | i++;
163 | } while (i < bytes.length);
164 | }
165 | if (!isLatin1 && !isUtf8) {
166 | charset = 'gbk';
167 | } else if (!isLatin1 && isUtf8) {
168 | charset = 'utf8';
169 | } else if (isLatin1 && !isUtf8) {
170 | charset = 'latin1';
171 | }
172 | return charset;
173 | }
174 |
--------------------------------------------------------------------------------
/lib/src/service/initial.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:async';
3 | //import 'dart:convert';
4 | import 'dart:typed_data';
5 | import 'package:flutter/services.dart';
6 | import 'package:path/path.dart';
7 | import 'package:path_provider/path_provider.dart';
8 | import 'package:shared_preferences/shared_preferences.dart';
9 | import 'package:sqflite/sqflite.dart';
10 |
11 | import 'package:light/src/service/config.dart';
12 | import 'package:light/src/service/db.dart';
13 |
14 | ///判断是否已经安装
15 | Future isInstalled(SharedPreferences prefs) async {
16 | // return false;
17 | if (prefs.getBool('installed') != null && prefs.getBool('installed') == true)
18 | return true;
19 | return false;
20 | }
21 |
22 | ///执行安装
23 | Future initial() async {
24 | SharedPreferences prefs = await SharedPreferences.getInstance();
25 | if (await isInstalled(prefs)) {
26 | print('Installed, skip......');
27 | return prefs;
28 | }
29 | print('Installing......');
30 |
31 | //检查权限
32 | if (!(await checkPermissions())) {
33 | return prefs;
34 | }
35 |
36 | Directory directory = await getApplicationDocumentsDirectory();
37 |
38 | try {
39 | Config config = await createConfig(directory);
40 | if (null == config) {
41 | throw new Exception('复制config失败');
42 | }
43 | DB db = await createDB(directory, config);
44 | if (null == db) {
45 | throw new Exception('复制db失败');
46 | }
47 | // bool dirRes = await createDirectory(config);
48 | // if (!dirRes) {
49 | // throw new Exception('创建文件夹失败');
50 | // }
51 | bool testRes = await test(dir: directory, db: db, config: config);
52 | if (!testRes) {
53 | throw new Exception('测试失败');
54 | }
55 | // createConfig(directory).then((Config config) {
56 | // print('flag1');
57 | // createDB(directory, config).then((DB db) {
58 | // print('flag2');
59 | // createDirectory(config).then((done) {
60 | // print('flag3');
61 | // if (done)
62 | // test(dir: directory, db: db, config: config).then((_) {
63 | // return prefs;
64 | // });
65 | // });
66 | // });
67 | // });
68 | prefs.setBool('installed', true);
69 | } on FileSystemException catch (e) {
70 | print('需要文件读写权限 $e');
71 | } catch (e) {
72 | print('Install failed. $e');
73 | }
74 | return prefs;
75 | }
76 |
77 | ///测试权限
78 | Future checkPermissions() async {
79 | Directory dir = await getApplicationDocumentsDirectory();
80 | String path = join(dir.path, 'test.txt');
81 | try {
82 | print('尝试写入测试文件 path=$path');
83 | File file = new File(path);
84 | file.writeAsStringSync('test');
85 | if (file.readAsStringSync() == 'test') {
86 | print('测试文件写入成功');
87 | return true;
88 | } else {
89 | print('测试写入文件失败');
90 | return false;
91 | }
92 | } catch (e) {
93 | print('测试文件写入失败:$e');
94 | if (dir.existsSync()) {
95 | print('文件夹存在:${dir.path}');
96 | } else {
97 | print('文件夹存在:${dir.path}');
98 | }
99 | if (new File(path).existsSync()) {
100 | print('文件存在:$path');
101 | List list = dir.listSync();
102 | list.forEach((FileSystemEntity entity) {
103 | print(entity.path);
104 | });
105 | } else {
106 | print('文件不存在:$path');
107 | }
108 | return false;
109 | }
110 | }
111 |
112 | ///创建配置文件
113 | Future createConfig(Directory dir) async {
114 | try {
115 | String path = join(dir.path, 'config.ini');
116 | print('正在复制配置文件config.ini到$path');
117 | ByteData data = await rootBundle.load(join('assets', 'config.ini'));
118 | List bytes =
119 | data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
120 | new File(path).writeAsBytesSync(bytes);
121 | return Config.getInstance1();
122 | } catch (e) {
123 | print('创建配置文件失败:$e');
124 | return null;
125 | }
126 | }
127 |
128 | ///创建数据库
129 | Future createDB(Directory dir, Config config) async {
130 | print('createDB');
131 | try {
132 | //数据库路径
133 | String path = join(dir.path, config.getString('database'));
134 | //创建路径
135 | await new Directory(dirname(path)).create(recursive: true);
136 |
137 | //删除数据库
138 | if (new File(path).existsSync()) {
139 | await deleteDatabase(path);
140 | }
141 | print('flag1.5');
142 |
143 | //读取asset资源
144 | ByteData dbData = await rootBundle.load(join('assets', 'light.db'));
145 | List dbBytes =
146 | dbData.buffer.asUint8List(dbData.offsetInBytes, dbData.lengthInBytes);
147 | //写入app文件夹
148 | await new File(path).writeAsBytes(dbBytes);
149 | print('flag1.6');
150 |
151 | //新建数据库并打开
152 | Database db = await openDatabase(path, version: 3,
153 | onCreate: (Database db, int version) async {
154 | // When creating the db, create the table
155 | print('数据库创建成功 version: $version, path: $path');
156 | await db.execute(
157 | "CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)");
158 | });
159 |
160 | // Insert some records in a transaction
161 | await db.transaction((txn) async {
162 | int id1 = await txn.rawInsert(
163 | 'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');
164 | print("inserted1: $id1");
165 | int id2 = await txn.rawInsert(
166 | 'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)',
167 | ["another name", 12345678, 3.1416]);
168 | print("inserted2: $id2");
169 | });
170 |
171 | // Update some record
172 | int count = await db.rawUpdate(
173 | 'UPDATE Test SET name = ?, VALUE = ? WHERE name = ?',
174 | ["updated name", "9876", "some name"]);
175 | print("updated: $count");
176 |
177 | // Get the records
178 | List