forked from JerryFans/TinyPNG4Flutter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
611 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"MakeClass": { | ||
"prefix": "makeClass", | ||
"body": [ | ||
"class ${TM_FILENAME_BASE/(.*)$/${1:/pascalcase}/} {", | ||
" $0", | ||
"}", | ||
], | ||
"description": "NewClass", | ||
}, | ||
"MakerStatelessW": { | ||
"prefix": "makeStatelessW", | ||
"body": [ | ||
"import 'package:flutter/cupertino.dart';", | ||
"import 'package:flutter/material.dart';\n", | ||
"class ${TM_FILENAME_BASE/(.*)$/${1:/pascalcase}/} extends StatelessWidget {", | ||
" final TAG = \"${TM_FILENAME_BASE/(.*)$/${1:/pascalcase}/}\";", | ||
" ${TM_FILENAME_BASE/(.*)$/${1:/pascalcase}/}({Key? key}) : super(key: key);\n", | ||
" @override", | ||
" Widget build(BuildContext context) {", | ||
" return Container();", | ||
" }", | ||
"}", | ||
], | ||
}, | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import 'package:TinyPNG4Flutter/Model/tiny_image_info.dart'; | ||
import 'package:get/get_state_manager/get_state_manager.dart'; | ||
import 'package:TinyPNG4Flutter/Model/tiny_image_info_item_view_model.dart'; | ||
import 'package:get/get.dart'; | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
import 'dart:typed_data'; | ||
import 'package:flutter/services.dart'; | ||
import 'package:dio/dio.dart'; | ||
import 'package:http/http.dart' as http; | ||
import 'package:path_provider_macos/path_provider_macos.dart'; | ||
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; | ||
|
||
class TinyImageInfoController extends GetxController { | ||
|
||
final PathProviderPlatform provider = PathProviderMacOS(); | ||
var taskList = <TinyImageInfoItemViewModel>[].obs; | ||
|
||
void refreshWithFileList(List<File> files) { | ||
var vms = <TinyImageInfoItemViewModel>[]; | ||
files.forEach((element) { | ||
vms.add(TinyImageInfoItemViewModel.file(element)); | ||
}); | ||
vms.forEach((element) { | ||
beginCompressTask(file: element.file); | ||
}); | ||
taskList.addAll(vms); | ||
taskList.refresh(); | ||
} | ||
|
||
void beginCompressTask({required File file}) async { | ||
// var data = await rootBundle.load("images/test1.PNG"); | ||
var data = await file.readAsBytes(); | ||
|
||
var buffer = data.buffer.asUint8List(); | ||
TinyImageInfo? info = await uploadOriginImage(buffer: buffer); | ||
if (info == null) { | ||
//upload fail | ||
return; | ||
} | ||
|
||
String? path = await provider.getDownloadsPath(); | ||
|
||
if (path == null) { | ||
return; | ||
} | ||
|
||
Directory? folder = await createDirectory(path, "tinyPngFlutterOutput"); | ||
|
||
if (folder == null) { return; } | ||
|
||
var compressFile = await createFile(folder.path, file.fileName); | ||
var isSuc = await downloadOutputImage(info,compressFile.path, onReceiveProgress: (count, total) { | ||
print("onReceiveProgress $count, $total"); | ||
},); | ||
print("$isSuc save $compressFile"); | ||
} | ||
|
||
Future<TinyImageInfo?> uploadOriginImage({required Uint8List? buffer}) async { | ||
var url = "api.tinify.com"; | ||
Uri uri = Uri.https(url, "/shrink"); | ||
var apiKey = "Y0v_xtfXJ6bSYkAITkCR6ROVKxw3BJK4"; | ||
var auth = "api:$apiKey"; | ||
var authData = base64Encode(utf8.encode(auth)); | ||
var authorizationHeader = "Basic " + authData; | ||
var headers = { | ||
"Accept": "application/json", | ||
"Authorization": authorizationHeader | ||
}; | ||
var response = await http.post(uri, headers: headers, body: buffer); | ||
if (response.statusCode != 201) { | ||
print("fail code is ${response.statusCode}"); | ||
return null; | ||
} else { | ||
var json = jsonDecode(utf8.decode(response.bodyBytes)); | ||
var jsonString = jsonEncode(json); | ||
print("success json $jsonString"); | ||
return TinyImageInfo.fromJson(json); | ||
} | ||
} | ||
|
||
Future<bool> downloadOutputImage(TinyImageInfo imageInfo, String savePath, {Function(int count, int total)? onReceiveProgress}) async { | ||
String? url = imageInfo.output?.url; | ||
String? type = imageInfo.output?.type; | ||
if (url == null || type == null) { | ||
return false; | ||
} | ||
Uri uri = Uri.parse(url); | ||
var dio = Dio(); | ||
var rsp = await dio.downloadUri( | ||
uri, savePath, | ||
options: Options(headers: {"Accept": type, "Content-Type": "application/json"},), | ||
onReceiveProgress: (count, total) { | ||
onReceiveProgress?.call(count,total); | ||
}, | ||
); | ||
return rsp.statusCode == 200; | ||
} | ||
|
||
Future<File> createFile(String path,String fileName) async { | ||
bool isExist = true; | ||
var filePath = path+"/"+fileName; | ||
var count = 0; | ||
while (true) { | ||
if (count > 0) { | ||
var onlyName = fileName.split(".").first; | ||
var type = fileName.split(".").last; | ||
filePath = path+"/"+onlyName+"_$count"+"."+type; | ||
} | ||
isExist = await File(filePath).exists(); | ||
print("try create path $filePath isExist $isExist"); | ||
if (isExist == false) { | ||
break; | ||
} | ||
count++; | ||
} | ||
return await File(filePath).create(); | ||
} | ||
|
||
Future<Directory?> createDirectory(String path,String directoryName) async { | ||
final filePath = path+"/"+directoryName; | ||
var file = Directory(filePath); | ||
try { | ||
bool exist = await file.exists(); | ||
if (!exist) { | ||
return await file.create(); | ||
} else { | ||
return file; | ||
} | ||
} catch (e) { | ||
return null; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
class TinyImageInfo { | ||
Input? input; | ||
Output? output; | ||
|
||
TinyImageInfo({this.input, this.output}); | ||
|
||
TinyImageInfo.fromJson(Map<String, dynamic> json) { | ||
input = json['input'] != null ? new Input.fromJson(json['input']) : null; | ||
output = | ||
json['output'] != null ? new Output.fromJson(json['output']) : null; | ||
} | ||
|
||
Map<String, dynamic> toJson() { | ||
final Map<String, dynamic> data = new Map<String, dynamic>(); | ||
if (this.input != null) { | ||
data['input'] = this.input!.toJson(); | ||
} | ||
if (this.output != null) { | ||
data['output'] = this.output!.toJson(); | ||
} | ||
return data; | ||
} | ||
} | ||
|
||
class Input { | ||
int? size; | ||
String? type; | ||
|
||
Input({this.size, this.type}); | ||
|
||
Input.fromJson(Map<String, dynamic> json) { | ||
size = json['size']; | ||
type = json['type']; | ||
} | ||
|
||
Map<String, dynamic> toJson() { | ||
final Map<String, dynamic> data = new Map<String, dynamic>(); | ||
data['size'] = this.size; | ||
data['type'] = this.type; | ||
return data; | ||
} | ||
} | ||
|
||
class Output { | ||
int? size; | ||
String? type; | ||
int? width; | ||
int? height; | ||
double? ratio; | ||
String? url; | ||
|
||
Output({this.size, this.type, this.width, this.height, this.ratio, this.url}); | ||
|
||
Output.fromJson(Map<String, dynamic> json) { | ||
size = json['size']; | ||
type = json['type']; | ||
width = json['width']; | ||
height = json['height']; | ||
ratio = json['ratio']; | ||
url = json['url']; | ||
} | ||
|
||
Map<String, dynamic> toJson() { | ||
final Map<String, dynamic> data = new Map<String, dynamic>(); | ||
data['size'] = this.size; | ||
data['type'] = this.type; | ||
data['width'] = this.width; | ||
data['height'] = this.height; | ||
data['ratio'] = this.ratio; | ||
data['url'] = this.url; | ||
return data; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import 'dart:io'; | ||
|
||
import 'tiny_image_info.dart'; | ||
|
||
extension FileExtention on FileSystemEntity{ | ||
String get fileName { | ||
return this.path.split("/").last; | ||
} | ||
} | ||
|
||
enum TinyImageInfoStatus { | ||
uploading, | ||
uploadFail, | ||
downloading, | ||
downloadFail, | ||
success | ||
} | ||
|
||
class TinyImageInfoItemViewModel { | ||
|
||
File file; | ||
String fileName = ""; | ||
String statusInfo = "wait for upload"; | ||
TinyImageInfoStatus status = TinyImageInfoStatus.uploading; | ||
TinyImageInfo? imageInfo; | ||
|
||
set setImageInfo(TinyImageInfo? imageInfo) { | ||
this.imageInfo = imageInfo; | ||
print("setting image info "); | ||
|
||
} | ||
|
||
TinyImageInfoItemViewModel.file(this.file) { | ||
this.fileName = file.fileName; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import 'package:TinyPNG4Flutter/Model/tiny_image_info_item_view_model.dart'; | ||
import 'package:flutter/cupertino.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
class ImageTaskCell extends StatelessWidget { | ||
final TinyImageInfoItemViewModel vm; | ||
|
||
ImageTaskCell({Key? key, required this.vm}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Container( | ||
margin: EdgeInsets.only(left: 15, right: 15), | ||
child: Row( | ||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
children: [ | ||
Row( | ||
children: [ | ||
Image.file( | ||
vm.file, | ||
height: 100, | ||
fit: BoxFit.fitHeight, | ||
), | ||
SizedBox( | ||
width: 5, | ||
), | ||
Text(vm.fileName), | ||
], | ||
), | ||
Text(vm.statusInfo), | ||
], | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.