forked from lxm_tools/flutter-picgo
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
807e94159c | ||
|
|
9fbdb0cf01 | ||
|
|
4b76d588b4 | ||
|
|
6b9d8d8c3e | ||
|
|
93d3c3ab15 | ||
|
|
d4d8b36f8e | ||
|
|
81481a99f9 | ||
|
|
8c0b2f772c | ||
|
|
434152c063 | ||
|
|
b91692e237 | ||
|
|
b0cbcbb1d8 | ||
|
|
02c65a6875 | ||
|
|
c85ad49515 | ||
|
|
3b016f170a | ||
|
|
a7723d8ea7 | ||
|
|
87eba041d8 | ||
|
|
1080ae4534 | ||
|
|
1ef205ca71 |
@@ -13,13 +13,14 @@
|
||||
|
||||
Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机版**工具
|
||||
|
||||
Flutter-PicGo 本体支持如下图床:
|
||||
**Flutter-PicGo 本体支持如下图床:**
|
||||
|
||||
- GitHub [v1.0+]
|
||||
- SM.MS [v1.1+]
|
||||
- Gitee [v1.2+]
|
||||
- 七牛云 [v1.3+]
|
||||
- 阿里云OSS [v1.4+]
|
||||
- 腾讯云COS [v1.5+]
|
||||
|
||||
> 开发进度可以查看 [Projects](https://github.com/PicGo/flutter-picgo/projects),会同步更新开发进度
|
||||
|
||||
@@ -30,6 +31,9 @@ Flutter-PicGo 本体支持如下图床:
|
||||
- 适配深色模式,可跟随系统或手动设置
|
||||
- 支持将flutter-picgo的配置导出至剪切板
|
||||
|
||||
> 基本使用配置与PicGo无异,可参考[配置文档](https://picgo.github.io/PicGo-Doc/zh/guide/config.html#%E5%9B%BE%E5%BA%8A%E5%8C%BA)。
|
||||
> 腾讯云COS仅支持v5版配置
|
||||
|
||||
# 应用截图
|
||||
|
||||

|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"iOS": {
|
||||
"versionName": "1.4.0",
|
||||
"versionCode": "8"
|
||||
"versionName": "1.5.2",
|
||||
"versionCode": "12"
|
||||
},
|
||||
"Android": {
|
||||
"versionName": "1.4.1",
|
||||
"versionCode": "9"
|
||||
"versionName": "1.5.1",
|
||||
"versionCode": "12"
|
||||
}
|
||||
}
|
||||
11
lib/api/picgo_api.dart
Normal file
11
lib/api/picgo_api.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_picgo/utils/net.dart';
|
||||
|
||||
class PicgoApi {
|
||||
/// 获取App最新版本
|
||||
static Future getLatestVersion() async {
|
||||
Response res = await NetUtils.getInstance().get(
|
||||
'https://cdn.jsdelivr.net/gh/PicGo/flutter-picgo@dev/docs/version.json');
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,13 @@ class NetUtils {
|
||||
_dio = new Dio(BaseOptions(
|
||||
connectTimeout: 30000, receiveTimeout: 30000, sendTimeout: 30000));
|
||||
if (!inProduction) {
|
||||
/// Tcyun
|
||||
dio.interceptors.add(TcyunInterceptor());
|
||||
|
||||
/// Log
|
||||
dio.interceptors
|
||||
.add(LogInterceptor(requestBody: true, responseBody: true));
|
||||
}
|
||||
|
||||
/// Tcyun Interceptor
|
||||
dio.interceptors.add(TcyunInterceptor());
|
||||
}
|
||||
|
||||
Dio get dio => _dio;
|
||||
|
||||
@@ -11,8 +11,14 @@ class Sql extends BaseModel {
|
||||
return await this.query(tableName);
|
||||
}
|
||||
|
||||
Future<List> getBySql(String where, List<dynamic> whereArgs) async {
|
||||
return await this.query(tableName, where: where, whereArgs: whereArgs);
|
||||
Future<List> getBySql(String where, List<dynamic> whereArgs,
|
||||
{String orderBy, int limit, int offset}) async {
|
||||
return await this.query(tableName,
|
||||
where: where,
|
||||
whereArgs: whereArgs,
|
||||
orderBy: orderBy,
|
||||
limit: limit,
|
||||
offset: offset);
|
||||
}
|
||||
|
||||
Future<int> rawUpdate(String sql, [List<dynamic> arguments]) async {
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:flutter_picgo/views/album_page/album_page_presenter.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:toast/toast.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
|
||||
class AlbumPage extends StatefulWidget {
|
||||
@override
|
||||
@@ -19,6 +20,10 @@ class AlbumPage extends StatefulWidget {
|
||||
class _AlbumPageState extends State<AlbumPage> implements AlbumPageContract {
|
||||
AlbumPagePresenter _presenter;
|
||||
List<Uploaded> _uploadeds = [];
|
||||
RefreshController _refreshController =
|
||||
RefreshController(initialRefresh: false);
|
||||
int _perPageItemSize = 8;
|
||||
int _currentPage = 0;
|
||||
|
||||
_AlbumPageState() {
|
||||
_presenter = AlbumPagePresenter(this);
|
||||
@@ -27,7 +32,7 @@ class _AlbumPageState extends State<AlbumPage> implements AlbumPageContract {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_presenter.doLoadUploadedImages();
|
||||
_onRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -49,8 +54,44 @@ class _AlbumPageState extends State<AlbumPage> implements AlbumPageContract {
|
||||
transition: TransitionType.cupertino);
|
||||
},
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
body: SmartRefresher(
|
||||
enablePullDown: true,
|
||||
enablePullUp: this._uploadeds.length >= _perPageItemSize,
|
||||
header: ClassicHeader(
|
||||
refreshStyle: RefreshStyle.Follow,
|
||||
idleText: '下拉刷新',
|
||||
releaseText: '释放刷新',
|
||||
completeText: '加载完成',
|
||||
refreshingText: '刷新中',
|
||||
failedText: '加载失败,请重试',
|
||||
),
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode) {
|
||||
Widget body;
|
||||
if (mode == LoadStatus.idle) {
|
||||
body = Text("上拉加载");
|
||||
} else if (mode == LoadStatus.loading) {
|
||||
body = SizedBox(
|
||||
width: 15,
|
||||
height: 15,
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else if (mode == LoadStatus.failed) {
|
||||
body = Text("加载失败!点击重试!");
|
||||
} else if (mode == LoadStatus.canLoading) {
|
||||
body = Text("松手,加载更多!");
|
||||
} else {
|
||||
body = Text("没有更多数据了!");
|
||||
}
|
||||
return Container(
|
||||
height: 55.0,
|
||||
child: Center(child: body),
|
||||
);
|
||||
},
|
||||
),
|
||||
onRefresh: _onRefresh,
|
||||
onLoading: _onLoading,
|
||||
controller: _refreshController,
|
||||
child: _uploadeds.length > 0 ? albumView() : emptyView()),
|
||||
);
|
||||
}
|
||||
@@ -142,35 +183,44 @@ class _AlbumPageState extends State<AlbumPage> implements AlbumPageContract {
|
||||
}
|
||||
|
||||
Widget emptyView() {
|
||||
return ListView(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 100),
|
||||
Center(
|
||||
child: Container(
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
child: Image.asset('assets/images/icon_empty_album.png',
|
||||
fit: BoxFit.fill),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Center(
|
||||
child: Text(
|
||||
'相册暂无任何照片,快点击右下角按钮去上传吧',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
)
|
||||
],
|
||||
Center(
|
||||
child: Text(
|
||||
'相册暂无任何照片,快点击右下角按钮去上传吧',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> _onRefresh() async {
|
||||
/// 刷新
|
||||
_onRefresh() async {
|
||||
// _uploadeds.clear();
|
||||
setState(() {
|
||||
_uploadeds.clear();
|
||||
this._currentPage = 0;
|
||||
this._uploadeds.clear();
|
||||
_refreshController.resetNoData();
|
||||
});
|
||||
return _presenter.doLoadUploadedImages();
|
||||
_presenter.doLoadUploadedImages(_perPageItemSize, this._currentPage);
|
||||
}
|
||||
|
||||
/// 上拉加载
|
||||
_onLoading() async {
|
||||
_presenter.doLoadUploadedImages(_perPageItemSize, _currentPage += 1);
|
||||
}
|
||||
|
||||
/// 处理图片点击
|
||||
handleTap(int index) {
|
||||
Clipboard.setData(ClipboardData(text: _uploadeds[index].path));
|
||||
Toast.show('已复制到剪切板', context);
|
||||
@@ -179,13 +229,29 @@ class _AlbumPageState extends State<AlbumPage> implements AlbumPageContract {
|
||||
@override
|
||||
void loadUploadedImages(List<Uploaded> uploadeds) {
|
||||
setState(() {
|
||||
this._uploadeds.addAll(uploadeds);
|
||||
if (this._currentPage == 0) {
|
||||
_refreshController.refreshCompleted();
|
||||
} else if (this._currentPage > 0 &&
|
||||
(uploadeds == null || uploadeds.length == 0)) {
|
||||
_refreshController.loadNoData();
|
||||
} else {
|
||||
this._currentPage += 1;
|
||||
_refreshController.loadComplete();
|
||||
}
|
||||
if (uploadeds != null && uploadeds.length > 0) {
|
||||
this._uploadeds.addAll(uploadeds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void loadError() {
|
||||
Toast.show('加载失败', context);
|
||||
if (this._currentPage == 1) {
|
||||
_refreshController.refreshFailed();
|
||||
} else {
|
||||
_refreshController.loadFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -17,10 +17,11 @@ class AlbumPagePresenter {
|
||||
|
||||
AlbumPagePresenter(this._view);
|
||||
|
||||
doLoadUploadedImages() async {
|
||||
doLoadUploadedImages(int limit, int offest) async {
|
||||
try {
|
||||
var sql = Sql.setTable(TABLE_NAME_UPLOADED);
|
||||
var result = await sql.get();
|
||||
var result = await sql.getBySql(null, null,
|
||||
limit: limit, offset: offest * limit, orderBy: 'id DESC');
|
||||
List<Uploaded> uploadeds = result.map((v) {
|
||||
return Uploaded.fromMap(v);
|
||||
}).toList();
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_picgo/api/picgo_api.dart';
|
||||
import 'package:flutter_picgo/routers/application.dart';
|
||||
import 'package:flutter_picgo/routers/routers.dart';
|
||||
import 'package:flutter_picgo/utils/local_notification.dart';
|
||||
import 'package:flutter_picgo/utils/shared_preferences.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
import 'package:toast/toast.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class PicGoSettingPage extends StatefulWidget {
|
||||
@override
|
||||
@@ -17,6 +23,7 @@ class _PicGoSettingPageState extends State<PicGoSettingPage> {
|
||||
bool isTimestampRename = false;
|
||||
bool isUploadedTip = false;
|
||||
bool isForceDelete = false;
|
||||
bool isNeedUpdate = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -33,6 +40,8 @@ class _PicGoSettingPageState extends State<PicGoSettingPage> {
|
||||
u?.getBool(SharedPreferencesKeys.settingIsForceDelete) ?? false;
|
||||
});
|
||||
});
|
||||
// update
|
||||
_getLatestVersion();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -117,7 +126,20 @@ class _PicGoSettingPageState extends State<PicGoSettingPage> {
|
||||
// ),
|
||||
ListTile(
|
||||
title: Text('检查更新'),
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
_handleUpdateTap();
|
||||
},
|
||||
trailing: CircleAvatar(
|
||||
backgroundColor: Colors.transparent,
|
||||
child: Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
// color: Colors.red,
|
||||
decoration: BoxDecoration(
|
||||
color: isNeedUpdate ? Colors.red : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(4)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -131,4 +153,38 @@ class _PicGoSettingPageState extends State<PicGoSettingPage> {
|
||||
instance.putBool(key, value);
|
||||
Toast.show('保存成功', context);
|
||||
}
|
||||
|
||||
_getLatestVersion() async {
|
||||
try {
|
||||
Response res = await PicgoApi.getLatestVersion();
|
||||
PackageInfo info = await PackageInfo.fromPlatform();
|
||||
int version = int.parse(info.buildNumber);
|
||||
debugPrint('$version');
|
||||
int remoteVersion = 0;
|
||||
if (Platform.isAndroid) {
|
||||
remoteVersion = int.parse('${res.data["Android"]["versionCode"]}');
|
||||
} else if (Platform.isIOS) {
|
||||
remoteVersion = int.parse('${res.data["iOS"]["versionCode"]}');
|
||||
}
|
||||
if (version < remoteVersion) {
|
||||
setState(() {
|
||||
this.isNeedUpdate = true;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
_handleUpdateTap() async {
|
||||
if (isNeedUpdate) {
|
||||
if (Platform.isAndroid) {
|
||||
launch('https://www.pgyer.com/flutter-picgo');
|
||||
} else if (Platform.isIOS) {
|
||||
launch('https://apps.apple.com/cn/app/flutter-picgo/id1519714305');
|
||||
}
|
||||
} else {
|
||||
Toast.show('当前已经是最新版本', context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.5.0+10
|
||||
version: 1.5.2+12
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
@@ -39,6 +39,7 @@ dependencies:
|
||||
provider: ^4.1.3
|
||||
crypto: ^2.1.4
|
||||
flutter_local_notifications: ^1.4.4+1
|
||||
pull_to_refresh: ^1.6.0
|
||||
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
|
||||
Reference in New Issue
Block a user