oauth support is almost done
This commit is contained in:
parent
4a23939191
commit
52769238bd
19 changed files with 146 additions and 9 deletions
|
|
@ -22,6 +22,14 @@
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data android:scheme="nexus.federated.nexus" />
|
||||||
|
</intent-filter>
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class AuthUrlController extends AsyncNotifier<OAuthAuthCodeResponse> {
|
||||||
.getAuthUrl(
|
.getAuthUrl(
|
||||||
.new(
|
.new(
|
||||||
homeserverUrl: homeserver,
|
homeserverUrl: homeserver,
|
||||||
redirectUri: .new(scheme: "nexus.federated.nexus"),
|
redirectUri: .new(scheme: "nexus.federated.nexus", path: "/"),
|
||||||
responseMode: .query,
|
responseMode: .query,
|
||||||
scopes: .new([.clientApi]),
|
scopes: .new([.clientApi]),
|
||||||
clientId: await ref.watch(
|
clientId: await ref.watch(
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import "package:nexus/models/requests/get_related_events.dart";
|
||||||
import "package:nexus/models/requests/get_room_state.dart";
|
import "package:nexus/models/requests/get_room_state.dart";
|
||||||
import "package:nexus/models/requests/join_room.dart";
|
import "package:nexus/models/requests/join_room.dart";
|
||||||
import "package:nexus/models/profile.dart";
|
import "package:nexus/models/profile.dart";
|
||||||
|
import "package:nexus/models/requests/oauth/exchange_token.dart";
|
||||||
import "package:nexus/models/requests/oauth/get_auth_url.dart";
|
import "package:nexus/models/requests/oauth/get_auth_url.dart";
|
||||||
import "package:nexus/models/requests/oauth/register_client.dart";
|
import "package:nexus/models/requests/oauth/register_client.dart";
|
||||||
import "package:nexus/models/requests/paginate.dart";
|
import "package:nexus/models/requests/paginate.dart";
|
||||||
|
|
@ -288,6 +289,9 @@ class ClientController extends AsyncNotifier<int> {
|
||||||
await _sendCommand("oauth_get_authorization_url", request.toJson()),
|
await _sendCommand("oauth_get_authorization_url", request.toJson()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Future<void> exchangeToken(OAuthExchangeTokenRequest request) async =>
|
||||||
|
await _sendCommand("oauth_exchange_token", request.toJson());
|
||||||
|
|
||||||
Future<Uri?> discoverHomeserver(Uri homeserver) async {
|
Future<Uri?> discoverHomeserver(Uri homeserver) async {
|
||||||
try {
|
try {
|
||||||
final response = await _sendCommand("discover_homeserver", {
|
final response = await _sendCommand("discover_homeserver", {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ class ClientIdController extends AsyncNotifier<String> {
|
||||||
),
|
),
|
||||||
homeserverUrl: homeserver,
|
homeserverUrl: homeserver,
|
||||||
clientUri: Uri.https("nexus.federated.nexus"),
|
clientUri: Uri.https("nexus.federated.nexus"),
|
||||||
redirectUris: .new([.new(scheme: "nexus.federated.nexus")]),
|
redirectUris: .new([
|
||||||
|
.new(scheme: "nexus.federated.nexus", path: "/"),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ void main() async {
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
ProviderScope(
|
ProviderScope(
|
||||||
|
retry: null,
|
||||||
observers: [
|
observers: [
|
||||||
// Change false to true if you want debug information on provider reloads
|
// Change false to true if you want debug information on provider reloads
|
||||||
// ignore: dead_code
|
// ignore: dead_code
|
||||||
|
|
|
||||||
17
lib/models/requests/oauth/exchange_token.dart
Normal file
17
lib/models/requests/oauth/exchange_token.dart
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
part "exchange_token.freezed.dart";
|
||||||
|
part "exchange_token.g.dart";
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OAuthExchangeTokenRequest with _$OAuthExchangeTokenRequest {
|
||||||
|
const factory OAuthExchangeTokenRequest({
|
||||||
|
required Uri homeserverUrl,
|
||||||
|
required String codeVerifier,
|
||||||
|
required Uri redirectUri,
|
||||||
|
required String code,
|
||||||
|
required String clientId,
|
||||||
|
}) = _OAuthExchangeTokenRequest;
|
||||||
|
|
||||||
|
factory OAuthExchangeTokenRequest.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$OAuthExchangeTokenRequestFromJson(json);
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ class ChatPage extends ConsumerWidget {
|
||||||
final showMembersByDefault = constraints.maxWidth > 1000;
|
final showMembersByDefault = constraints.maxWidth > 1000;
|
||||||
final initComplete = ref.watch(InitCompleteController.provider);
|
final initComplete = ref.watch(InitCompleteController.provider);
|
||||||
final roomId = ref.watch(KeyController.provider(KeyController.roomKey));
|
final roomId = ref.watch(KeyController.provider(KeyController.roomKey));
|
||||||
|
|
||||||
ref.read(EmojiController.provider);
|
ref.read(EmojiController.provider);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
import "package:app_links/app_links.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_hooks/flutter_hooks.dart";
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
import "package:flutter_svg/flutter_svg.dart";
|
import "package:flutter_svg/flutter_svg.dart";
|
||||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
import "package:nexus/controllers/auth_url.dart";
|
import "package:nexus/controllers/auth_url.dart";
|
||||||
import "package:nexus/controllers/client.dart";
|
import "package:nexus/controllers/client.dart";
|
||||||
|
import "package:nexus/controllers/client_id.dart";
|
||||||
import "package:nexus/helpers/launch_helper.dart";
|
import "package:nexus/helpers/launch_helper.dart";
|
||||||
import "package:nexus/main.dart";
|
import "package:nexus/main.dart";
|
||||||
import "package:nexus/models/homeserver.dart";
|
import "package:nexus/models/homeserver.dart";
|
||||||
|
|
@ -48,11 +50,35 @@ class SelectServerPage extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final authUrl = await ref.read(
|
final codeResponse = await ref.watch(
|
||||||
AuthUrlController.provider(newUrl).future,
|
AuthUrlController.provider(newUrl).future,
|
||||||
);
|
);
|
||||||
|
|
||||||
await ref.watch(LaunchHelper.provider).launchUrl(authUrl.url);
|
await ref.watch(LaunchHelper.provider).launchUrl(codeResponse.url);
|
||||||
|
|
||||||
|
AppLinks().uriLinkStream.listen((encodedUri) async {
|
||||||
|
final code = encodedUri.queryParameters["code"];
|
||||||
|
|
||||||
|
if (code != null) {
|
||||||
|
await ref
|
||||||
|
.watch(ClientController.provider.notifier)
|
||||||
|
.exchangeToken(
|
||||||
|
.new(
|
||||||
|
homeserverUrl: newUrl,
|
||||||
|
codeVerifier: codeResponse.codeVerifier,
|
||||||
|
redirectUri: .new(
|
||||||
|
scheme: "nexus.federated.nexus",
|
||||||
|
path: "/",
|
||||||
|
),
|
||||||
|
code: code,
|
||||||
|
clientId: await ref.watch(
|
||||||
|
ClientIdController.provider(newUrl).future,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.onError(showError);
|
||||||
|
}
|
||||||
|
});
|
||||||
// await Navigator.of(context).push(
|
// await Navigator.of(context).push(
|
||||||
// MaterialPageRoute(builder: (_) => LoginPage(homeserver: newUrl)),
|
// MaterialPageRoute(builder: (_) => LoginPage(homeserver: newUrl)),
|
||||||
// );
|
// );
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <dynamic_color/dynamic_color_plugin.h>
|
#include <dynamic_color/dynamic_color_plugin.h>
|
||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
|
#include <gtk/gtk_plugin.h>
|
||||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin.h>
|
#include <media_kit_video/media_kit_video_plugin.h>
|
||||||
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||||
|
|
@ -21,6 +22,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) gtk_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
|
||||||
|
gtk_plugin_register_with_registrar(gtk_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
|
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
|
||||||
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
|
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
dynamic_color
|
dynamic_color
|
||||||
file_selector_linux
|
file_selector_linux
|
||||||
|
gtk
|
||||||
media_kit_libs_linux
|
media_kit_libs_linux
|
||||||
media_kit_video
|
media_kit_video
|
||||||
screen_retriever_linux
|
screen_retriever_linux
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
Name=Nexus
|
Name=Nexus
|
||||||
GenericName=Matrix Client
|
GenericName=Matrix Client
|
||||||
Comment=A simple and user-friendly Matrix client
|
Comment=A simple and user-friendly Matrix client
|
||||||
Exec=nexus
|
Exec=nexus %u
|
||||||
Icon=nexus
|
Icon=nexus
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Chat;Network;InstantMessaging;
|
Categories=Chat;Network;InstantMessaging;
|
||||||
|
MimeType=x-scheme-handler/nexus.federated.nexus;
|
||||||
|
|
@ -23,6 +23,13 @@ static void first_frame_cb(MyApplication* self, FlView *view)
|
||||||
// Implements GApplication::activate.
|
// Implements GApplication::activate.
|
||||||
static void my_application_activate(GApplication* application) {
|
static void my_application_activate(GApplication* application) {
|
||||||
MyApplication* self = MY_APPLICATION(application);
|
MyApplication* self = MY_APPLICATION(application);
|
||||||
|
|
||||||
|
GList* windows = gtk_application_get_windows(GTK_APPLICATION(application));
|
||||||
|
if (windows) {
|
||||||
|
gtk_window_present(GTK_WINDOW(windows->data));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GtkWindow* window =
|
GtkWindow* window =
|
||||||
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
|
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
|
||||||
|
|
||||||
|
|
@ -93,7 +100,7 @@ static gboolean my_application_local_command_line(GApplication* application, gch
|
||||||
g_application_activate(application);
|
g_application_activate(application);
|
||||||
*exit_status = 0;
|
*exit_status = 0;
|
||||||
|
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements GApplication::startup.
|
// Implements GApplication::startup.
|
||||||
|
|
@ -140,6 +147,6 @@ MyApplication* my_application_new() {
|
||||||
|
|
||||||
return MY_APPLICATION(g_object_new(my_application_get_type(),
|
return MY_APPLICATION(g_object_new(my_application_get_type(),
|
||||||
"application-id", APPLICATION_ID,
|
"application-id", APPLICATION_ID,
|
||||||
"flags", G_APPLICATION_NON_UNIQUE,
|
"flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN,
|
||||||
nullptr));
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import app_links
|
||||||
import dynamic_color
|
import dynamic_color
|
||||||
import file_picker
|
import file_picker
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
|
|
@ -18,6 +19,7 @@ import wakelock_plus
|
||||||
import window_manager
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,18 @@
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<!-- abstract name for this URL type (you can leave it blank) -->
|
||||||
|
<string>auth_callback</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<!-- your schemes -->
|
||||||
|
<string>nexus.federated.nexus</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
40
pubspec.lock
40
pubspec.lock
|
|
@ -41,6 +41,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.11"
|
version: "0.13.11"
|
||||||
|
app_links:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: app_links
|
||||||
|
sha256: "3462d9defc61565fde4944858b59bec5be2b9d5b05f20aed190adb3ad08a7abc"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
|
app_links_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: app_links_linux
|
||||||
|
sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
app_links_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: app_links_platform_interface
|
||||||
|
sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
|
app_links_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: app_links_web
|
||||||
|
sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -558,6 +590,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.2"
|
||||||
|
gtk:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: gtk
|
||||||
|
sha256: "4ff85b2a16724029dd9e5bbb5a94b6918f9973f74ba571c949d2002801879cf5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
hooks:
|
hooks:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ dependencies:
|
||||||
m3e_card_list: ^0.1.0
|
m3e_card_list: ^0.1.0
|
||||||
xdg_directories: ^1.1.0
|
xdg_directories: ^1.1.0
|
||||||
package_info_plus: ^9.0.1
|
package_info_plus: ^9.0.1
|
||||||
|
app_links: ^7.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: 2.15.0
|
build_runner: 2.15.0
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <app_links/app_links_plugin_c_api.h>
|
||||||
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
|
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
|
||||||
|
|
@ -15,6 +16,8 @@
|
||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
AppLinksPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
|
||||||
DynamicColorPluginCApiRegisterWithRegistrar(
|
DynamicColorPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
app_links
|
||||||
dynamic_color
|
dynamic_color
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
media_kit_libs_windows_video
|
media_kit_libs_windows_video
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
#include <flutter/dart_project.h>
|
#include <flutter/dart_project.h>
|
||||||
#include <flutter/flutter_view_controller.h>
|
#include <flutter/flutter_view_controller.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include "app_links/app_links_plugin_c_api.h"
|
||||||
#include "flutter_window.h"
|
#include "flutter_window.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||||
_In_ wchar_t *command_line, _In_ int show_command) {
|
_In_ wchar_t *command_line, _In_ int show_command) {
|
||||||
|
// Forward the link to an existing instance, if any, then exit.
|
||||||
|
// You may ignore the result if you need to create another window.
|
||||||
|
if (SendAppLinkToInstance()) {
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
// Attach to console when present (e.g., 'flutter run') or create a
|
// Attach to console when present (e.g., 'flutter run') or create a
|
||||||
// new console when running with a debugger.
|
// new console when running with a debugger.
|
||||||
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
|
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue