✨ App shortcuts
This commit is contained in:
@@ -271,6 +271,8 @@ PODS:
|
||||
- PromisesObjC (= 2.4.0)
|
||||
- protocol_handler_ios (0.0.1):
|
||||
- Flutter
|
||||
- quick_actions_ios (0.0.1):
|
||||
- Flutter
|
||||
- receive_sharing_intent (1.8.1):
|
||||
- Flutter
|
||||
- record_ios (1.1.0):
|
||||
@@ -365,6 +367,7 @@ DEPENDENCIES:
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- pointer_interceptor_ios (from `.symlinks/plugins/pointer_interceptor_ios/ios`)
|
||||
- protocol_handler_ios (from `.symlinks/plugins/protocol_handler_ios/ios`)
|
||||
- quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`)
|
||||
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||
- record_ios (from `.symlinks/plugins/record_ios/ios`)
|
||||
- sensors_plus (from `.symlinks/plugins/sensors_plus/ios`)
|
||||
@@ -481,6 +484,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/pointer_interceptor_ios/ios"
|
||||
protocol_handler_ios:
|
||||
:path: ".symlinks/plugins/protocol_handler_ios/ios"
|
||||
quick_actions_ios:
|
||||
:path: ".symlinks/plugins/quick_actions_ios/ios"
|
||||
receive_sharing_intent:
|
||||
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||
record_ios:
|
||||
@@ -567,6 +572,7 @@ SPEC CHECKSUMS:
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
||||
protocol_handler_ios: 59f23ee71f3ec602d67902ca7f669a80957888d5
|
||||
quick_actions_ios: 500fcc11711d9f646739093395c4ae8eec25f779
|
||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||
record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374
|
||||
SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838
|
||||
|
||||
@@ -216,6 +216,8 @@
|
||||
};
|
||||
7310A7D52EB10962002C0FD3 /* Solian Watch App */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
);
|
||||
path = "Solian Watch App";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -757,14 +759,10 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||
@@ -822,14 +820,10 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
@@ -880,14 +874,10 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Solian Watch App/Pods-Solian Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Solian Watch App/Pods-Solian Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Solian Watch App/Pods-Solian Watch App-frameworks.sh\"\n";
|
||||
|
||||
6
ios/Runner/Assets.xcassets/Contents.json
Normal file
6
ios/Runner/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import 'package:island/services/notify.dart';
|
||||
import 'package:island/services/widget_sync_service.dart';
|
||||
import 'package:island/services/timezone.dart';
|
||||
import 'package:island/services/app_intents.dart';
|
||||
import 'package:island/services/quick_actions.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:relative_time/relative_time.dart';
|
||||
@@ -111,6 +112,17 @@ void main() async {
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
talker.info("[QuickActions] Initializing Quick Actions service...");
|
||||
final quickActionsService = QuickActionsService();
|
||||
await quickActionsService.initialize();
|
||||
talker.info("[QuickActions] Quick Actions service is ready!");
|
||||
} catch (err) {
|
||||
talker.error(
|
||||
"[QuickActions] Failed to initialize Quick Actions service... $err",
|
||||
);
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) {
|
||||
|
||||
89
lib/services/quick_actions.dart
Normal file
89
lib/services/quick_actions.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:island/route.dart';
|
||||
import 'package:island/services/event_bus.dart';
|
||||
import 'package:island/talker.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
|
||||
class QuickActionsService {
|
||||
static final QuickActionsService _instance = QuickActionsService._internal();
|
||||
factory QuickActionsService() => _instance;
|
||||
QuickActionsService._internal();
|
||||
|
||||
final QuickActions _quickActions = const QuickActions();
|
||||
bool _initialized = false;
|
||||
|
||||
Future<void> initialize() async {
|
||||
if (kIsWeb || (!Platform.isAndroid && !Platform.isIOS)) {
|
||||
talker.warning(
|
||||
'[QuickActions] Quick Actions only supported on Android and iOS',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_initialized) {
|
||||
talker.info('[QuickActions] Already initialized');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
talker.info('[QuickActions] Initializing Quick Actions...');
|
||||
|
||||
// TODO Add icons for these
|
||||
final shortcuts = <ShortcutItem>[
|
||||
const ShortcutItem(type: 'compose_post', localizedTitle: 'New Post'),
|
||||
const ShortcutItem(type: 'explore', localizedTitle: 'Explore'),
|
||||
const ShortcutItem(type: 'chats', localizedTitle: 'Chats'),
|
||||
const ShortcutItem(
|
||||
type: 'notifications',
|
||||
localizedTitle: 'Notifications',
|
||||
),
|
||||
];
|
||||
|
||||
await _quickActions.initialize(_handleShortcut);
|
||||
await _quickActions.setShortcutItems(shortcuts);
|
||||
|
||||
_initialized = true;
|
||||
talker.info('[QuickActions] Quick Actions initialized successfully');
|
||||
} catch (e, stack) {
|
||||
talker.error('[QuickActions] Initialization failed', e, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
void _handleShortcut(String type) {
|
||||
talker.info('[QuickActions] Shortcut tapped: $type');
|
||||
|
||||
final context = rootNavigatorKey.currentContext;
|
||||
if (context == null) {
|
||||
talker.warning('[QuickActions] Context not available, skipping action');
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'compose_post':
|
||||
eventBus.fire(const ShowComposeSheetEvent());
|
||||
break;
|
||||
|
||||
case 'explore':
|
||||
context.go('/explore');
|
||||
break;
|
||||
|
||||
case 'chats':
|
||||
context.go('/chat');
|
||||
break;
|
||||
|
||||
case 'notifications':
|
||||
context.go('/notifications');
|
||||
break;
|
||||
|
||||
default:
|
||||
talker.warning('[QuickActions] Unknown shortcut type: $type');
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_initialized = false;
|
||||
}
|
||||
}
|
||||
32
pubspec.lock
32
pubspec.lock
@@ -2229,6 +2229,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
quick_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: quick_actions
|
||||
sha256: "7e35dd6a21f5bbd21acf6899039eaf85001a5ac26d52cbd6a8a2814505b90798"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
quick_actions_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_android
|
||||
sha256: "23f04632ada7fc16665d84ba54a0c792c09727e7fda6c989c6e6ba1853aa15dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.27"
|
||||
quick_actions_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_ios
|
||||
sha256: a2e08ceb01f9d26e1b1826b1c4f5da6b7b6bbf61bcbaacd8e93dfff58b91f996
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
quick_actions_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_platform_interface
|
||||
sha256: "1fec7068db5122cd019e9340d3d7be5d36eab099695ef3402c7059ee058329a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
recase:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -38,6 +38,7 @@ dependencies:
|
||||
cupertino_icons: ^1.0.8
|
||||
flutter_hooks: ^0.21.3+1
|
||||
hooks_riverpod: ^3.1.0
|
||||
quick_actions: ^1.0.8
|
||||
go_router: ^17.0.1
|
||||
styled_widget: ^0.4.1
|
||||
shared_preferences: ^2.5.4
|
||||
|
||||
Reference in New Issue
Block a user