Skip to content

Commit

Permalink
build UI and download task
Browse files Browse the repository at this point in the history
  • Loading branch information
JerryFans committed Jan 6, 2022
1 parent 81495ad commit dfbb052
Show file tree
Hide file tree
Showing 13 changed files with 611 additions and 85 deletions.
26 changes: 26 additions & 0 deletions .vscode/dart.json.code-snippets
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();",
" }",
"}",
],
},
}
Binary file added images/test1.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
135 changes: 135 additions & 0 deletions lib/Controller/tiny_image_info_controller.dart
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;
}
}

}
74 changes: 74 additions & 0 deletions lib/Model/tiny_image_info.dart
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;
}
}

38 changes: 38 additions & 0 deletions lib/Model/tiny_image_info_item_view_model.dart
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;
}


}
35 changes: 35 additions & 0 deletions lib/View/image_task_cell.dart
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),
],
),
);
}
}
Loading

0 comments on commit dfbb052

Please sign in to comment.