upload avatar on desktop

This commit is contained in:
niuhuan 2022-03-17 17:52:51 +08:00
parent be634e763a
commit 7e742a185a
5 changed files with 155 additions and 2 deletions

View File

@ -50,7 +50,7 @@ class _GamesScreenState extends State<GamesScreen> {
gameCard = GameCard(element); gameCard = GameCard(element);
} else { } else {
wraps.add(Wrap( wraps.add(Wrap(
children: [GameCard(element), gameCard!], children: [GameCard(element), gameCard],
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
)); ));
gameCard = null; gameCard = null;
@ -58,7 +58,7 @@ class _GamesScreenState extends State<GamesScreen> {
} }
if (gameCard != null) { if (gameCard != null) {
wraps.add(Wrap( wraps.add(Wrap(
children: [gameCard!], children: [gameCard],
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
)); ));
} }

View File

@ -0,0 +1,71 @@
import 'dart:io';
import 'dart:ui' as ui;
import 'package:image/image.dart' as image;
import 'package:crop_image/crop_image.dart';
import 'package:flutter/material.dart';
class DesktopCropper extends StatefulWidget {
final String? title;
final double? aspectRatio;
final String file;
const DesktopCropper({
Key? key,
this.title,
this.aspectRatio,
required this.file,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _DesktopCropperState();
}
class _DesktopCropperState extends State<DesktopCropper> {
late final _controller = CropController(
aspectRatio: widget.aspectRatio,
);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? "图片裁剪"),
actions: [
IconButton(onPressed: _finish, icon: const Icon(Icons.done)),
],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: CropImage(
controller: _controller,
image: Image.file(File(widget.file)),
),
),
),
);
}
Future _finish() async {
var cropped = await _controller.croppedBitmap();
var data = await cropped.toByteData(format: ui.ImageByteFormat.png);
if (data != null) {
var u8list = data.buffer.asUint8List();
image.Image? baseSizeImage = image.decodePng(u8list);
if (baseSizeImage != null) {
if (cropped.width > 200) {
baseSizeImage =
image.copyResize(baseSizeImage, height: 200, width: 200);
}
var f = image.encodeJpg(baseSizeImage!);
Navigator.of(context).pop(f);
}
}
}
}

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart'; import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@ -12,6 +13,8 @@ import 'package:pikapika/screens/components/Avatar.dart';
import 'package:pikapika/screens/components/Images.dart'; import 'package:pikapika/screens/components/Images.dart';
import 'package:pikapika/screens/components/ItemBuilder.dart'; import 'package:pikapika/screens/components/ItemBuilder.dart';
import 'DesktopCropper.dart';
const double _cardHeight = 180; const double _cardHeight = 180;
// //
@ -120,6 +123,10 @@ class _UserProfileCardState extends State<UserProfileCard> {
onTap: () async { onTap: () async {
if (Platform.isAndroid || Platform.isIOS) { if (Platform.isAndroid || Platform.isIOS) {
await _updateAvatarPhone(); await _updateAvatarPhone();
} else if (Platform.isMacOS ||
Platform.isWindows ||
Platform.isLinux) {
await _updateAvatarDesktop();
} }
}, },
child: Avatar(profile.avatar, size: 65), child: Avatar(profile.avatar, size: 65),
@ -202,6 +209,29 @@ class _UserProfileCardState extends State<UserProfileCard> {
} }
} }
Future _updateAvatarDesktop() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
);
if (result != null) {
List<int>? buff = await Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return DesktopCropper(
file: result.files.first.path!,
aspectRatio: 1,
title: "裁剪头像",
);
}),
);
if (buff != null) {
var data = base64Encode(buff);
await method.updateAvatar(data);
_reload();
}
}
}
void _reload() { void _reload() {
setState(() { setState(() {
_future = _load(); _future = _load();

View File

@ -8,6 +8,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1+2" version: "1.0.1+2"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.2"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -57,6 +64,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
crop_image:
dependency: "direct main"
description:
name: crop_image
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -64,6 +78,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.2" version: "0.3.2"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -85,6 +106,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
file_picker:
dependency: "direct main"
description:
name: file_picker
url: "https://pub.dartlang.org"
source: hosted
version: "4.5.1"
filesystem_picker: filesystem_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -168,6 +203,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
image:
dependency: "direct main"
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
image_cropper: image_cropper:
dependency: "direct main" dependency: "direct main"
description: description:
@ -446,6 +488,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
xml: xml:
dependency: transitive dependency: transitive
description: description:

View File

@ -45,6 +45,9 @@ dependencies:
modal_bottom_sheet: ^2.0.0 modal_bottom_sheet: ^2.0.0
image_cropper: ^1.5.0 image_cropper: ^1.5.0
image_picker: ^0.8.4+9 image_picker: ^0.8.4+9
file_picker: ^4.5.1
crop_image: ^1.0.2
image: ^3.1.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: