shortcut: icon from entry
This commit is contained in:
parent
8052347895
commit
097a051b37
8 changed files with 40 additions and 15 deletions
|
@ -38,8 +38,6 @@ import deckers.thibault.aves.utils.Utils;
|
|||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;
|
||||
|
||||
public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
||||
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)
|
||||
.asBitmap()
|
||||
.apply(options)
|
||||
.apply(centerCropTransform())
|
||||
.centerCrop()
|
||||
.load(uri)
|
||||
.signature(signature)
|
||||
.submit(size, size);
|
||||
|
|
|
@ -2,6 +2,8 @@ package deckers.thibault.aves.channel.calls;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -10,6 +12,9 @@ import androidx.core.content.pm.ShortcutInfoCompat;
|
|||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
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 deckers.thibault.aves.MainActivity;
|
||||
|
@ -35,8 +40,9 @@ public class AppShortcutHandler implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
case "pin": {
|
||||
String label = call.argument("label");
|
||||
byte[] iconBytes = call.argument("iconBytes");
|
||||
List<String> filters = call.argument("filters");
|
||||
pin(label, filters);
|
||||
new Thread(() -> pin(label, iconBytes, filters)).start();
|
||||
result.success(null);
|
||||
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) {
|
||||
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))
|
||||
.setShortLabel(label)
|
||||
.setIcon(IconCompat.createWithResource(context, R.mipmap.ic_shortcut_collection))
|
||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, context, MainActivity.class)
|
||||
.putExtra("page", "/collection")
|
||||
.putExtra("filters", filters.toArray(new String[0])))
|
||||
.setIcon(icon)
|
||||
.setIntent(intent)
|
||||
.build();
|
||||
|
||||
ShortcutManagerCompat.requestPinShortcut(context, shortcut, null);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
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/services.dart';
|
||||
|
||||
|
@ -22,10 +24,12 @@ class AppShortcutService {
|
|||
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 {
|
||||
await platform.invokeMethod('pin', <String, dynamic>{
|
||||
'label': label,
|
||||
'iconBytes': iconBytes,
|
||||
'filters': filters.map((filter) => filter.toJson()).toList(),
|
||||
});
|
||||
} on PlatformException catch (e) {
|
||||
|
|
|
@ -356,7 +356,8 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
);
|
||||
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() {
|
||||
|
|
|
@ -87,8 +87,7 @@ class SectionHeader extends StatelessWidget {
|
|||
// force a higher first line to match leading icon/selector dimension
|
||||
style: TextStyle(height: 2.3 * textScaleFactor),
|
||||
), // 23 hair spaces match a width of 40.0
|
||||
if (hasTrailing)
|
||||
TextSpan(text: '\u200A' * 17),
|
||||
if (hasTrailing) TextSpan(text: '\u200A' * 17),
|
||||
TextSpan(
|
||||
text: text,
|
||||
style: Constants.titleTextStyle,
|
||||
|
|
|
@ -43,7 +43,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
|
|||
labelText: 'Shortcut label',
|
||||
),
|
||||
autofocus: true,
|
||||
maxLength: 10,
|
||||
maxLength: 25,
|
||||
onChanged: (_) => _validate(),
|
||||
onSubmitted: (_) => _submit(context),
|
||||
),
|
||||
|
|
|
@ -66,6 +66,7 @@ class ThumbnailProviderKey {
|
|||
final ImageEntry entry;
|
||||
final double extent;
|
||||
final double scale;
|
||||
|
||||
// do not access `contentId` via `entry` for hashCode and equality purposes
|
||||
// as an entry is not constant and its contentId can change
|
||||
final int contentId;
|
||||
|
|
|
@ -75,7 +75,12 @@ class ScaleLayer extends StatelessWidget {
|
|||
builder: (context, snapshot) {
|
||||
final center = map.center;
|
||||
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 start = map.project(center);
|
||||
final targetPoint = util.calculateEndingGlobalCoordinates(center, 90, distance);
|
||||
|
|
Loading…
Reference in a new issue