app shortcuts (WIP)
This commit is contained in:
parent
0c06bf8443
commit
9da57961fc
8 changed files with 121 additions and 35 deletions
|
@ -45,19 +45,20 @@
|
|||
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
|
||||
android:value="false" />
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
@ -65,14 +66,17 @@
|
|||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="vnd.android.cursor.dir/image" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="vnd.android.cursor.dir/image" />
|
||||
|
@ -80,6 +84,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.PICK" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="vnd.android.cursor.dir/image" />
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
package deckers.thibault.aves;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -29,7 +37,7 @@ public class MainActivity extends FlutterActivity {
|
|||
|
||||
public static final String VIEWER_CHANNEL = "deckers.thibault/aves/viewer";
|
||||
|
||||
private Map<String, String> intentDataMap;
|
||||
private Map<String, Object> intentDataMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -69,6 +77,33 @@ public class MainActivity extends FlutterActivity {
|
|||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
setupShortcuts();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
private void setupShortcuts() {
|
||||
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
|
||||
|
||||
Intent searchIntent = new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class);
|
||||
searchIntent.putExtra("page", "search");
|
||||
ShortcutInfo search = new ShortcutInfo.Builder(this, "search")
|
||||
.setShortLabel(getString(R.string.search_shortcut_short_label))
|
||||
.setIcon(Icon.createWithResource(this, R.drawable.ic_outline_search))
|
||||
.setIntent(searchIntent)
|
||||
.build();
|
||||
|
||||
Intent videosIntent = new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class);
|
||||
videosIntent.putExtra("page", "collection");
|
||||
videosIntent.putExtra("filters", new String[]{"anyVideo"});
|
||||
ShortcutInfo videos = new ShortcutInfo.Builder(this, "videos")
|
||||
.setShortLabel(getString(R.string.videos_shortcut_short_label))
|
||||
.setIcon(Icon.createWithResource(this, R.drawable.ic_outline_movie))
|
||||
.setIntent(videosIntent)
|
||||
.build();
|
||||
shortcutManager.setDynamicShortcuts(Arrays.asList(videos, search));
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
|
@ -77,6 +112,15 @@ public class MainActivity extends FlutterActivity {
|
|||
String action = intent.getAction();
|
||||
if (action == null) return;
|
||||
switch (action) {
|
||||
case Intent.ACTION_MAIN:
|
||||
String page = intent.getStringExtra("page");
|
||||
if (page != null) {
|
||||
intentDataMap = new HashMap<>();
|
||||
intentDataMap.put("page", page);
|
||||
String[] filters = intent.getStringArrayExtra("filters");
|
||||
intentDataMap.put("filters", filters != null ? new ArrayList<>(Arrays.asList(filters)) : null);
|
||||
}
|
||||
break;
|
||||
case Intent.ACTION_VIEW:
|
||||
Uri uri = intent.getData();
|
||||
String mimeType = intent.getType();
|
||||
|
|
5
android/app/src/main/res/drawable/ic_outline_movie.xml
Normal file
5
android/app/src/main/res/drawable/ic_outline_movie.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M4,6.47L5.76,10H20v8H4V6.47M22,4h-4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4z"/>
|
||||
</vector>
|
5
android/app/src/main/res/drawable/ic_outline_search.xml
Normal file
5
android/app/src/main/res/drawable/ic_outline_search.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||
</vector>
|
|
@ -1,4 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Aves</string>
|
||||
<string name="search_shortcut_short_label">Search</string>
|
||||
<string name="videos_shortcut_short_label">Videos</string>
|
||||
</resources>
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:aves/widgets/collection/collection_page.dart';
|
||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||
|
||||
enum HomePageSetting { collection, albums }
|
||||
enum HomePageSetting { collection, albums, search }
|
||||
|
||||
extension ExtraHomePageSetting on HomePageSetting {
|
||||
String get name {
|
||||
|
@ -10,6 +10,8 @@ extension ExtraHomePageSetting on HomePageSetting {
|
|||
return 'Collection';
|
||||
case HomePageSetting.albums:
|
||||
return 'Albums';
|
||||
case HomePageSetting.search:
|
||||
return 'Search';
|
||||
default:
|
||||
return toString();
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
Widget _buildAppBarTitle() {
|
||||
if (collection.isBrowsing) {
|
||||
Widget title = Text(
|
||||
AvesApp.mode == AppMode.pick ? 'Select' : 'Collection',
|
||||
AvesApp.mode == AppMode.pick ? 'Pick' : 'Collection',
|
||||
key: Key('appbar-title'),
|
||||
);
|
||||
if (AvesApp.mode == AppMode.main) {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import 'package:aves/main.dart';
|
||||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/model/filters/mime.dart';
|
||||
import 'package:aves/model/image_entry.dart';
|
||||
import 'package:aves/model/mime_types.dart';
|
||||
import 'package:aves/model/settings/home_page.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_lens.dart';
|
||||
|
@ -29,6 +32,8 @@ class HomePage extends StatefulWidget {
|
|||
class _HomePageState extends State<HomePage> {
|
||||
MediaStoreSource _mediaStore;
|
||||
ImageEntry _viewerEntry;
|
||||
HomePageSetting _shortcutPage;
|
||||
List<String> _shortcutFilters;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -77,6 +82,11 @@ class _HomePageState extends State<HomePage> {
|
|||
String pickMimeTypes = intentData['mimeType'];
|
||||
debugPrint('pick mimeType=$pickMimeTypes');
|
||||
break;
|
||||
default:
|
||||
final extraPage = intentData['page'];
|
||||
_shortcutPage = HomePageSetting.values.firstWhere((v) => v.toString().split('.')[1] == extraPage, orElse: () => null);
|
||||
final extraFilters = intentData['filters'];
|
||||
_shortcutFilters = extraFilters != null ? (extraFilters as List).cast<String>() : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,27 +110,43 @@ class _HomePageState extends State<HomePage> {
|
|||
}
|
||||
|
||||
Route _getRedirectRoute() {
|
||||
switch (AvesApp.mode) {
|
||||
case AppMode.view:
|
||||
if (AvesApp.mode == AppMode.view) {
|
||||
return DirectMaterialPageRoute(
|
||||
settings: RouteSettings(name: SingleFullscreenPage.routeName),
|
||||
builder: (_) => SingleFullscreenPage(entry: _viewerEntry),
|
||||
);
|
||||
case AppMode.main:
|
||||
case AppMode.pick:
|
||||
if (_mediaStore != null) {
|
||||
switch (settings.homePage) {
|
||||
}
|
||||
|
||||
HomePageSetting startPage;
|
||||
Iterable<CollectionFilter> filters;
|
||||
if (AvesApp.mode == AppMode.pick) {
|
||||
startPage = HomePageSetting.collection;
|
||||
} else {
|
||||
startPage = _shortcutPage ?? settings.homePage;
|
||||
filters = (_shortcutFilters ?? []).map((filterString) {
|
||||
switch (filterString) {
|
||||
case 'anyVideo':
|
||||
return MimeFilter(MimeTypes.anyVideo);
|
||||
}
|
||||
debugPrint('failed to parse shortcut filter=$filterString');
|
||||
return null;
|
||||
});
|
||||
}
|
||||
switch (startPage) {
|
||||
case HomePageSetting.albums:
|
||||
return DirectMaterialPageRoute(
|
||||
settings: RouteSettings(name: AlbumListPage.routeName),
|
||||
builder: (_) => AlbumListPage(source: _mediaStore),
|
||||
);
|
||||
case HomePageSetting.search:
|
||||
case HomePageSetting.collection:
|
||||
default:
|
||||
return DirectMaterialPageRoute(
|
||||
settings: RouteSettings(name: CollectionPage.routeName),
|
||||
builder: (_) => CollectionPage(
|
||||
CollectionLens(
|
||||
source: _mediaStore,
|
||||
filters: filters,
|
||||
groupFactor: settings.collectionGroupFactor,
|
||||
sortFactor: settings.collectionSortFactor,
|
||||
),
|
||||
|
@ -128,7 +154,4 @@ class _HomePageState extends State<HomePage> {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue