shortcut: icon from entry

This commit is contained in:
Thibault Deckers 2020-09-28 13:43:25 +09:00
parent 8052347895
commit 097a051b37
8 changed files with 40 additions and 15 deletions

View file

@ -38,8 +38,6 @@ import deckers.thibault.aves.utils.Utils;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;
public class AppAdapterHandler implements MethodChannel.MethodCallHandler { public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
private static final String LOG_TAG = Utils.createLogTag(AppAdapterHandler.class); private static final String LOG_TAG = Utils.createLogTag(AppAdapterHandler.class);
@ -184,7 +182,7 @@ public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
FutureTarget<Bitmap> target = Glide.with(context) FutureTarget<Bitmap> target = Glide.with(context)
.asBitmap() .asBitmap()
.apply(options) .apply(options)
.apply(centerCropTransform()) .centerCrop()
.load(uri) .load(uri)
.signature(signature) .signature(signature)
.submit(size, size); .submit(size, size);

View file

@ -2,6 +2,8 @@ package deckers.thibault.aves.channel.calls;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -10,6 +12,9 @@ import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat; import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat; import androidx.core.graphics.drawable.IconCompat;
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool;
import com.bumptech.glide.load.resource.bitmap.TransformationUtils;
import java.util.List; import java.util.List;
import deckers.thibault.aves.MainActivity; import deckers.thibault.aves.MainActivity;
@ -35,8 +40,9 @@ public class AppShortcutHandler implements MethodChannel.MethodCallHandler {
} }
case "pin": { case "pin": {
String label = call.argument("label"); String label = call.argument("label");
byte[] iconBytes = call.argument("iconBytes");
List<String> filters = call.argument("filters"); List<String> filters = call.argument("filters");
pin(label, filters); new Thread(() -> pin(label, iconBytes, filters)).start();
result.success(null); result.success(null);
break; break;
} }
@ -46,17 +52,28 @@ public class AppShortcutHandler implements MethodChannel.MethodCallHandler {
} }
} }
private void pin(String label, @Nullable List<String> filters) { private void pin(String label, byte[] iconBytes, @Nullable List<String> filters) {
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context) || filters == null) { if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context) || filters == null) {
return; return;
} }
IconCompat icon;
if (iconBytes != null && iconBytes.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
bitmap = TransformationUtils.centerCrop(new LruBitmapPool(2 << 24), bitmap, 256, 256);
icon = IconCompat.createWithBitmap(bitmap);
} else {
icon = IconCompat.createWithResource(context, R.mipmap.ic_shortcut_collection);
}
Intent intent = new Intent(Intent.ACTION_MAIN, null, context, MainActivity.class)
.putExtra("page", "/collection")
.putExtra("filters", filters.toArray(new String[0]));
ShortcutInfoCompat shortcut = new ShortcutInfoCompat.Builder(context, "collection-" + TextUtils.join("-", filters)) ShortcutInfoCompat shortcut = new ShortcutInfoCompat.Builder(context, "collection-" + TextUtils.join("-", filters))
.setShortLabel(label) .setShortLabel(label)
.setIcon(IconCompat.createWithResource(context, R.mipmap.ic_shortcut_collection)) .setIcon(icon)
.setIntent(new Intent(Intent.ACTION_MAIN, null, context, MainActivity.class) .setIntent(intent)
.putExtra("page", "/collection")
.putExtra("filters", filters.toArray(new String[0])))
.build(); .build();
ShortcutManagerCompat.requestPinShortcut(context, shortcut, null); ShortcutManagerCompat.requestPinShortcut(context, shortcut, null);

View file

@ -1,4 +1,6 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/services/image_file_service.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -22,10 +24,12 @@ class AppShortcutService {
return false; return false;
} }
static Future<void> pin(String label, Set<CollectionFilter> filters) async { static Future<void> pin(String label, ImageEntry iconEntry, Set<CollectionFilter> filters) async {
final iconBytes = iconEntry != null ? await ImageFileService.getThumbnail(iconEntry, 256, 256) : null;
try { try {
await platform.invokeMethod('pin', <String, dynamic>{ await platform.invokeMethod('pin', <String, dynamic>{
'label': label, 'label': label,
'iconBytes': iconBytes,
'filters': filters.map((filter) => filter.toJson()).toList(), 'filters': filters.map((filter) => filter.toJson()).toList(),
}); });
} on PlatformException catch (e) { } on PlatformException catch (e) {

View file

@ -356,7 +356,8 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
); );
if (name == null || name.isEmpty) return; if (name == null || name.isEmpty) return;
unawaited(AppShortcutService.pin(name, collection.filters)); final iconEntry = collection.sortedEntries.isNotEmpty ? collection.sortedEntries.first : null;
unawaited(AppShortcutService.pin(name, iconEntry, collection.filters));
} }
void _goToSearch() { void _goToSearch() {

View file

@ -87,8 +87,7 @@ class SectionHeader extends StatelessWidget {
// force a higher first line to match leading icon/selector dimension // force a higher first line to match leading icon/selector dimension
style: TextStyle(height: 2.3 * textScaleFactor), style: TextStyle(height: 2.3 * textScaleFactor),
), // 23 hair spaces match a width of 40.0 ), // 23 hair spaces match a width of 40.0
if (hasTrailing) if (hasTrailing) TextSpan(text: '\u200A' * 17),
TextSpan(text: '\u200A' * 17),
TextSpan( TextSpan(
text: text, text: text,
style: Constants.titleTextStyle, style: Constants.titleTextStyle,

View file

@ -43,7 +43,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
labelText: 'Shortcut label', labelText: 'Shortcut label',
), ),
autofocus: true, autofocus: true,
maxLength: 10, maxLength: 25,
onChanged: (_) => _validate(), onChanged: (_) => _validate(),
onSubmitted: (_) => _submit(context), onSubmitted: (_) => _submit(context),
), ),

View file

@ -66,6 +66,7 @@ class ThumbnailProviderKey {
final ImageEntry entry; final ImageEntry entry;
final double extent; final double extent;
final double scale; final double scale;
// do not access `contentId` via `entry` for hashCode and equality purposes // do not access `contentId` via `entry` for hashCode and equality purposes
// as an entry is not constant and its contentId can change // as an entry is not constant and its contentId can change
final int contentId; final int contentId;

View file

@ -75,7 +75,12 @@ class ScaleLayer extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
final center = map.center; final center = map.center;
final latitude = center.latitude.abs(); final latitude = center.latitude.abs();
final level = map.zoom.round() + (latitude > 80 ? 4 : latitude > 60 ? 3 : 2); final level = map.zoom.round() +
(latitude > 80
? 4
: latitude > 60
? 3
: 2);
final distance = scale[max(0, min(20, level))].toDouble(); final distance = scale[max(0, min(20, level))].toDouble();
final start = map.project(center); final start = map.project(center);
final targetPoint = util.calculateEndingGlobalCoordinates(center, 90, distance); final targetPoint = util.calculateEndingGlobalCoordinates(center, 90, distance);