This commit is contained in:
朱子楚\zhuzi
2023-09-04 20:45:56 +08:00
16 changed files with 666 additions and 387 deletions

View File

@ -4,6 +4,24 @@
#include <QObject>
#include <QtQml/qqml.h>
namespace FluHttpType {
Q_NAMESPACE
enum CacheMode {
/** 不使用缓存 */
NoCache = 0x0000,
/** 请求网络失败后,读取缓存 */
RequestFailedReadCache = 0x0001,
/** 如果缓存不存在才请求网络,否则使用缓存 */
IfNoneCacheRequest = 0x0002,
/** 先使用缓存,不管是否存在,仍然请求网络 */
FirstCacheThenRequest = 0x0004,
};
Q_ENUM_NS(CacheMode)
QML_NAMED_ELEMENT(FluHttpType)
}
namespace FluScreenshotType {
Q_NAMESPACE

View File

@ -6,14 +6,26 @@
#include <QUrlQuery>
#include <QHttpMultiPart>
#include <QJsonDocument>
#include <QStandardPaths>
#include <QTextStream>
#include <QDir>
#include "Def.h"
#include "MainThread.h"
#include "FluApp.h"
#include "FluTools.h"
HttpCallable::HttpCallable(QObject *parent)
: QObject{parent}
{
}
FluHttp::FluHttp(QObject *parent)
: QObject{parent}
{
retry(3);
timeout(15000);
cacheMode(FluHttpType::CacheMode::NoCache);
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache");
}
FluHttp::~FluHttp(){
@ -21,7 +33,7 @@ FluHttp::~FluHttp(){
}
void FluHttp::cancel(){
foreach (QPointer<QNetworkReply> item, _cache) {
foreach (QPointer<QNetworkReply> item, _cacheReply) {
if(item){
item->abort();
}
@ -29,13 +41,22 @@ void FluHttp::cancel(){
}
void FluHttp::handleReply(QNetworkReply* reply){
_cache.append(reply);
_cacheReply.append(reply);
}
void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"post").toMap();
void FluHttp::post(QString url,HttpCallable* callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
onStart(callable);
auto requestMap = toRequest(url,params,headers,"post");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){
Q_EMIT callable->cache(readCache(requestMap));
Q_EMIT callable->finish();
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){
Q_EMIT callable->cache(readCache(requestMap));
}
for (int i = 0; i < retry(); ++i) {
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
@ -55,7 +76,7 @@ void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,&multiPart);
_cache.append(reply);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
@ -64,26 +85,40 @@ void FluHttp::post(QString url,QJSValue callable,QMap<QString, QVariant> params,
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
handleCache(requestMap,result);
Q_EMIT callable->success(result);
break;
}else{
if(i == retry()-1){
onError(callable,status,errorString,result);
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){
Q_EMIT callable->cache(readCache(requestMap));
}
Q_EMIT callable->error(status,errorString,result);
}
}
}
onFinish(callable);
Q_EMIT callable->finish();
// Q_EMIT callable->finish();
});
}
void FluHttp::postString(QString url,QJSValue callable,QString params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"postString").toMap();
void FluHttp::postString(QString url,HttpCallable* callable,QString params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
onStart(callable);
auto requestMap = toRequest(url,params,headers,"postString");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){
Q_EMIT callable->cache(readCache(requestMap));
Q_EMIT callable->finish();
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){
Q_EMIT callable->cache(readCache(requestMap));
}
for (int i = 0; i < retry(); ++i) {
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
@ -94,7 +129,7 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMap<QStri
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(request,params.toUtf8());
_cache.append(reply);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
@ -103,26 +138,39 @@ void FluHttp::postString(QString url,QJSValue callable,QString params,QMap<QStri
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
handleCache(requestMap,result);
Q_EMIT callable->success(result);
break;
}else{
if(i == retry()-1){
onError(callable,status,errorString,result);
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){
Q_EMIT callable->cache(readCache(requestMap));
}
Q_EMIT callable->error(status,errorString,result);
}
}
}
onFinish(callable);
Q_EMIT callable->finish();
});
}
void FluHttp::postJson(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"postJson").toMap();
void FluHttp::postJson(QString url,HttpCallable* callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
onStart(callable);
auto requestMap = toRequest(url,params,headers,"postJson");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){
Q_EMIT callable->cache(readCache(requestMap));
Q_EMIT callable->finish();
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){
Q_EMIT callable->cache(readCache(requestMap));
}
for (int i = 0; i < retry(); ++i) {
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
@ -133,7 +181,7 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap<QString, QVariant> par
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(request,QJsonDocument::fromVariant(data["params"]).toJson());
_cache.append(reply);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
@ -142,27 +190,40 @@ void FluHttp::postJson(QString url,QJSValue callable,QMap<QString, QVariant> par
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
handleCache(requestMap,result);
Q_EMIT callable->success(result);
break;
}else{
if(i == retry()-1){
onError(callable,status,errorString,result);
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){
Q_EMIT callable->cache(readCache(requestMap));
}
Q_EMIT callable->error(status,errorString,result);
}
}
}
onFinish(callable);
Q_EMIT callable->finish();
});
}
void FluHttp::get(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"get").toMap();
QThreadPool::globalInstance()->start([=](){
void FluHttp::get(QString url,HttpCallable* callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
auto requestMap = toRequest(url,params,headers,"get");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest){
Q_EMIT callable->cache(readCache(requestMap));
}
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){
Q_EMIT callable->cache(readCache(requestMap));
Q_EMIT callable->finish();
return;
}
for (int i = 0; i < retry(); ++i) {
onStart(callable);
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
QUrl _url(url);
@ -171,7 +232,7 @@ void FluHttp::get(QString url,QJSValue callable,QMap<QString, QVariant> params,Q
addHeaders(&request,data["headers"].toMap());
QEventLoop loop;
QNetworkReply* reply = manager.get(request);
_cache.append(reply);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
@ -180,26 +241,31 @@ void FluHttp::get(QString url,QJSValue callable,QMap<QString, QVariant> params,Q
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
handleCache(requestMap,result);
Q_EMIT callable->success(result);
break;
}else{
if(i == retry()-1){
onError(callable,status,errorString,result);
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache){
Q_EMIT callable->cache(readCache(requestMap));
}
Q_EMIT callable->error(status,errorString,result);
}
}
}
onFinish(callable);
Q_EMIT callable->finish();
});
}
void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"download").toMap();
void FluHttp::download(QString url,HttpCallable* callable,QString filePath,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
onStart(callable);
auto requestMap = toRequest(url,params,headers,"download");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
QNetworkAccessManager manager;
QUrl _url(url);
addQueryParam(&_url,data["params"].toMap());
@ -209,8 +275,8 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QStri
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode))
{
onError(callable,-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),"");
onFinish(callable);
Q_EMIT callable->error(-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),"");
Q_EMIT callable->finish();
return;
}
QEventLoop loop;
@ -218,28 +284,29 @@ void FluHttp::download(QString url,QJSValue callable,QString filePath,QMap<QStri
loop.quit();
});
QPointer<QNetworkReply> reply = manager.get(request);
_cache.append(reply);
_cacheReply.append(reply);
connect(reply,&QNetworkReply::downloadProgress,this,[=](qint64 bytesReceived, qint64 bytesTotal){
onDownloadProgress(callable,bytesReceived,bytesTotal);
Q_EMIT callable->downloadProgress(bytesReceived,bytesTotal);
});
loop.exec();
if (reply->error() == QNetworkReply::NoError) {
file->write(reply->readAll());
onSuccess(callable,filePath);
Q_EMIT callable->success(filePath);
}else{
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
Q_EMIT callable->error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
}
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
onFinish(callable);
Q_EMIT callable->finish();
});
}
void FluHttp::upload(QString url,QJSValue callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QMap<QString, QVariant> data = invokeIntercept(params,headers,"upload").toMap();
void FluHttp::upload(QString url,HttpCallable* callable,QMap<QString, QVariant> params,QMap<QString, QVariant> headers){
QThreadPool::globalInstance()->start([=](){
onStart(callable);
auto requestMap = toRequest(url,params,headers,"upload");
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
Q_EMIT callable->start();
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
QUrl _url(url);
@ -262,41 +329,46 @@ void FluHttp::upload(QString url,QJSValue callable,QMap<QString, QVariant> param
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,&multiPart);
_cache.append(reply);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
connect(reply,&QNetworkReply::uploadProgress,this,[=](qint64 bytesSent, qint64 bytesTotal){
onUploadProgress(callable,bytesSent,bytesTotal);
Q_EMIT callable->uploadProgress(bytesSent,bytesTotal);
});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
_cache.removeOne(reply);
_cacheReply.removeOne(reply);
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
Q_EMIT callable->success(result);
}else{
onError(callable,status,errorString,result);
Q_EMIT callable->error(status,errorString,result);
}
onFinish(callable);
Q_EMIT callable->finish();
});
}
QVariant FluHttp::invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method){
QMap<QString, QVariant> requet = {
QMap<QString, QVariant> FluHttp::toRequest(const QString& url,const QVariant& params,const QVariant& headers,const QString& method){
QMap<QString, QVariant> request = {
{"url",url},
{"params",params},
{"headers",headers},
{"method",method}
};
return request;
}
QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){
if(!FluApp::getInstance()->httpInterceptor()){
return requet;
return request;
}
QVariant target;
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, requet));
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Qt::BlockingQueuedConnection,Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request));
return target;
}
@ -320,54 +392,44 @@ void FluHttp::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>&
}
}
void FluHttp::onStart(const QJSValue& callable){
MainThread::post([=](){
QJSValue onStart = callable.property("onStart");
onStart.call();
});
QString FluHttp::readCache(const QMap<QString, QVariant>& request){
auto filePath = getCacheFilePath(request);
QString result;
QFile file(filePath);
if(!file.exists()){
return result;
}
if (file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
result = FluTools::getInstance()->fromBase64(stream.readAll().toUtf8());
}
return result;
}
void FluHttp::onFinish(const QJSValue& callable){
MainThread::post([=](){
QJSValue onFinish = callable.property("onFinish");
onFinish.call();
});
bool FluHttp::cacheExists(const QMap<QString, QVariant>& request){
return QFile(getCacheFilePath(request)).exists();
}
void FluHttp::onError(const QJSValue& callable,int status,QString errorString,QString result){
MainThread::post([=](){
QJSValue onError = callable.property("onError");
QJSValueList args;
args<<status<<errorString<<result;
onError.call(args);
});
QString FluHttp::getCacheFilePath(const QMap<QString, QVariant>& request){
auto fileName = FluTools::getInstance()->md5(QJsonDocument::fromVariant(QVariant(request)).toJson());
QDir dir = _cacheDir;
if (!dir.exists(_cacheDir)){
dir.mkpath(_cacheDir);
}
auto filePath = _cacheDir+"/"+fileName;
return filePath;
}
void FluHttp::onSuccess(const QJSValue& callable,QString result){
MainThread::post([=](){
QJSValueList args;
args<<result;
QJSValue onSuccess = callable.property("onSuccess");
onSuccess.call(args);
});
}
void FluHttp::onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total){
MainThread::post([=](){
QJSValueList args;
args<<static_cast<double>(recv);
args<<static_cast<double>(total);
QJSValue onDownloadProgress = callable.property("onDownloadProgress");
onDownloadProgress.call(args);
});
}
void FluHttp::onUploadProgress(const QJSValue& callable,qint64 sent, qint64 total){
MainThread::post([=](){
QJSValueList args;
args<<static_cast<double>(sent);
args<<static_cast<double>(total);
QJSValue onUploadProgress = callable.property("onUploadProgress");
onUploadProgress.call(args);
});
void FluHttp::handleCache(QMap<QString, QVariant> request,const QString& result){
if(_cacheMode==FluHttpType::CacheMode::NoCache){
return;
}
auto filePath = getCacheFilePath(request);
QSharedPointer<QFile> file(new QFile(filePath));
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode))
{
return;
}
file->write(FluTools::getInstance()->toBase64(result).toUtf8());
}

View File

@ -6,37 +6,53 @@
#include <QFile>
#include <QNetworkAccessManager>
#include "stdafx.h"
#include <QMutex>
class HttpCallable : public QObject{
Q_OBJECT
QML_NAMED_ELEMENT(HttpCallable)
public:
explicit HttpCallable(QObject *parent = nullptr);
Q_SIGNAL void start();
Q_SIGNAL void finish();
Q_SIGNAL void error(int status,QString errorString,QString result);
Q_SIGNAL void success(QString result);
Q_SIGNAL void cache(QString result);
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
Q_SIGNAL void uploadProgress(qint64 recv, qint64 total);
};
class FluHttp : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(int,retry);
Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(int,cacheMode);
Q_PROPERTY_AUTO(QString,cacheDir);
QML_NAMED_ELEMENT(FluHttp)
private:
QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method);
QVariant invokeIntercept(QMap<QString, QVariant> request);
QMap<QString, QVariant> toRequest(const QString& url,const QVariant& params,const QVariant& headers,const QString& method);
void handleReply(QNetworkReply* reply);
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
void onStart(const QJSValue& callable);
void onFinish(const QJSValue& callable);
void onError(const QJSValue& callable,int status,QString errorString,QString result);
void onSuccess(const QJSValue& callable,QString result);
void onDownloadProgress(const QJSValue& callable,qint64 recv, qint64 total);
void onUploadProgress(const QJSValue& callable,qint64 recv, qint64 total);
void handleCache(QMap<QString, QVariant> request, const QString& result);
QString readCache(const QMap<QString, QVariant>& request);
bool cacheExists(const QMap<QString, QVariant>& request);
QString getCacheFilePath(const QMap<QString, QVariant>& request);
public:
explicit FluHttp(QObject *parent = nullptr);
~FluHttp();
//神坑!!! 如果参数使用QVariantMap会有问题在6.4.3版本中QML一调用就会编译失败。所以改用QMap<QString, QVariant>
Q_INVOKABLE void get(QString url,QJSValue callable,QMap<QString, QVariant> params= {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void post(QString url,QJSValue callable,QMap<QString, QVariant> params= {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postString(QString url,QJSValue callable,QString params = "",QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postJson(QString url,QJSValue callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void download(QString url,QJSValue callable,QString filePath,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void upload(QString url,QJSValue callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void get(QString url,HttpCallable* callable,QMap<QString, QVariant> params= {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void post(QString url,HttpCallable* callable,QMap<QString, QVariant> params= {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postString(QString url,HttpCallable* callable,QString params = "",QMap<QString, QVariant> headers = {});
Q_INVOKABLE void postJson(QString url,HttpCallable* callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void download(QString url,HttpCallable* callable,QString filePath,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void upload(QString url,HttpCallable* callable,QMap<QString, QVariant> params = {},QMap<QString, QVariant> headers = {});
Q_INVOKABLE void cancel();
private:
QList<QPointer<QNetworkReply>> _cache;
QList<QPointer<QNetworkReply>> _cacheReply;
};
#endif // FLUHTTP_H

View File

@ -31,7 +31,7 @@ FluTheme::FluTheme(QObject *parent)
});
primaryColor(FluColors::getInstance()->Blue());
nativeText(false);
enableAnimation(false);
enableAnimation(true);
darkMode(FluThemeType::DarkMode::Light);
_systemDark = systemDark();
qApp->installEventFilter(this);

View File

@ -6,6 +6,8 @@
#include <QScreen>
#include <QColor>
#include <QFileInfo>
#include <QDir>
#include <QCryptographicHash>
#include <QTextDocument>
FluTools* FluTools::m_instance = nullptr;
@ -128,3 +130,23 @@ QUrl FluTools::getUrlByFilePath(const QString& path){
QColor FluTools::colorAlpha(const QColor& color,qreal alpha){
return QColor(color.red(),color.green(),color.blue(),255*alpha);
}
QString FluTools::md5(QString text)
{
return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Md5).toHex();
}
QString FluTools::toBase64(QString text)
{
return text.toUtf8().toBase64();
}
QString FluTools::fromBase64(QString text)
{
return QByteArray::fromBase64(text.toUtf8());
}
bool FluTools::removeDir(QString dirPath){
QDir qDir(dirPath);
return qDir.removeRecursively();
}

View File

@ -144,6 +144,35 @@ public:
*/
Q_INVOKABLE QColor colorAlpha(const QColor&,qreal alpha);
/**
* @brief md5
* @param text
* @return
*/
Q_INVOKABLE QString md5(QString text);
/**
* @brief toBase64
* @param text
* @return
*/
Q_INVOKABLE QString toBase64(QString text);
/**
* @brief fromBase64
* @param text
* @return
*/
Q_INVOKABLE QString fromBase64(QString text);
/**
* @brief removeDir
* @param dirPath
* @return
*/
Q_INVOKABLE bool removeDir(QString dirPath);
};
#endif // FLUTOOLS_H

View File

@ -752,7 +752,12 @@ Item {
id:nav_stack2
anchors.fill: nav_stack
clip: true
visible: FluPageType.SingleInstance === nav_stack.currentItem.launchMode
visible: {
if(!nav_stack.currentItem){
return false
}
return FluPageType.SingleInstance === nav_stack.currentItem.launchMode
}
}
function navStack(){
return nav_stack

View File

@ -96,24 +96,22 @@ Popup{
ctx.globalCompositeOperation = 'destination-out'
ctx.fillStyle = 'black'
var rect = Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2)
ctx.fillRect(rect.x,rect.y,rect.width,rect.height)
drawRoundedRect(rect,2,ctx)
ctx.restore()
}
//Todo
function drawRoundedRect(rect, r, ctx) {
var ptA = Qt.point(rect.x + r, rect.y)
var ptB = Qt.point(rect.x + rect.width, rect.y)
var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height)
var ptD = Qt.point(rect.x, rect.y + rect.height)
var ptE = Qt.point(rect.x, rect.y)
ctx.beginPath()
ctx.moveTo(ptA.x, ptA.y)
ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r)
ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r)
ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r)
ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r)
ctx.beginPath();
ctx.moveTo(rect.x + r, rect.y);
ctx.lineTo(rect.x + rect.width - r, rect.y);
ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r);
ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r);
ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r);
ctx.lineTo(rect.x + r, rect.y + rect.height);
ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r);
ctx.lineTo(rect.x, rect.y + r);
ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
ctx.closePath();
ctx.fill()
ctx.closePath()
}
}
FluArea{

View File

@ -753,7 +753,12 @@ Item {
id:nav_stack2
anchors.fill: nav_stack
clip: true
visible: FluPageType.SingleInstance === nav_stack.currentItem.launchMode
visible: {
if(!nav_stack.currentItem){
return false
}
return FluPageType.SingleInstance === nav_stack.currentItem.launchMode
}
}
function navStack(){
return nav_stack

View File

@ -89,19 +89,18 @@ Popup{
ctx.restore()
}
function drawRoundedRect(rect, r, ctx) {
var ptA = Qt.point(rect.x + r, rect.y)
var ptB = Qt.point(rect.x + rect.width, rect.y)
var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height)
var ptD = Qt.point(rect.x, rect.y + rect.height)
var ptE = Qt.point(rect.x, rect.y)
ctx.beginPath()
ctx.moveTo(ptA.x, ptA.y)
ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r)
ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r)
ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r)
ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r)
ctx.beginPath();
ctx.moveTo(rect.x + r, rect.y);
ctx.lineTo(rect.x + rect.width - r, rect.y);
ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r);
ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r);
ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r);
ctx.lineTo(rect.x + r, rect.y + rect.height);
ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r);
ctx.lineTo(rect.x, rect.y + r);
ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
ctx.closePath();
ctx.fill()
ctx.closePath()
}
}
FluArea{

View File

@ -38,6 +38,7 @@ void FluentUIPlugin::registerTypes(const char *uri)
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
qmlRegisterType<FluHttpInterceptor>(uri,major,minor,"FluHttpInterceptor");
qmlRegisterType<FluHttp>(uri,major,minor,"FluHttp");
qmlRegisterType<HttpCallable>(uri,major,minor,"HttpCallable");
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluPageType::staticMetaObject, uri,major,minor,"FluPageType", "Access to enums & flags only");