diff --git a/feather/macos/AppDelegate.swift b/feather/macos/AppDelegate.swift new file mode 100644 index 00000000..a1f9c9bd --- /dev/null +++ b/feather/macos/AppDelegate.swift @@ -0,0 +1,43 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Cocoa + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + @IBOutlet weak var window: NSWindow! + + func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + + func applicationWillFinishLaunching(_ notification: Notification) { + NSLog("applicationWillFinishLaunching"); + NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(AppDelegate.handleEvent(_:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)); + } + +// @objc - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +// { +// NSString *param = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; +// } + @objc func handleEvent(_ event: NSAppleEventDescriptor!, withReplyEvent: NSAppleEventDescriptor!) { + let param:String? = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue; + NSLog("Param: %@", param!); + let win:MainWindow = self.window as! MainWindow; + win.flutterViewController.receivedUriLaunch(param!); + } + +} + diff --git a/feather/macos/Assets.xcassets/AppIcon.appiconset/Contents.json b/feather/macos/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..8a213cb7 --- /dev/null +++ b/feather/macos/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,60 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app-icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app-icon_512.png", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/feather/macos/Assets.xcassets/AppIcon.appiconset/app-icon_512.png b/feather/macos/Assets.xcassets/AppIcon.appiconset/app-icon_512.png new file mode 100644 index 00000000..1f1353c7 Binary files /dev/null and b/feather/macos/Assets.xcassets/AppIcon.appiconset/app-icon_512.png differ diff --git a/feather/macos/Base.lproj/MainMenu.xib b/feather/macos/Base.lproj/MainMenu.xib new file mode 100644 index 00000000..28350547 --- /dev/null +++ b/feather/macos/Base.lproj/MainMenu.xib @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/FeatherApp-Bridging-Header.h b/feather/macos/FeatherApp-Bridging-Header.h new file mode 100644 index 00000000..f8f76606 --- /dev/null +++ b/feather/macos/FeatherApp-Bridging-Header.h @@ -0,0 +1,18 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import +#import +#import diff --git a/feather/macos/FeatherApp.xcodeproj/project.pbxproj b/feather/macos/FeatherApp.xcodeproj/project.pbxproj new file mode 100644 index 00000000..c34093fd --- /dev/null +++ b/feather/macos/FeatherApp.xcodeproj/project.pbxproj @@ -0,0 +1,489 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Build Flutter Bundle" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Build Flutter Bundle"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainWindow.swift */; }; + 33CC112F204626C80003C045 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC112C20461AD40003C045 /* flutter_assets */; }; + 4D277AAF21AE332C00D39356 /* FlutterEmbedderMenubar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D277AAB21AE332C00D39356 /* FlutterEmbedderMenubar.framework */; }; + 4D277AB121AE332C00D39356 /* FlutterEmbedderColorPanel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D277AAD21AE332C00D39356 /* FlutterEmbedderColorPanel.framework */; }; + 4D277AB221AE332C00D39356 /* FlutterEmbedderFileChooser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D277AAE21AE332C00D39356 /* FlutterEmbedderFileChooser.framework */; }; + 4D277AB321AE333A00D39356 /* FlutterEmbedderColorPanel.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 4D277AAD21AE332C00D39356 /* FlutterEmbedderColorPanel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4D277AB421AE333A00D39356 /* FlutterEmbedderFileChooser.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 4D277AAE21AE332C00D39356 /* FlutterEmbedderFileChooser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4D277AB621AE333A00D39356 /* FlutterEmbedderMenubar.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 4D277AAB21AE332C00D39356 /* FlutterEmbedderMenubar.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4DCE8BBE2162667F003A471F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4DCE8BBC2162667F003A471F /* InfoPlist.strings */; }; + 4DD3B527213CB7EE009C4DBB /* SignInView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4DD3B526213CB7EE009C4DBB /* SignInView.xib */; }; + 4DD3B529213CB8CC009C4DBB /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DD3B528213CB8CC009C4DBB /* SignInView.swift */; }; + 4DFA41C421AF86FE00052B11 /* FlutterEmbedderMacFeather.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DFA41C321AF86FE00052B11 /* FlutterEmbedderMacFeather.framework */; }; + 4DFA41C621AF883700052B11 /* FlutterEmbedder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DFA41C521AF883700052B11 /* FlutterEmbedder.framework */; }; + 4DFA41C721AF88D000052B11 /* FlutterEmbedder.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 4DFA41C521AF883700052B11 /* FlutterEmbedder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4DFA41C821AF88D000052B11 /* FlutterEmbedderMacFeather.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 4DFA41C321AF86FE00052B11 /* FlutterEmbedderMacFeather.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 4DFA41C721AF88D000052B11 /* FlutterEmbedder.framework in Bundle Framework */, + 4DFA41C821AF88D000052B11 /* FlutterEmbedderMacFeather.framework in Bundle Framework */, + 4D277AB321AE333A00D39356 /* FlutterEmbedderColorPanel.framework in Bundle Framework */, + 4D277AB421AE333A00D39356 /* FlutterEmbedderFileChooser.framework in Bundle Framework */, + 4D277AB621AE333A00D39356 /* FlutterEmbedderMenubar.framework in Bundle Framework */, + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 33CC10ED2044A3C60003C045 /* FeatherApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = FeatherApp.app; path = "app_9vzIF7brk1rN.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindow.swift; sourceTree = ""; }; + 33CC11162044C3600003C045 /* FeatherApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FeatherApp-Bridging-Header.h"; sourceTree = ""; }; + 33CC112C20461AD40003C045 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = ../../build/flutter_assets; sourceTree = ""; }; + 4D277AAB21AE332C00D39356 /* FlutterEmbedderMenubar.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FlutterEmbedderMenubar.framework; sourceTree = ""; }; + 4D277AAD21AE332C00D39356 /* FlutterEmbedderColorPanel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FlutterEmbedderColorPanel.framework; sourceTree = ""; }; + 4D277AAE21AE332C00D39356 /* FlutterEmbedderFileChooser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FlutterEmbedderFileChooser.framework; sourceTree = ""; }; + 4DCE8BBB216265FE003A471F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = ""; }; + 4DCE8BBD2162667F003A471F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 4DD3B526213CB7EE009C4DBB /* SignInView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SignInView.xib; sourceTree = ""; }; + 4DD3B528213CB8CC009C4DBB /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; + 4DFA41C321AF86FE00052B11 /* FlutterEmbedderMacFeather.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FlutterEmbedderMacFeather.framework; sourceTree = ""; }; + 4DFA41C521AF883700052B11 /* FlutterEmbedder.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FlutterEmbedder.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D277AAF21AE332C00D39356 /* FlutterEmbedderMenubar.framework in Frameworks */, + 4DFA41C421AF86FE00052B11 /* FlutterEmbedderMacFeather.framework in Frameworks */, + 4DFA41C621AF883700052B11 /* FlutterEmbedder.framework in Frameworks */, + 4D277AB221AE332C00D39356 /* FlutterEmbedderFileChooser.framework in Frameworks */, + 4D277AB121AE332C00D39356 /* FlutterEmbedderColorPanel.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 4DD3B526213CB7EE009C4DBB /* SignInView.xib */, + 4DD3B528213CB8CC009C4DBB /* SignInView.swift */, + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainWindow.swift */, + 33CC11162044C3600003C045 /* FeatherApp-Bridging-Header.h */, + 33CC11242044D66E0003C045 /* Resources */, + 33CC10EE2044A3C60003C045 /* Products */, + 4DFA41C521AF883700052B11 /* FlutterEmbedder.framework */, + 4DFA41C321AF86FE00052B11 /* FlutterEmbedderMacFeather.framework */, + 4D277AAD21AE332C00D39356 /* FlutterEmbedderColorPanel.framework */, + 4D277AAE21AE332C00D39356 /* FlutterEmbedderFileChooser.framework */, + 4D277AAB21AE332C00D39356 /* FlutterEmbedderMenubar.framework */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* FeatherApp.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 4DCE8BBC2162667F003A471F /* InfoPlist.strings */, + 33CC10F72044A3C60003C045 /* Info.plist */, + 33CC112C20461AD40003C045 /* flutter_assets */, + ); + name = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* FeatherApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "FeatherApp" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = FeatherApp; + productName = FeatherApp; + productReference = 33CC10ED2044A3C60003C045 /* FeatherApp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 0920; + ProvisioningStyle = Manual; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "FeatherApp" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* FeatherApp */, + 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + 4DD3B527213CB7EE009C4DBB /* SignInView.xib in Resources */, + 33CC112F204626C80003C045 /* flutter_assets in Resources */, + 4DCE8BBE2162667F003A471F /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$PROJECT_DIR\"/../..\n/Users/rainvisitor/flutter/bin/flutter build bundle"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DD3B529213CB8CC009C4DBB /* SignInView.swift in Sources */, + 33CC11132044BFA00003C045 /* MainWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + 4DCE8BBB216265FE003A471F /* en */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; + 4DCE8BBC2162667F003A471F /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 4DCE8BBD2162667F003A471F /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10.5; + PRODUCT_BUNDLE_IDENTIFIER = "com.feather-apps.app-9vzIF7brk1rN"; + PRODUCT_NAME = "app_9vzIF7brk1rN"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "FeatherApp-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10.5; + PRODUCT_BUNDLE_IDENTIFIER = "com.feather-apps.app-9vzIF7brk1rN"; + PRODUCT_NAME = "app_9vzIF7brk1rN"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "FeatherApp-Bridging-Header.h"; + SWIFT_VERSION = 4.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "FeatherApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "FeatherApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Build Flutter Bundle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata.gz b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata.gz new file mode 100644 index 00000000..2c8dfd23 Binary files /dev/null and b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata.gz differ diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..cb171f27 Binary files /dev/null and b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate.gz b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate.gz new file mode 100644 index 00000000..3a3ee82a Binary files /dev/null and b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/mark.xcuserdatad/UserInterfaceState.xcuserstate.gz differ diff --git a/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/rainvisitor.xcuserdatad/UserInterfaceState.xcuserstate b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/rainvisitor.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..ecdd03c6 Binary files /dev/null and b/feather/macos/FeatherApp.xcodeproj/project.xcworkspace/xcuserdata/rainvisitor.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/feather/macos/FeatherApp.xcodeproj/xcuserdata/rainvisitor.xcuserdatad/xcschemes/xcschememanagement.plist b/feather/macos/FeatherApp.xcodeproj/xcuserdata/rainvisitor.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..dbe51319 --- /dev/null +++ b/feather/macos/FeatherApp.xcodeproj/xcuserdata/rainvisitor.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + Build Flutter Bundle.xcscheme_^#shared#^_ + + orderHint + 1 + + FeatherApp.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/feather/macos/FlutterEmbedder.framework/FlutterEmbedder b/feather/macos/FlutterEmbedder.framework/FlutterEmbedder new file mode 120000 index 00000000..349bcbf6 --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/FlutterEmbedder @@ -0,0 +1 @@ +Versions/Current/FlutterEmbedder \ No newline at end of file diff --git a/feather/macos/FlutterEmbedder.framework/Headers b/feather/macos/FlutterEmbedder.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/feather/macos/FlutterEmbedder.framework/Modules b/feather/macos/FlutterEmbedder.framework/Modules new file mode 120000 index 00000000..5736f318 --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/feather/macos/FlutterEmbedder.framework/Resources b/feather/macos/FlutterEmbedder.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/feather/macos/FlutterEmbedder.framework/Versions/A/FlutterEmbedder b/feather/macos/FlutterEmbedder.framework/Versions/A/FlutterEmbedder new file mode 100755 index 00000000..20701e1e Binary files /dev/null and b/feather/macos/FlutterEmbedder.framework/Versions/A/FlutterEmbedder differ diff --git a/feather/macos/FlutterEmbedder.framework/Versions/A/Headers/FlutterEmbedder.h b/feather/macos/FlutterEmbedder.framework/Versions/A/Headers/FlutterEmbedder.h new file mode 100644 index 00000000..d1a997ae --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Versions/A/Headers/FlutterEmbedder.h @@ -0,0 +1,335 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_H_ +#define FLUTTER_EMBEDDER_H_ + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifndef FLUTTER_EXPORT +#define FLUTTER_EXPORT +#endif // FLUTTER_EXPORT + +#define FLUTTER_ENGINE_VERSION 1 + +typedef enum { + kSuccess = 0, + kInvalidLibraryVersion, + kInvalidArguments, + kInternalInconsistency, +} FlutterEngineResult; + +typedef enum { + kOpenGL, + kSoftware, +} FlutterRendererType; + +typedef struct _FlutterEngine* FlutterEngine; + +typedef struct { + // horizontal scale factor + double scaleX; + // horizontal skew factor + double skewX; + // horizontal translation + double transX; + // vertical skew factor + double skewY; + // vertical scale factor + double scaleY; + // vertical translation + double transY; + // input x-axis perspective factor + double pers0; + // input y-axis perspective factor + double pers1; + // perspective scale factor + double pers2; +} FlutterTransformation; + +typedef void (*VoidCallback)(void* /* user data */); + +typedef struct { + // Target texture of the active texture unit (example GL_TEXTURE_2D). + uint32_t target; + // The name of the texture. + uint32_t name; + // The texture format (example GL_RGBA8). + uint32_t format; + // User data to be returned on the invocation of the destruction callback. + void* user_data; + // Callback invoked (on an engine managed thread) that asks the embedder to + // collect the texture. + VoidCallback destruction_callback; +} FlutterOpenGLTexture; + +typedef bool (*BoolCallback)(void* /* user data */); +typedef FlutterTransformation (*TransformationCallback)(void* /* user data */); +typedef uint32_t (*UIntCallback)(void* /* user data */); +typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */, + const void* /* allocation */, + size_t /* row bytes */, + size_t /* height */); +typedef void* (*ProcResolver)(void* /* user data */, const char* /* name */); +typedef bool (*TextureFrameCallback)(void* /* user data */, + int64_t /* texture identifier */, + size_t /* width */, + size_t /* height */, + FlutterOpenGLTexture* /* texture out */); + +typedef struct { + // The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig). + size_t struct_size; + BoolCallback make_current; + BoolCallback clear_current; + BoolCallback present; + UIntCallback fbo_callback; + // This is an optional callback. Flutter will ask the emebdder to create a GL + // context current on a background thread. If the embedder is able to do so, + // Flutter will assume that this context is in the same sharegroup as the main + // rendering context and use this context for asynchronous texture uploads. + // Though optional, it is recommended that all embedders set this callback as + // it will lead to better performance in texture handling. + BoolCallback make_resource_current; + // By default, the renderer config assumes that the FBO does not change for + // the duration of the engine run. If this argument is true, the + // engine will ask the embedder for an updated FBO target (via an fbo_callback + // invocation) after a present call. + bool fbo_reset_after_present; + // The transformation to apply to the render target before any rendering + // operations. This callback is optional. + TransformationCallback surface_transformation; + ProcResolver gl_proc_resolver; + // When the embedder specifies that a texture has a frame available, the + // engine will call this method (on an internal engine managed thread) so that + // external texture details can be supplied to the engine for subsequent + // composition. + TextureFrameCallback gl_external_texture_frame_callback; +} FlutterOpenGLRendererConfig; + +typedef struct { + // The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig). + size_t struct_size; + // The callback presented to the embedder to present a fully populated buffer + // to the user. The pixel format of the buffer is the native 32-bit RGBA + // format. The buffer is owned by the Flutter engine and must be copied in + // this callback if needed. + SoftwareSurfacePresentCallback surface_present_callback; +} FlutterSoftwareRendererConfig; + +typedef struct { + FlutterRendererType type; + union { + FlutterOpenGLRendererConfig open_gl; + FlutterSoftwareRendererConfig software; + }; +} FlutterRendererConfig; + +typedef struct { + // The size of this struct. Must be sizeof(FlutterWindowMetricsEvent). + size_t struct_size; + // Physical width of the window. + size_t width; + // Physical height of the window. + size_t height; + // Scale factor for the physical screen. + double pixel_ratio; +} FlutterWindowMetricsEvent; + +typedef enum { + kCancel, + kUp, + kDown, + kMove, +} FlutterPointerPhase; + +typedef struct { + // The size of this struct. Must be sizeof(FlutterPointerEvent). + size_t struct_size; + FlutterPointerPhase phase; + size_t timestamp; // in microseconds. + double x; + double y; + // An optional device identifier. If this is not specified, it is assumed that + // the embedder has no multitouch capability. + int32_t device; +} FlutterPointerEvent; + +struct _FlutterPlatformMessageResponseHandle; +typedef struct _FlutterPlatformMessageResponseHandle + FlutterPlatformMessageResponseHandle; + +typedef struct { + // The size of this struct. Must be sizeof(FlutterPlatformMessage). + size_t struct_size; + const char* channel; + const uint8_t* message; + const size_t message_size; + // The response handle on which to invoke + // |FlutterEngineSendPlatformMessageResponse| when the response is ready. This + // field is ignored for messages being sent from the embedder to the + // framework. If the embedder ever receives a message with a non-null response + // handle, that handle must always be used with a + // |FlutterEngineSendPlatformMessageResponse| call. If not, this is a memory + // leak. It is not safe to send multiple responses on a single response + // object. + const FlutterPlatformMessageResponseHandle* response_handle; +} FlutterPlatformMessage; + +typedef void (*FlutterPlatformMessageCallback)( + const FlutterPlatformMessage* /* message*/, + void* /* user data */); + +typedef struct { + // The size of this struct. Must be sizeof(FlutterProjectArgs). + size_t struct_size; + // The path to the Flutter assets directory containing project assets. The + // string can be collected after the call to |FlutterEngineRun| returns. The + // string must be NULL terminated. + const char* assets_path; + // The path to the Dart file containing the |main| entry point. + // The string can be collected after the call to |FlutterEngineRun| returns. + // The string must be NULL terminated. + // + // \deprecated As of Dart 2, running from Dart source is no longer supported. + // Dart code should now be compiled to kernel form and will be loaded by from + // |kernel_blob.bin| in the assets directory. This struct member is retained + // for ABI stability. + const char* main_path__unused__; + // The path to the |.packages| for the project. The string can be collected + // after the call to |FlutterEngineRun| returns. The string must be NULL + // terminated. + // + // \deprecated As of Dart 2, running from Dart source is no longer supported. + // Dart code should now be compiled to kernel form and will be loaded by from + // |kernel_blob.bin| in the assets directory. This struct member is retained + // for ABI stability. + const char* packages_path__unused__; + // The path to the icudtl.dat file for the project. The string can be + // collected after the call to |FlutterEngineRun| returns. The string must + // be NULL terminated. + const char* icu_data_path; + // The command line argument count used to initialize the project. + int command_line_argc; + // The command line arguments used to initialize the project. The strings can + // be collected after the call to |FlutterEngineRun| returns. The strings must + // be NULL terminated. + // Note: The first item in the command line (if specificed at all) is + // interpreted as the executable name. So if an engine flag needs to be passed + // into the same, it needs to not be the very first item in the list. The set + // of engine flags are only meant to control unstable features in the engine. + // Deployed applications should not pass any command line arguments at all as + // they may affect engine stability at runtime in the presence of unsanitized + // input. The list of currently recognized engine flags and their descriptions + // can be retrieved from the |switches.h| engine source file. + const char* const* command_line_argv; + // The callback invoked by the engine in order to give the embedder the chance + // to respond to platform messages from the Dart application. The callback + // will be invoked on the thread on which the |FlutterEngineRun| call is made. + FlutterPlatformMessageCallback platform_message_callback; + // The VM snapshot data buffer used in AOT operation. This buffer must be + // mapped in as read-only. For more information refer to the documentation on + // the Wiki at + // https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode + const uint8_t* vm_snapshot_data; + // The size of the VM snapshot data buffer. + size_t vm_snapshot_data_size; + // The VM snapshot instructions buffer used in AOT operation. This buffer must + // be mapped in as read-execute. For more information refer to the + // documentation on the Wiki at + // https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode + const uint8_t* vm_snapshot_instructions; + // The size of the VM snapshot instructions buffer. + size_t vm_snapshot_instructions_size; + // The isolate snapshot data buffer used in AOT operation. This buffer must be + // mapped in as read-only. For more information refer to the documentation on + // the Wiki at + // https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode + const uint8_t* isolate_snapshot_data; + // The size of the isolate snapshot data buffer. + size_t isolate_snapshot_data_size; + // The isolate snapshot instructions buffer used in AOT operation. This buffer + // must be mapped in as read-execute. For more information refer to the + // documentation on the Wiki at + // https://github.com/flutter/flutter/wiki/Flutter-engine-operation-in-AOT-Mode + const uint8_t* isolate_snapshot_instructions; + // The size of the isolate snapshot instructions buffer. + size_t isolate_snapshot_instructions_size; + // The callback invoked by the engine in root isolate scope. Called + // immediately after the root isolate has been created and marked runnable. + VoidCallback root_isolate_create_callback; +} FlutterProjectArgs; + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineRun(size_t version, + const FlutterRendererConfig* config, + const FlutterProjectArgs* args, + void* user_data, + FlutterEngine* engine_out); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineShutdown(FlutterEngine engine); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendWindowMetricsEvent( + FlutterEngine engine, + const FlutterWindowMetricsEvent* event); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendPointerEvent( + FlutterEngine engine, + const FlutterPointerEvent* events, + size_t events_count); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendPlatformMessage( + FlutterEngine engine, + const FlutterPlatformMessage* message); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendPlatformMessageResponse( + FlutterEngine engine, + const FlutterPlatformMessageResponseHandle* handle, + const uint8_t* data, + size_t data_length); + +// This API is only meant to be used by platforms that need to flush tasks on a +// message loop not controlled by the Flutter engine. This API will be +// deprecated soon. +FLUTTER_EXPORT +FlutterEngineResult __FlutterEngineFlushPendingTasksNow(); + +// Register an external texture with a unique (per engine) identifier. Only +// rendering backends that support external textures accept external texture +// registrations. After the external texture is registered, the application can +// mark that a frame is available by calling +// |FlutterEngineMarkExternalTextureFrameAvailable|. +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineRegisterExternalTexture( + FlutterEngine engine, + int64_t texture_identifier); + +// Unregister a previous texture registration. +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineUnregisterExternalTexture( + FlutterEngine engine, + int64_t texture_identifier); + +// Mark that a new texture frame is available for a given texture identifier. +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable( + FlutterEngine engine, + int64_t texture_identifier); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_EMBEDDER_H_ diff --git a/feather/macos/FlutterEmbedder.framework/Versions/A/Modules/module.modulemap b/feather/macos/FlutterEmbedder.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 00000000..60328fe1 --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module FlutterEmbedder { + umbrella header "FlutterEmbedder.h" + + export * + module * { export * } +} diff --git a/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/Info.plist b/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..02a4027b --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + FlutterEmbedder + CFBundleIdentifier + io.flutter.flutter-embedder + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FlutterEmbedder + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright 2013 The Flutter Authors. All rights reserved. + + diff --git a/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/icudtl.dat b/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/icudtl.dat new file mode 100644 index 00000000..d9677abf Binary files /dev/null and b/feather/macos/FlutterEmbedder.framework/Versions/A/Resources/icudtl.dat differ diff --git a/feather/macos/FlutterEmbedder.framework/Versions/Current b/feather/macos/FlutterEmbedder.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/feather/macos/FlutterEmbedder.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/FlutterEmbedderColorPanel b/feather/macos/FlutterEmbedderColorPanel.framework/FlutterEmbedderColorPanel new file mode 120000 index 00000000..12360a77 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/FlutterEmbedderColorPanel @@ -0,0 +1 @@ +Versions/Current/FlutterEmbedderColorPanel \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Headers b/feather/macos/FlutterEmbedderColorPanel.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Modules b/feather/macos/FlutterEmbedderColorPanel.framework/Modules new file mode 120000 index 00000000..5736f318 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Resources b/feather/macos/FlutterEmbedderColorPanel.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/FlutterEmbedderColorPanel b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/FlutterEmbedderColorPanel new file mode 100755 index 00000000..851ed1c8 Binary files /dev/null and b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/FlutterEmbedderColorPanel differ diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FLEColorPanelPlugin.h b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FLEColorPanelPlugin.h new file mode 100644 index 00000000..4fb9fb62 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FLEColorPanelPlugin.h @@ -0,0 +1,26 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import + +/** + * A FlutterPlugin to manage macOS's shared NSColorPanel singleton. Owned by + * the FlutterViewController. Responsible for managing the panel's display state + * and sending selected color data to Flutter, via system channels. + */ +@interface FLEColorPanelPlugin : NSObject + +@end diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FlutterEmbedderColorPanel.h b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FlutterEmbedderColorPanel.h new file mode 100644 index 00000000..72a5d25c --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Headers/FlutterEmbedderColorPanel.h @@ -0,0 +1,15 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "FLEColorPanelPlugin.h" diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Modules/module.modulemap b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 00000000..e052ed19 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module FlutterEmbedderColorPanel { + umbrella header "FlutterEmbedderColorPanel.h" + + export * + module * { export * } +} diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Resources/Info.plist b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..20c61cf5 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,42 @@ + + + + + BuildMachineOSBuild + 17G65 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FlutterEmbedderColorPanel + CFBundleIdentifier + com.google.FlutterEmbedderColorPanel + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FlutterEmbedderColorPanel + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 9B55 + DTPlatformVersion + GM + DTSDKBuild + 17B41 + DTSDKName + macosx10.13 + DTXcode + 0910 + DTXcodeBuild + 9B55 + + diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/_CodeSignature/CodeResources b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/_CodeSignature/CodeResources new file mode 100644 index 00000000..b33eb0c3 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/A/_CodeSignature/CodeResources @@ -0,0 +1,165 @@ + + + + + files + + Resources/Info.plist + + lDWm2lz41WlzGN5GVYKvN+Dvg+A= + + + files2 + + Headers/FLEColorPanelPlugin.h + + hash + + wuYMqqm06LBgmR/Ryy9/Z76sWyE= + + hash2 + + THw4AdeLFpGVSncji7AHKFk3BZs/uWYnG3X/ip4G2io= + + + Headers/FlutterEmbedderColorPanel.h + + hash + + krDdd7Gn+4ZVxmqeHp0dRPJaq8Q= + + hash2 + + TLGm5riwPKF0UZ8yWaUqdPbWfNy7XLI+asTJducj6aI= + + + Modules/module.modulemap + + hash + + 3DztYnKLgja5CAHFjd3fYwXp6+c= + + hash2 + + +MMHNdRhUj3gYt6OzL5zUV10MUCh+DnwJmOq5FIk5RM= + + + Resources/Info.plist + + hash + + lDWm2lz41WlzGN5GVYKvN+Dvg+A= + + hash2 + + nw0NStaK1D1TzCo0Gi5XptdKHK9QNssgzaiopFSdmNI= + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/feather/macos/FlutterEmbedderColorPanel.framework/Versions/Current b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/feather/macos/FlutterEmbedderColorPanel.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/FlutterEmbedderFileChooser b/feather/macos/FlutterEmbedderFileChooser.framework/FlutterEmbedderFileChooser new file mode 120000 index 00000000..0a7908f4 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/FlutterEmbedderFileChooser @@ -0,0 +1 @@ +Versions/Current/FlutterEmbedderFileChooser \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Headers b/feather/macos/FlutterEmbedderFileChooser.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Modules b/feather/macos/FlutterEmbedderFileChooser.framework/Modules new file mode 120000 index 00000000..5736f318 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Resources b/feather/macos/FlutterEmbedderFileChooser.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/FlutterEmbedderFileChooser b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/FlutterEmbedderFileChooser new file mode 100755 index 00000000..6ff04aac Binary files /dev/null and b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/FlutterEmbedderFileChooser differ diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FLEFileChooserPlugin.h b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FLEFileChooserPlugin.h new file mode 100644 index 00000000..7473ab37 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FLEFileChooserPlugin.h @@ -0,0 +1,26 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import + +/** + * A FlutterPlugin to handle file choosing affordances. Owned by the FlutterViewController. + * Responsible for creating and showing instances of NSSavePanel or NSOpenPanel and sending + * selected file paths to flutter clients, via system channels. + */ +@interface FLEFileChooserPlugin : NSObject + +@end diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FlutterEmbedderFileChooser.h b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FlutterEmbedderFileChooser.h new file mode 100644 index 00000000..07b8f2be --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Headers/FlutterEmbedderFileChooser.h @@ -0,0 +1,15 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "FLEFileChooserPlugin.h" diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Modules/module.modulemap b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 00000000..16c92b80 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module FlutterEmbedderFileChooser { + umbrella header "FlutterEmbedderFileChooser.h" + + export * + module * { export * } +} diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Resources/Info.plist b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..395c4ada --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,42 @@ + + + + + BuildMachineOSBuild + 17G65 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FlutterEmbedderFileChooser + CFBundleIdentifier + com.google.FlutterEmbedderFileChooser + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FlutterEmbedderFileChooser + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 9B55 + DTPlatformVersion + GM + DTSDKBuild + 17B41 + DTSDKName + macosx10.13 + DTXcode + 0910 + DTXcodeBuild + 9B55 + + diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/_CodeSignature/CodeResources b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/_CodeSignature/CodeResources new file mode 100644 index 00000000..3a83a983 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/A/_CodeSignature/CodeResources @@ -0,0 +1,165 @@ + + + + + files + + Resources/Info.plist + + DFRRJ1XNFr8hsTcRjUFgl4ry8Yk= + + + files2 + + Headers/FLEFileChooserPlugin.h + + hash + + o7chZmnJ+qfIragP+xmEb3UC50A= + + hash2 + + 6wAZtnWPC7f3ZN8Om2Ml3Ysu8xIeQK0ULkIh9tAoDq0= + + + Headers/FlutterEmbedderFileChooser.h + + hash + + J8d0BRuKDgrMz+Ednay0vgLNtZ8= + + hash2 + + /nsFBdhdAgue64ue4CD05SUarkLJ3l8uVhwMxF/UGUI= + + + Modules/module.modulemap + + hash + + Q0zUkqeIk9RB1nYV2gh5TOxAh1k= + + hash2 + + Wghb5KTXPF9nOL2atqe9NFOJ7GxUWOCQCSlppILYt/0= + + + Resources/Info.plist + + hash + + DFRRJ1XNFr8hsTcRjUFgl4ry8Yk= + + hash2 + + j6623NJ1u6UqS6oXnFxCnW6Ohmf+WPUiQaJXacNhx1Q= + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/feather/macos/FlutterEmbedderFileChooser.framework/Versions/Current b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/feather/macos/FlutterEmbedderFileChooser.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/FlutterEmbedderMacFeather b/feather/macos/FlutterEmbedderMacFeather.framework/FlutterEmbedderMacFeather new file mode 120000 index 00000000..a8a2ae9b --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/FlutterEmbedderMacFeather @@ -0,0 +1 @@ +Versions/Current/FlutterEmbedderMacFeather \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Headers b/feather/macos/FlutterEmbedderMacFeather.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Modules b/feather/macos/FlutterEmbedderMacFeather.framework/Modules new file mode 120000 index 00000000..5736f318 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Resources b/feather/macos/FlutterEmbedderMacFeather.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/FlutterEmbedderMacFeather b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/FlutterEmbedderMacFeather new file mode 100755 index 00000000..d2e8c6cc Binary files /dev/null and b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/FlutterEmbedderMacFeather differ diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEChannels.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEChannels.h new file mode 100644 index 00000000..3038bc68 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEChannels.h @@ -0,0 +1,90 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +/** + * An object encapsulating a method call from Flutter. + */ +@interface FLEMethodCall : NSObject + +/** + * Initializes an FLEMethodCall. If |arguments| is provided, it must be serializable to JSON. + */ +- (nonnull instancetype)initWithMethodName:(nonnull NSString *)name + arguments:(nullable id)arguments NS_DESIGNATED_INITIALIZER; +- (nonnull instancetype)init NS_UNAVAILABLE; + +/** + * The name of the method being called. + */ +@property(readonly, nonatomic, nonnull) NSString *methodName; + +/** + * The arguments to the method being called, if any. + * + * This object must be serializable to JSON. See + * https://docs.flutter.io/flutter/services/JSONMethodCodec-class.html + * for supported types. + */ +@property(readonly, nonatomic, nullable) id arguments; + +@end + +#pragma mark - + +/** + * A method call result callback. Used for sending a method call's response back to the + * Flutter engine. The result must be serializable to JSON. + */ +typedef void (^FLEMethodResult)(id _Nullable result); + +/** + * A constant that can be passed to an FLEMethodResult to indicate that the message is not handled + * (e.g., the method name is unknown). + */ +extern NSString const *_Nonnull FLEMethodNotImplemented; + +/** + * An error object that can be passed to an FLEMethodResult to send an error response to the caller + * on the Flutter side. + */ +@interface FLEMethodError : NSObject + +/** + * Initializes an FLEMethodError. If |details| is provided, it must be serializable to JSON. + */ +- (nonnull instancetype)initWithCode:(nonnull NSString *)code + message:(nullable NSString *)message + details:(nullable id)details NS_DESIGNATED_INITIALIZER; +- (nonnull instancetype)init NS_UNAVAILABLE; + +/** + * The error code, as a string. + */ +@property(readonly, nonatomic, nonnull) NSString *code; + +/** + * A human-readable description of the error. + */ +@property(readonly, nonatomic, nullable) NSString *message; + +/** + * Any additional details or context about the error. + * + * This object must be serializable to JSON. + */ +@property(readonly, nonatomic, nullable) id details; + +@end diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLECodecs.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLECodecs.h new file mode 100644 index 00000000..d4fa7298 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLECodecs.h @@ -0,0 +1,181 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "FLEChannels.h" + +/** + * Translates between a binary message and higher-level method call and response/error objects. + */ +@protocol FLEMethodCodec + +/** + * Returns the shared instance of the codec. + */ ++ (nonnull instancetype)sharedInstance; + +/** + * Returns a binary encoding of the given |methodCall|, or nil if the method call cannot be + * serialized by this codec. + */ +- (nullable NSData*)encodeMethodCall:(nonnull FLEMethodCall*)methodCall; + +/** + * Returns the FLEMethodCall encoded in |methodData|, or nil if it cannot be decoded. + */ +- (nullable FLEMethodCall*)decodeMethodCall:(nonnull NSData*)methodData; + +/** + * Returns a binary encoding of |result|. Returns nil if |result| is not a type supported by the + * codec. + */ +- (nullable NSData*)encodeSuccessEnvelope:(nullable id)result; + +/** + * Returns a binary encoding of |error|. Returns nil if the |details| parameter of |error| is not + * a type supported by the codec. + */ +- (nullable NSData*)encodeErrorEnvelope:(nonnull FLEMethodError*)error; + +@end + +/** + * A codec that uses JSON as the encoding format. Method arguments and error details for plugins + * using this codec must be serializable to JSON. + */ +@interface FLEJSONMethodCodec : NSObject +@end + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FLEStandardDataType) { + FLEStandardDataTypeUInt8, + FLEStandardDataTypeInt32, + FLEStandardDataTypeInt64, + FLEStandardDataTypeFloat64, +}; + +@interface FLEStandardWriter : NSObject +- (instancetype )initWithData:(NSMutableData*)data; +- (void)writeByte:(UInt8)value; +- (void)writeBytes:(const void*)bytes length:(NSUInteger)length; +- (void)writeData:(NSData*)data; +- (void)writeSize:(UInt32)size; +- (void)writeAlignment:(UInt8)alignment; +- (void)writeUTF8:(NSString*)value; +- (void)writeValue:(id )value; +@end + +@interface FLEStandardReader : NSObject +- (instancetype )initWithData:(NSData* )data; +- (BOOL)hasMore; +- (UInt8)readByte; +- (void)readBytes:(void*)destination length:(NSUInteger)length; +- (NSData*)readData:(NSUInteger)length; +- (UInt32)readSize; +- (void)readAlignment:(UInt8)alignment; +- (NSString*)readUTF8; +- (id _Nullable )readValue; +- (id _Nullable )readValueOfType:(UInt8)type; +@end + + +@interface FLEStandardReaderWriter : NSObject +- (FLEStandardWriter*)writerWithData:(NSMutableData*)data; +- (FLEStandardReader*)readerWithData:(NSData*)data; +@end + + +/** + * A codec that uses JSON as the encoding format. Method arguments and error details for plugins + * using this codec must be serializable to JSON. + */ +@interface FLEStandardMethodCodec : NSObject ++ (instancetype _Nonnull )codecWithReaderWriter:(FLEStandardReaderWriter* _Nonnull)readerWriter; +@end + +@interface FLEStandardTypedData : NSObject +/** + Creates a `FlutterStandardTypedData` which interprets the specified data + as plain bytes. + + - Parameter data: the byte data. + */ ++ (instancetype)typedDataWithBytes:(NSData*)data; + +/** + Creates a `FlutterStandardTypedData` which interprets the specified data + as 32-bit signed integers. + + - Parameter data: the byte data. The length must be divisible by 4. + */ ++ (instancetype)typedDataWithInt32:(NSData*)data; + +/** + Creates a `FlutterStandardTypedData` which interprets the specified data + as 64-bit signed integers. + + - Parameter data: the byte data. The length must be divisible by 8. + */ ++ (instancetype)typedDataWithInt64:(NSData*)data; + +/** + Creates a `FlutterStandardTypedData` which interprets the specified data + as 64-bit floats. + + - Parameter data: the byte data. The length must be divisible by 8. + */ ++ (instancetype)typedDataWithFloat64:(NSData*)data; + ++ (instancetype)typedDataWithData:(NSData*)data type:(FLEStandardDataType)type; + +/** + The raw underlying data buffer. + */ +@property(readonly, nonatomic) NSData* data; + +/** + The type of the encoded values. + */ +@property(readonly, nonatomic) FLEStandardDataType type; + +/** + The number of value items encoded. + */ +@property(readonly, nonatomic) UInt32 elementCount; + +/** + The number of bytes used by the encoding of a single value item. + */ +@property(readonly, nonatomic) UInt8 elementSize; +@end + +@interface FLEStandardBigInteger : NSObject +/** + Creates a `FlutterStandardBigInteger` from a hexadecimal representation. + + - Parameter hex: a hexadecimal string. + */ ++ (instancetype)bigIntegerWithHex:(NSString*)hex; + +/** + The hexadecimal string representation of this integer. + */ +@property(readonly, nonatomic) NSString* hex; +@end + + +NS_ASSUME_NONNULL_END +// TODO: Implement the other core Flutter codecs. Issue #67. diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEOpenGLContextHandling.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEOpenGLContextHandling.h new file mode 100644 index 00000000..4d54e6b1 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEOpenGLContextHandling.h @@ -0,0 +1,32 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * Protocol for views owned by FLEViewController to handle context changes, specifically relating to + * OpenGL context changes. + */ +@protocol FLEOpenGLContextHandling + +/** + * Sets the receiver as the current context object. + */ +- (void)makeCurrentContext; + +/** + * Called when the display is updated. In an NSOpenGLView this is best handled via a flushBuffer + * call. + */ +- (void)onPresent; + +@end diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEPlugin.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEPlugin.h new file mode 100644 index 00000000..d5b57b98 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEPlugin.h @@ -0,0 +1,68 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "FLEChannels.h" +#import "FLECodecs.h" + +@class FLEViewController; + +/** + * A plugin is an object that can respond appropriately to Flutter platform messages over a specific + * named system channel. See https://flutter.io/platform-channels/. + * + * Note: This interface will be changing in the future to more closely match the iOS Flutter + * platform message API. It will be a one-time breaking change. + */ +@protocol FLEPlugin + +/** + * A weak reference to the owning controller. May be used to send messages to the Flutter + * framework. + */ +@property(nullable, weak) FLEViewController *controller; + +/** + * The name of the system channel via which this plugin communicates. + */ +@property(nonnull, readonly) NSString *channel; + +/** + * Called when a message is sent from Flutter on this plugin's channel. + * The result callback must be called exactly once, with one of: + * - FLEMethodNotImplemented, if the method call is unknown. + * - An FLEMethodError, if the method call was understood but there was a + * problem handling it. + * - Any other value (including nil) to indicate success. The value will + * be returned to the Flutter caller, and must be serializable to JSON. + * + * If handling the method involves multiple responses to Flutter, follow-up + * messages can be sent by calling the other direction using + * -[FLEViewController invokeMethod:arguments:onChannel:]. + */ +- (void)handleMethodCall:(nonnull FLEMethodCall *)call result:(nonnull FLEMethodResult)result; + +@optional + +/** + * If implemented, returns the codec to use for method calls to this plugin. + * + * If not implemented, the codec is assumed to be FLEJSONMethodCodec. Note that this is different + * from existing Flutter platforms, which default to the standard codec; this is to preserve + * backwards compatibility for FLEPlugin until the breaking change for the platform messages API. + */ +@property(nonnull, readonly) id codec; + +@end diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEReshapeListener.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEReshapeListener.h new file mode 100644 index 00000000..f8557814 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEReshapeListener.h @@ -0,0 +1,26 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +/** + * Protocol for listening to reshape events on this FlutterView. + * Used to notify the underlying Flutter engine of the new screen dimensions. + * Reflected from [NSOpenGLView.reshape]. + */ +@protocol FLEReshapeListener + +- (void)viewDidReshape:(nonnull NSOpenGLView *)view; + +@end diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEView.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEView.h new file mode 100644 index 00000000..1bf7a3f1 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEView.h @@ -0,0 +1,29 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import + +/** + * View capable of acting as a rendering target and input source for the Flutter + * engine. + */ +@interface FLEView : NSOpenGLView + +/** + * Listener for reshape events. See protocol description. + */ +@property(nonatomic, weak, nullable) IBOutlet id reshapeListener; + +@end diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEViewController.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEViewController.h new file mode 100644 index 00000000..3d8d6245 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FLEViewController.h @@ -0,0 +1,116 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "FLECodecs.h" +#import "FLEOpenGLContextHandling.h" +#import "FLEPlugin.h" +#import "FLEReshapeListener.h" + +/** + * Controls embedder plugins and communication with the underlying Flutter engine, managing a view + * intended to handle key inputs and drawing protocols (see |view|). + * + * Can be launched headless (no managed view), at which point a Dart executable will be run on the + * Flutter engine in non-interactive mode, or with a drawable Flutter canvas. + */ +@interface FLEViewController : NSViewController + +- (void)receivedUriLaunch:(nonnull NSString *)uri; + + +- (void)setCurrentActivityMessage:(nonnull NSString *)message; + +- (void)showSignInView; + +- (void) hideSignInView; + +- (IBAction)signInCancelled:(id _Nonnull )sender; + +/** + * The view this controller manages when launched in interactive mode (headless set to false). Must + * be capable of handling text input events, and the OpenGL context handling protocols. + */ +@property(nullable) NSView *view; + +@property (strong, nullable) IBOutlet NSView *signInView; + +@property (nonatomic, retain, nullable) IBOutlet NSProgressIndicator* activityIndicator; + +@property (weak) IBOutlet NSTextField *currentActivityTextField; + +/** + * Launches the Flutter engine in snapshot mode with the provided configuration. The path argument + * is used to identify the Flutter application the engine should be configured with. See + * https://github.com/flutter/engine/wiki/Custom-Flutter-Engine-Embedders for more information + * on embedding, including the meaning of various possible arguments. + * + * In snapshot mode, the snapshot in the assets directory will be used instead of the original + * dart sources. + */ +- (BOOL)launchEngineWithAssetsPath:(nonnull NSURL *)assets + asHeadless:(BOOL)headless + commandLineArguments:(nonnull NSArray *)arguments; + +/** + * Launches the Flutter engine in source mode with the provided configuration. The path arguments + * are used to identify the Flutter application the engine should be configured with. See + * https://github.com/flutter/engine/wiki/Custom-Flutter-Engine-Embedders for more information + * on embedding, including the meaning of various possible arguments. + * + * In source mode, the Dart source and its dependencies will be read directly from their locations + * on disk. + * TODO: Evaluate whether this mode needs to be present in the long term, and if so reconsider this + * API structure. + */ +- (BOOL)launchEngineWithMainPath:(nonnull NSURL *)main + assetsPath:(nonnull NSURL *)assets + packagesPath:(nonnull NSURL *)packages + asHeadless:(BOOL)headless + commandLineArguments:(nonnull NSArray *)arguments; + +/** + * Adds a plugin to the view controller to handle domain-specific system messages. The plugin's + * channel property will determine which system channel the plugin operates on. Only one plugin + * can operate on a given named channel; if two plugins declare the same channel, the second + * add will return NO. + */ +- (BOOL)addPlugin:(nonnull id)plugin; + +/** + * Sends a platform message to the Flutter engine on |channel|, encoded using |codec|. + * + * // TODO: Move to an API that mirrors the FlutterMethodChannel API. + * // TODO: Support responses. + */ +- (void)invokeMethod:(nonnull NSString *)method + arguments:(nullable id)arguments + onChannel:(nonnull NSString *)channel + withCodec:(nonnull id)codec; + +/** + * Calls invokeMethod:arguments:onChannel:withCodec: using FLEJSONCodec. See the note in + * FLEPlugin.h for why JSON is the default. + */ +- (void)invokeMethod:(nonnull NSString *)method + arguments:(nullable id)arguments + onChannel:(nonnull NSString *)channel; + +@end + +@interface FoobarView : NSView + +@end + diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FlutterEmbedderMacFeather.h b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FlutterEmbedderMacFeather.h new file mode 100644 index 00000000..023bff70 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Headers/FlutterEmbedderMacFeather.h @@ -0,0 +1,21 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "FLEChannels.h" +#import "FLECodecs.h" +#import "FLEOpenGLContextHandling.h" +#import "FLEPlugin.h" +#import "FLEReshapeListener.h" +#import "FLEView.h" +#import "FLEViewController.h" diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Modules/module.modulemap b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 00000000..8f883a17 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module FlutterEmbedderMacFeather { + umbrella header "FlutterEmbedderMacFeather.h" + + export * + module * { export * } +} diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Resources/Info.plist b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..89adb754 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,47 @@ + + + + + BuildMachineOSBuild + 17G65 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FlutterEmbedderMacFeather + CFBundleIdentifier + com.google.FlutterEmbedderMac + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FlutterEmbedderMacFeather + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 9B55 + DTPlatformVersion + GM + DTSDKBuild + 17B41 + DTSDKName + macosx10.13 + DTXcode + 0910 + DTXcodeBuild + 9B55 + UIDeviceFamily + + 1 + 2 + + + diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/_CodeSignature/CodeResources b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/_CodeSignature/CodeResources new file mode 100644 index 00000000..a0398173 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/A/_CodeSignature/CodeResources @@ -0,0 +1,231 @@ + + + + + files + + Resources/Info.plist + + lktashG4aZTJEhxr605cyYaILHU= + + + files2 + + Headers/FLEChannels.h + + hash + + t5zUbejkzYkcAlKUVsA5M21gDSA= + + hash2 + + 4mKeAe7nF9qt24yrhlHvHuT1v1Ye+wQcW+tGUrKLsTA= + + + Headers/FLECodecs.h + + hash + + JKfA4lXMRWQFJ8hB3iMQrIgmeZI= + + hash2 + + Kzy9bmI1agViqQPBAyCN37rDNEV2YBD26K0b7j74TwI= + + + Headers/FLEOpenGLContextHandling.h + + hash + + rTAR+uM1y9Mt4sqmkBzoCPb1BxE= + + hash2 + + Su0f5dK5dpmByikkCxttjOC846IpAHOto8V/e6pq5WQ= + + + Headers/FLEPlugin.h + + hash + + eKR2qITpnYr6cDxidyt3IlsBWvI= + + hash2 + + dxZ8p/9jfuDU56q+1S8riMHCXA5/4xps6aTLpuCcxkU= + + + Headers/FLEReshapeListener.h + + hash + + LUMi2vMwfxTBRgMWHPm7Z/U030c= + + hash2 + + OmLsafGShz9L3Z8NcLbXXxNEZjFe4bAJTfBM7lDePsI= + + + Headers/FLEView.h + + hash + + aJnsIo9F4+ZiD0o9PpmOmAQ/fYc= + + hash2 + + Nrxc/b+P6qwhXL3zDta40TiZjxDL/xbuNG07Msw0JOM= + + + Headers/FLEViewController.h + + hash + + zr4PgAfxAkxYs7Z5QspOm2AHyy0= + + hash2 + + ebi0gwZS2urwcXilvy6NSdXURspvZnPwuzeMF0b1zks= + + + Headers/FlutterEmbedderMacFeather.h + + hash + + uZ4eKVn+5raNoFuqiAh6O3apwBA= + + hash2 + + ExeJ5QGTx+wHV+e8+kMxHG8bmip0MJilngighyodAYM= + + + Modules/module.modulemap + + hash + + 5eXQcABLV383S4akjJ/z3rJeN+I= + + hash2 + + K2pPIp/B/AGYqEa/CAeWGoXUN3K5PyWMQHd1Xb4WxiM= + + + Resources/Info.plist + + hash + + lktashG4aZTJEhxr605cyYaILHU= + + hash2 + + 5sg11gLbKPSLVK+zGrdT1cGF4rEyzY61kteayQzGUNM= + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/feather/macos/FlutterEmbedderMacFeather.framework/Versions/Current b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/feather/macos/FlutterEmbedderMacFeather.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMenubar.framework/FlutterEmbedderMenubar b/feather/macos/FlutterEmbedderMenubar.framework/FlutterEmbedderMenubar new file mode 120000 index 00000000..e6dbc0be --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/FlutterEmbedderMenubar @@ -0,0 +1 @@ +Versions/Current/FlutterEmbedderMenubar \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Headers b/feather/macos/FlutterEmbedderMenubar.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Modules b/feather/macos/FlutterEmbedderMenubar.framework/Modules new file mode 120000 index 00000000..5736f318 --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Resources b/feather/macos/FlutterEmbedderMenubar.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/FlutterEmbedderMenubar b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/FlutterEmbedderMenubar new file mode 100755 index 00000000..303f6793 Binary files /dev/null and b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/FlutterEmbedderMenubar differ diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FLEMenubarPlugin.h b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FLEMenubarPlugin.h new file mode 100644 index 00000000..d751ee99 --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FLEMenubarPlugin.h @@ -0,0 +1,30 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import + +/** + * A Flutter plugin to control the native menu bar. + */ +@interface FLEMenubarPlugin : NSObject + +/** + * The menu item that Flutter-provided menus should be inserted after. If unset, Flutter-provided + * menus will be inserted after the application menu (i.e., starting at index 1). + */ +@property(nonatomic) NSMenuItem *insertAfterMenuItem; + +@end diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FlutterEmbedderMenubar.h b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FlutterEmbedderMenubar.h new file mode 100644 index 00000000..cf7e9cce --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Headers/FlutterEmbedderMenubar.h @@ -0,0 +1,15 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "FLEMenubarPlugin.h" diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Modules/module.modulemap b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 00000000..c0c29431 --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module FlutterEmbedderMenubar { + umbrella header "FlutterEmbedderMenubar.h" + + export * + module * { export * } +} diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Resources/Info.plist b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..cab0d16a --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,44 @@ + + + + + BuildMachineOSBuild + 17G65 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FlutterEmbedderMenubar + CFBundleIdentifier + com.google.FlutterEmbedderMenubar + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FlutterEmbedderMenubar + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 9B55 + DTPlatformVersion + GM + DTSDKBuild + 17B41 + DTSDKName + macosx10.13 + DTXcode + 0910 + DTXcodeBuild + 9B55 + NSHumanReadableCopyright + Copyright © 2018 Google LLC. All rights reserved. + + diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/_CodeSignature/CodeResources b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/_CodeSignature/CodeResources new file mode 100644 index 00000000..120ff65b --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/A/_CodeSignature/CodeResources @@ -0,0 +1,165 @@ + + + + + files + + Resources/Info.plist + + TXRUQhCiny9jnk8/UNXj+9etaOU= + + + files2 + + Headers/FLEMenubarPlugin.h + + hash + + rwuFgTPBsXXvy9UEUts8PcTBhWE= + + hash2 + + /uSrEvzhXQ4pP9BryiYfssFEvZcZheXuHcSy9QRyR6Y= + + + Headers/FlutterEmbedderMenubar.h + + hash + + Owj9VmFcYl/HVCK57y1vsF8wIo4= + + hash2 + + p1KdGuH5TGbguNADO4nlyS8U7cSnLiepIJrvse7J1pQ= + + + Modules/module.modulemap + + hash + + mZ+PUPSHrEMG1DdWmD+PHkzG3Sc= + + hash2 + + tDmy2s0D7II4n3NHSAPHghjgPSfC3Km8SxGjoUtqdAg= + + + Resources/Info.plist + + hash + + TXRUQhCiny9jnk8/UNXj+9etaOU= + + hash2 + + mLPzl+7JZYsBNvyu0K+QDnaV+bIN8NnKQkkhxdvaYtU= + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/feather/macos/FlutterEmbedderMenubar.framework/Versions/Current b/feather/macos/FlutterEmbedderMenubar.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/feather/macos/FlutterEmbedderMenubar.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/feather/macos/Info.plist b/feather/macos/Info.plist new file mode 100644 index 00000000..b8d0b3a0 --- /dev/null +++ b/feather/macos/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + $(PRODUCT_NAME) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0.0 + CFBundleVersion + 1 + LSApplicationCategoryType + + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2018. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/feather/macos/MainWindow.swift b/feather/macos/MainWindow.swift new file mode 100644 index 00000000..abecf89c --- /dev/null +++ b/feather/macos/MainWindow.swift @@ -0,0 +1,43 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Cocoa + +class MainWindow: NSWindow { + @IBOutlet weak var flutterViewController: FLEViewController! + + override func awakeFromNib() { + flutterViewController.add(FLEColorPanelPlugin()) + flutterViewController.add(FLEFileChooserPlugin()) + flutterViewController.add(FLEMenubarPlugin()) + + let assetsPath = Bundle.main.bundlePath + "/Contents/Resources/flutter_assets"; + NSLog("Assets Path: %@", assetsPath); + + let assets = NSURL.fileURL(withPath: assetsPath, isDirectory: true); + // Pass through argument zero, since the Flutter engine expects to be processing a full + // command line string. + var arguments = [CommandLine.arguments[0]]; +#if !DEBUG + arguments.append("--dart-non-checked-mode"); +#endif + flutterViewController.launchEngine( + withAssetsPath: assets, + asHeadless: false, + commandLineArguments: arguments) + + super.awakeFromNib() + } +} + diff --git a/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/AppAuth.xcscheme b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/AppAuth.xcscheme new file mode 100644 index 00000000..433364ef --- /dev/null +++ b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/AppAuth.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMAppAuth.xcscheme b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMAppAuth.xcscheme new file mode 100644 index 00000000..a2afd835 --- /dev/null +++ b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMAppAuth.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme new file mode 100644 index 00000000..53315c7a --- /dev/null +++ b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/Pods-Example Embedder.xcscheme b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/Pods-Example Embedder.xcscheme new file mode 100644 index 00000000..16da6269 --- /dev/null +++ b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/Pods-Example Embedder.xcscheme @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/xcschememanagement.plist b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..1cb509d5 --- /dev/null +++ b/feather/macos/Pods/Pods.xcodeproj/xcuserdata/mark.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,39 @@ + + + + + SchemeUserState + + AppAuth.xcscheme + + isShown + + orderHint + 3 + + GTMAppAuth.xcscheme + + isShown + + orderHint + 4 + + GTMSessionFetcher.xcscheme + + isShown + + orderHint + 5 + + Pods-Example Embedder.xcscheme + + isShown + + orderHint + 6 + + + SuppressBuildableAutocreation + + + diff --git a/feather/macos/SignInView.swift b/feather/macos/SignInView.swift new file mode 100644 index 00000000..37417b11 --- /dev/null +++ b/feather/macos/SignInView.swift @@ -0,0 +1,16 @@ +import Cocoa + + +class SignInView: NSView { + + override init(frame frameRect: NSRect) { + super.init(frame:frameRect); +// Bundle.main.loadNibNamed(NSNib.Name(rawValue: "SignInView"), owner: self, topLevelObjects: nil); +// self.view.frame = NSMakeRect(0, 0, frame.size.width, frame.size.height); +// self.addSubview(view); + } + + required init?(coder decoder: NSCoder) { + super.init(coder: decoder); + } +} diff --git a/feather/macos/SignInView.xib b/feather/macos/SignInView.xib new file mode 100644 index 00000000..ebda97f5 --- /dev/null +++ b/feather/macos/SignInView.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feather/macos/en.lproj/InfoPlist.strings b/feather/macos/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..e90f884c --- /dev/null +++ b/feather/macos/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +"CFBundleDisplayName" = "NKUST AP"; +"CFBundleName" = "NKUST AP"; diff --git a/feather/macos/en.lproj/MainMenu.strings b/feather/macos/en.lproj/MainMenu.strings new file mode 100644 index 00000000..74bb6bb9 --- /dev/null +++ b/feather/macos/en.lproj/MainMenu.strings @@ -0,0 +1,195 @@ + +/* Class = "NSMenuItem"; title = "FeatherApp"; ObjectID = "1Xt-HY-uBw"; */ +"1Xt-HY-uBw.title" = "NKUST AP"; + +/* Class = "NSMenu"; title = "Find"; ObjectID = "1b7-l0-nxx"; */ +"1b7-l0-nxx.title" = "Find"; + +/* Class = "NSMenuItem"; title = "Transformations"; ObjectID = "2oI-Rn-ZJC"; */ +"2oI-Rn-ZJC.title" = "Transformations"; + +/* Class = "NSMenu"; title = "Spelling"; ObjectID = "3IN-sU-3Bg"; */ +"3IN-sU-3Bg.title" = "Spelling"; + +/* Class = "NSMenu"; title = "Speech"; ObjectID = "3rS-ZA-NoH"; */ +"3rS-ZA-NoH.title" = "Speech"; + +/* Class = "NSMenuItem"; title = "Find"; ObjectID = "4EN-yA-p0u"; */ +"4EN-yA-p0u.title" = "Find"; + +/* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ +"4J7-dP-txa.title" = "Enter Full Screen"; + +/* Class = "NSMenuItem"; title = "Quit FeatherApp"; ObjectID = "4sb-4s-VLi"; */ +"4sb-4s-VLi.title" = "Quit NKUST AP"; + +/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */ +"5QF-Oa-p0T.title" = "Edit"; + +/* Class = "NSMenuItem"; title = "About FeatherApp"; ObjectID = "5kV-Vb-QxS"; */ +"5kV-Vb-QxS.title" = "About NKUST AP"; + +/* Class = "NSMenuItem"; title = "Redo"; ObjectID = "6dh-zS-Vam"; */ +"6dh-zS-Vam.title" = "Redo"; + +/* Class = "NSMenuItem"; title = "Correct Spelling Automatically"; ObjectID = "78Y-hA-62v"; */ +"78Y-hA-62v.title" = "Correct Spelling Automatically"; + +/* Class = "NSMenuItem"; title = "Substitutions"; ObjectID = "9ic-FL-obx"; */ +"9ic-FL-obx.title" = "Substitutions"; + +/* Class = "NSMenuItem"; title = "Smart Copy/Paste"; ObjectID = "9yt-4B-nSM"; */ +"9yt-4B-nSM.title" = "Smart Copy/Paste"; + +/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ +"AYu-sK-qS6.title" = "Main Menu"; + +/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ +"BOF-NM-1cW.title" = "Preferences…"; + +/* Class = "NSTextFieldCell"; title = "Waiting for web browser sign-in..."; ObjectID = "Cjz-n0-fmH"; */ +"Cjz-n0-fmH.title" = "Waiting for web browser sign-in..."; + +/* Class = "NSMenuItem"; title = "Spelling and Grammar"; ObjectID = "Dv1-io-Yv7"; */ +"Dv1-io-Yv7.title" = "Spelling and Grammar"; + +/* Class = "NSMenu"; title = "Substitutions"; ObjectID = "FeM-D8-WVr"; */ +"FeM-D8-WVr.title" = "Substitutions"; + +/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ +"H8h-7b-M4v.title" = "View"; + +/* Class = "NSMenuItem"; title = "Text Replacement"; ObjectID = "HFQ-gK-NFA"; */ +"HFQ-gK-NFA.title" = "Text Replacement"; + +/* Class = "NSMenuItem"; title = "Show Spelling and Grammar"; ObjectID = "HFo-cy-zxI"; */ +"HFo-cy-zxI.title" = "Show Spelling and Grammar"; + +/* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ +"HyV-fh-RgO.title" = "View"; + +/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ +"Kd2-mp-pUS.title" = "Show All"; + +/* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ +"LE2-aR-0XJ.title" = "Bring All to Front"; + +/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ +"NMo-om-nkz.title" = "Services"; + +/* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ +"OY7-WF-poV.title" = "Minimize"; + +/* Class = "NSMenuItem"; title = "Hide FeatherApp"; ObjectID = "Olw-nP-bQN"; */ +"Olw-nP-bQN.title" = "Hide NKUST AP"; + +/* Class = "NSMenuItem"; title = "Find Previous"; ObjectID = "OwM-mh-QMV"; */ +"OwM-mh-QMV.title" = "Find Previous"; + +/* Class = "NSMenuItem"; title = "Stop Speaking"; ObjectID = "Oyz-dy-DGm"; */ +"Oyz-dy-DGm.title" = "Stop Speaking"; + +/* Class = "NSWindow"; title = "FeatherApp"; ObjectID = "QvC-M9-y7g"; */ +"QvC-M9-y7g.title" = "NKUST AP"; + +/* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ +"R4o-n2-Eq4.title" = "Zoom"; + +/* Class = "NSMenuItem"; title = "Select All"; ObjectID = "Ruw-6m-B2m"; */ +"Ruw-6m-B2m.title" = "Select All"; + +/* Class = "NSMenuItem"; title = "Jump to Selection"; ObjectID = "S0p-oC-mLd"; */ +"S0p-oC-mLd.title" = "Jump to Selection"; + +/* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ +"Td7-aD-5lo.title" = "Window"; + +/* Class = "NSMenuItem"; title = "Capitalize"; ObjectID = "UEZ-Bs-lqG"; */ +"UEZ-Bs-lqG.title" = "Capitalize"; + +/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ +"Vdr-fp-XzO.title" = "Hide Others"; + +/* Class = "NSMenu"; title = "Edit"; ObjectID = "W48-6f-4Dl"; */ +"W48-6f-4Dl.title" = "Edit"; + +/* Class = "NSMenuItem"; title = "Paste and Match Style"; ObjectID = "WeT-3V-zwk"; */ +"WeT-3V-zwk.title" = "Paste and Match Style"; + +/* Class = "NSMenuItem"; title = "Find…"; ObjectID = "Xz5-n4-O0W"; */ +"Xz5-n4-O0W.title" = "Find…"; + +/* Class = "NSMenuItem"; title = "Find and Replace…"; ObjectID = "YEy-JH-Tfz"; */ +"YEy-JH-Tfz.title" = "Find and Replace…"; + +/* Class = "NSMenuItem"; title = "Start Speaking"; ObjectID = "Ynk-f8-cLZ"; */ +"Ynk-f8-cLZ.title" = "Start Speaking"; + +/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ +"aUF-d1-5bR.title" = "Window"; + +/* Class = "NSMenuItem"; title = "Use Selection for Find"; ObjectID = "buJ-ug-pKt"; */ +"buJ-ug-pKt.title" = "Use Selection for Find"; + +/* Class = "NSMenu"; title = "Transformations"; ObjectID = "c8a-y6-VQd"; */ +"c8a-y6-VQd.title" = "Transformations"; + +/* Class = "NSMenuItem"; title = "Smart Links"; ObjectID = "cwL-P1-jid"; */ +"cwL-P1-jid.title" = "Smart Links"; + +/* Class = "NSMenuItem"; title = "Make Lower Case"; ObjectID = "d9M-CD-aMd"; */ +"d9M-CD-aMd.title" = "Make Lower Case"; + +/* Class = "NSMenuItem"; title = "Undo"; ObjectID = "dRJ-4n-Yzg"; */ +"dRJ-4n-Yzg.title" = "Undo"; + +/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "fmb-7q-fym"; */ +"fmb-7q-fym.title" = "Cancel"; + +/* Class = "NSMenuItem"; title = "Paste"; ObjectID = "gVA-U4-sdL"; */ +"gVA-U4-sdL.title" = "Paste"; + +/* Class = "NSMenuItem"; title = "Smart Quotes"; ObjectID = "hQb-2v-fYv"; */ +"hQb-2v-fYv.title" = "Smart Quotes"; + +/* Class = "NSMenuItem"; title = "Check Document Now"; ObjectID = "hz2-CU-CR7"; */ +"hz2-CU-CR7.title" = "Check Document Now"; + +/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ +"hz9-B4-Xy5.title" = "Services"; + +/* Class = "NSMenuItem"; title = "Check Grammar With Spelling"; ObjectID = "mK6-2p-4JG"; */ +"mK6-2p-4JG.title" = "Check Grammar With Spelling"; + +/* Class = "NSMenuItem"; title = "Delete"; ObjectID = "pa3-QI-u2k"; */ +"pa3-QI-u2k.title" = "Delete"; + +/* Class = "NSMenuItem"; title = "Find Next"; ObjectID = "q09-fT-Sye"; */ +"q09-fT-Sye.title" = "Find Next"; + +/* Class = "NSMenuItem"; title = "Check Spelling While Typing"; ObjectID = "rbD-Rh-wIN"; */ +"rbD-Rh-wIN.title" = "Check Spelling While Typing"; + +/* Class = "NSMenuItem"; title = "Smart Dashes"; ObjectID = "rgM-f4-ycn"; */ +"rgM-f4-ycn.title" = "Smart Dashes"; + +/* Class = "NSMenuItem"; title = "Data Detectors"; ObjectID = "tRr-pd-1PS"; */ +"tRr-pd-1PS.title" = "Data Detectors"; + +/* Class = "NSMenu"; title = "FeatherApp"; ObjectID = "uQy-DD-JDr"; */ +"uQy-DD-JDr.title" = "NKUST AP"; + +/* Class = "NSMenuItem"; title = "Cut"; ObjectID = "uRl-iY-unG"; */ +"uRl-iY-unG.title" = "Cut"; + +/* Class = "NSMenuItem"; title = "Make Upper Case"; ObjectID = "vmV-6d-7jI"; */ +"vmV-6d-7jI.title" = "Make Upper Case"; + +/* Class = "NSMenuItem"; title = "Copy"; ObjectID = "x3v-GG-iWU"; */ +"x3v-GG-iWU.title" = "Copy"; + +/* Class = "NSMenuItem"; title = "Speech"; ObjectID = "xrE-MZ-jX0"; */ +"xrE-MZ-jX0.title" = "Speech"; + +/* Class = "NSMenuItem"; title = "Show Substitutions"; ObjectID = "z6F-FW-3nz"; */ +"z6F-FW-3nz.title" = "Show Substitutions"; diff --git a/lib/main.dart b/lib/main.dart index 032ca569..ea90a366 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/observer.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_crashlytics/flutter_crashlytics.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -18,37 +19,46 @@ import 'package:nkust_ap/utils/utils.dart'; void main() async { bool isInDebugMode = Constants.isInDebugMode; - FlutterError.onError = (FlutterErrorDetails details) { - if (isInDebugMode) { - // In development mode simply print to console. - FlutterError.dumpErrorToConsole(details); - } else { - // In production mode report to the application zone to report to - // Crashlytics. - Zone.current.handleUncaughtError(details.exception, details.stack); - } - }; + if (Platform.isIOS || Platform.isAndroid) { + FlutterError.onError = (FlutterErrorDetails details) { + if (isInDebugMode) { + // In development mode simply print to console. + FlutterError.dumpErrorToConsole(details); + } else { + // In production mode report to the application zone to report to + // Crashlytics. + Zone.current.handleUncaughtError(details.exception, details.stack); + } + }; - await FlutterCrashlytics().initialize(); + await FlutterCrashlytics().initialize(); - runZoned>(() async { + runZoned>(() async { + runApp(MyApp()); + }, onError: (error, stackTrace) async { + // Whenever an error occurs, call the `reportCrash` function. This will send + // Dart errors to our dev console or Crashlytics depending on the environment. + await FlutterCrashlytics() + .reportCrash(error, stackTrace, forceCrash: false); + }); + } else { runApp(MyApp()); - }, onError: (error, stackTrace) async { - // Whenever an error occurs, call the `reportCrash` function. This will send - // Dart errors to our dev console or Crashlytics depending on the environment. - await FlutterCrashlytics() - .reportCrash(error, stackTrace, forceCrash: false); - }); + //TODO add other platform Crashlytics + } } class MyApp extends StatelessWidget { - final FirebaseAnalytics analytics = FirebaseAnalytics(); - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + FirebaseAnalytics analytics; + FirebaseMessaging _firebaseMessaging; @override Widget build(BuildContext context) { - _initFCM(); - FA.analytics = analytics; + if (Platform.isAndroid || Platform.isIOS) { + analytics = FirebaseAnalytics(); + _firebaseMessaging = FirebaseMessaging(); + _initFCM(); + FA.analytics = analytics; + } return new MaterialApp( localeResolutionCallback: (Locale locale, Iterable supportedLocales) { @@ -85,9 +95,11 @@ class MyApp extends StatelessWidget { UnderlineInputBorder(borderSide: BorderSide(color: Colors.white)), ), ), - navigatorObservers: [ - FirebaseAnalyticsObserver(analytics: analytics), - ], + navigatorObservers: (Platform.isIOS || Platform.isAndroid) + ? [ + FirebaseAnalyticsObserver(analytics: analytics), + ] + : [], localizationsDelegates: [ const AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, diff --git a/lib/pages/home/about/about_us_page.dart b/lib/pages/home/about/about_us_page.dart index 92bc8b3f..2771d67a 100644 --- a/lib/pages/home/about/about_us_page.dart +++ b/lib/pages/home/about/about_us_page.dart @@ -56,6 +56,7 @@ class AboutUsPageState extends State onPressed: () { Navigator.of(context) .pushNamed(OpenSourcePage.routerName); + FA.logAction('open_source', 'click'); }) ], backgroundColor: Resource.Colors.blue, @@ -121,9 +122,16 @@ class AboutUsPageState extends State Utils.launchUrl('fb://page/735951703168873') .catchError((onError) => Utils.launchUrl( 'https://www.facebook.com/NKUST.ITC/')); - else + else if (Platform.isIOS) Utils.launchUrl( 'https://www.facebook.com/NKUST.ITC/'); + else + Utils.launchUrl( + 'https://www.facebook.com/NKUST.ITC/') + .catchError((onError) => + Utils.showToast(app.platformError)); + ; + FA.logAction('fb', 'click'); }, iconSize: 48.0, ), @@ -135,15 +143,23 @@ class AboutUsPageState extends State 'github://organization/NKUST-ITC') .catchError((onError) => Utils.launchUrl( 'https://github.com/NKUST-ITC')); - else + else if (Platform.isIOS) Utils.launchUrl('https://github.com/NKUST-ITC'); + else + Utils.launchUrl('https://github.com/NKUST-ITC') + .catchError((onError) => + Utils.showToast(app.platformError)); + FA.logAction('github', 'click'); }, iconSize: 48.0, ), IconButton( icon: Image.asset("assets/images/ic_email.webp"), onPressed: () { - Utils.launchUrl('mailto:abc873693@gmail.com'); + Utils.launchUrl('mailto:abc873693@gmail.com') + .catchError((onError) => + Utils.showToast(app.platformError)); + FA.logAction('email', 'click'); }, iconSize: 48.0, ), diff --git a/lib/pages/home/bus/bus_reservations_page.dart b/lib/pages/home/bus/bus_reservations_page.dart index b3d5e9e2..e2182201 100644 --- a/lib/pages/home/bus/bus_reservations_page.dart +++ b/lib/pages/home/bus/bus_reservations_page.dart @@ -67,7 +67,10 @@ class BusReservationsPageState extends State case _State.error: case _State.empty: return FlatButton( - onPressed: _getBusReservations, + onPressed: () { + _getBusReservations(); + FA.logAction('retry', 'click'); + }, child: HintContent( icon: Icons.assignment, content: state == _State.error @@ -77,7 +80,10 @@ class BusReservationsPageState extends State ); default: return RefreshIndicator( - onRefresh: () => _getBusReservations(), + onRefresh: () { + _getBusReservations(); + FA.logAction('refresh', 'swipe'); + }, child: ListView( children: busReservationWeights, ), @@ -142,12 +148,14 @@ class BusReservationsPageState extends State textAlign: TextAlign.center, ), leftActionText: app.back, - rightActionText: app.busCancelReserve, + rightActionText: app.determine, rightActionFunction: () { _cancelBusReservation(busReservation); + FA.logAction('cancel_bus', 'click'); }, ), ); + FA.logAction('cancel_bus', 'create'); }, ) : Container(), @@ -232,6 +240,8 @@ class BusReservationsPageState extends State style: TextStyle( color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), ); + FA.logAction('cancel_bus', 'status', + message: 'fail_${response.data["message"]}'); } else { title = app.busCancelReserveSuccess; messageWidget = RichText( @@ -264,6 +274,7 @@ class BusReservationsPageState extends State ]), ); _getBusReservations(); + FA.logAction('cancel_bus', 'status', message: 'success'); } Navigator.pop(context, 'dialog'); showDialog( @@ -275,21 +286,19 @@ class BusReservationsPageState extends State actionFunction: () => Navigator.of(context, rootNavigator: true).pop('dialog')), ); - //Utils.showDefaultDialog(context, title, message, app.iKnow, () {}); }).catchError((e) { Navigator.pop(context, 'dialog'); if (e is DioError) { switch (e.type) { case DioErrorType.RESPONSE: - Utils.handleResponseError( - context, 'getBusReservations', mounted, e); + Utils.handleResponseError(context, 'cancel_bus', mounted, e); break; case DioErrorType.DEFAULT: if (e.message.contains("HttpException")) { setState(() { state = _State.error; - Utils.showToast(app.busFailInfinity); }); + Utils.showToast(app.busFailInfinity); } break; case DioErrorType.CANCEL: diff --git a/lib/pages/home/bus/bus_reserve_page.dart b/lib/pages/home/bus/bus_reserve_page.dart index 70a8aa62..e7fe444f 100644 --- a/lib/pages/home/bus/bus_reserve_page.dart +++ b/lib/pages/home/bus/bus_reserve_page.dart @@ -71,7 +71,10 @@ class BusReservePageState extends State case _State.error: case _State.empty: return FlatButton( - onPressed: _getBusTimeTables, + onPressed: () { + _getBusTimeTables(); + FA.logAction('retry', 'click'); + }, child: HintContent( icon: Icons.assignment, content: state == _State.error ? app.clickToRetry : app.busEmpty, @@ -79,7 +82,10 @@ class BusReservePageState extends State ); default: return RefreshIndicator( - onRefresh: () => _getBusTimeTables(), + onRefresh: () { + _getBusTimeTables(); + FA.logAction('refresh', 'swipe'); + }, child: ListView( physics: const NeverScrollableScrollPhysics(), children: _renderBusTimeWidgets(), @@ -155,7 +161,27 @@ class BusReservePageState extends State ), ); } - : null, + : () { + showDialog( + context: context, + builder: (BuildContext context) => YesNoDialog( + title: app.busCancelReserve, + contentWidget: Text( + "${app.busCancelReserveConfirmContent1}${busTime.getStart(app)}" + "${app.busCancelReserveConfirmContent2}${busTime.getEnd(app)}\n" + "${busTime.getTime()}${app.busCancelReserveConfirmContent3}", + textAlign: TextAlign.center, + ), + leftActionText: app.back, + rightActionText: app.determine, + rightActionFunction: () { + _cancelBusReservation(busTime); + FA.logAction('cancel_bus', 'click'); + }, + ), + ); + FA.logAction('cancel_bus', 'create'); + }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -247,6 +273,7 @@ class BusReservePageState extends State onDateSelected: (DateTime datetime) { dateTime = datetime; _getBusTimeTables(); + FA.logAction('date_select', 'click'); }, initialCalendarDateOverride: dateTime, dayChildAspectRatio: @@ -290,6 +317,7 @@ class BusReservePageState extends State selectStartStation = text; }); } + FA.logAction('segment', 'click'); }, ), ), @@ -364,7 +392,7 @@ class BusReservePageState extends State builder: (BuildContext context) => ProgressDialog(app.reserving), barrierDismissible: true); Helper.instance.bookingBusReservation(busTime.busId).then((response) { - //TODO 優化成物件 + //TODO to object String title = ""; Widget messageWidget; if (!response.data["success"]) { @@ -374,6 +402,8 @@ class BusReservePageState extends State style: TextStyle( color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), ); + FA.logAction('book_bus', 'status', + message: 'fail_${response.data["message"]}'); } else { title = app.busReserveSuccess; messageWidget = RichText( @@ -406,6 +436,7 @@ class BusReservePageState extends State ]), ); _getBusTimeTables(); + FA.logAction('book_bus', 'status', message: 'success'); } Navigator.pop(context, 'dialog'); showDialog( @@ -423,7 +454,7 @@ class BusReservePageState extends State if (e is DioError) { switch (e.type) { case DioErrorType.RESPONSE: - Utils.handleResponseError(context, 'bookingBus', mounted, e); + Utils.handleResponseError(context, 'book_bus', mounted, e); break; case DioErrorType.DEFAULT: if (e.message.contains("HttpException")) { @@ -446,4 +477,92 @@ class BusReservePageState extends State } }); } + + _cancelBusReservation(BusTime busTime) { + showDialog( + context: context, + builder: (BuildContext context) => ProgressDialog(app.canceling), + barrierDismissible: true); + Helper.instance.cancelBusReservation(busTime.cancelKey).then((response) { + String title = ""; + Widget messageWidget; + if (!response.data["success"]) { + title = app.busCancelReserveFail; + messageWidget = Text( + response.data["message"], + style: TextStyle( + color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), + ); + FA.logAction('cancel_bus', 'status', + message: 'fail_${response.data["message"]}'); + } else { + title = app.busCancelReserveSuccess; + messageWidget = RichText( + textAlign: TextAlign.left, + text: TextSpan( + style: TextStyle( + color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), + children: [ + TextSpan( + text: '${app.busReserveCancelDate}:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: '${busTime.getDate()}\n', + ), + TextSpan( + text: '${app.busReserveCancelLocation}:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: '${busTime.getStart(app)}${app.campus}\n', + ), + TextSpan( + text: '${app.busReserveCancelTime}:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: '${busTime.getTime()}', + ), + ]), + ); + _getBusTimeTables(); + FA.logAction('cancel_bus', 'status', message: 'success'); + } + Navigator.pop(context, 'dialog'); + showDialog( + context: context, + builder: (BuildContext context) => DefaultDialog( + title: title, + contentWidget: messageWidget, + actionText: app.iKnow, + actionFunction: () => + Navigator.of(context, rootNavigator: true).pop('dialog')), + ); + }).catchError((e) { + Navigator.pop(context, 'dialog'); + if (e is DioError) { + switch (e.type) { + case DioErrorType.RESPONSE: + Utils.handleResponseError(context, 'cancel_bus', mounted, e); + break; + case DioErrorType.DEFAULT: + if (e.message.contains("HttpException")) { + setState(() { + state = _State.error; + }); + Utils.showToast(app.busFailInfinity); + } + break; + case DioErrorType.CANCEL: + break; + default: + Utils.handleDioError(e, app); + break; + } + } else { + throw e; + } + }); + } } diff --git a/lib/pages/home/bus/bus_rule_page.dart b/lib/pages/home/bus/bus_rule_page.dart index c19b07e5..d27254b3 100644 --- a/lib/pages/home/bus/bus_rule_page.dart +++ b/lib/pages/home/bus/bus_rule_page.dart @@ -30,6 +30,7 @@ class BusRulePageState extends State @override void initState() { super.initState(); + FA.setCurrentScreen("BusRulePage", "bus_rule_page.dart"); } @override @@ -40,7 +41,7 @@ class BusRulePageState extends State @override Widget build(BuildContext context) { app = AppLocalizations.of(context); - ; + //TODO English version return new Scaffold( appBar: AppBar( title: Text(app.busRule), diff --git a/lib/pages/home/calculate_units_page.dart b/lib/pages/home/calculate_units_page.dart index a6a1bdae..b2dacc49 100644 --- a/lib/pages/home/calculate_units_page.dart +++ b/lib/pages/home/calculate_units_page.dart @@ -153,7 +153,10 @@ class CalculateUnitsPageState extends State Expanded( flex: 19, child: RefreshIndicator( - onRefresh: () => _calculate(), + onRefresh: () { + FA.logAction('refresh', 'swipe'); + _calculate(); + }, child: _body(), ), ), diff --git a/lib/pages/home/course_page.dart b/lib/pages/home/course_page.dart index ad6d53e0..32a12cdf 100644 --- a/lib/pages/home/course_page.dart +++ b/lib/pages/home/course_page.dart @@ -146,6 +146,7 @@ class CoursePageState extends State ), ), ); + FA.logAction('show_course', 'click'); }, child: Text( (course.title[0] + course.title[1]) ?? "", @@ -162,7 +163,13 @@ class CoursePageState extends State case _State.empty: case _State.error: return FlatButton( - onPressed: state == _State.error ? _getCourseTables : _selectSemester, + onPressed: () { + if (state == _State.error) + _getCourseTables(); + else + _selectSemester(); + FA.logAction('retry', 'click'); + }, child: HintContent( icon: Icons.class_, content: @@ -236,7 +243,10 @@ class CoursePageState extends State Expanded( flex: 19, child: RefreshIndicator( - onRefresh: () => _getCourseTables(), + onRefresh: () { + _getCourseTables(); + FA.logAction('refresh', 'swipe'); + }, child: _body(), ), ), @@ -312,6 +322,7 @@ class CoursePageState extends State for (var semester in semesterData.semesters) { semesters.add(_dialogItem(semesters.length, semester.text)); } + FA.logAction('pick_yms', 'click'); showDialog( context: context, builder: (BuildContext context) => SimpleDialog( diff --git a/lib/pages/home/info/notification_page.dart b/lib/pages/home/info/notification_page.dart index 26778794..d5098fcd 100644 --- a/lib/pages/home/info/notification_page.dart +++ b/lib/pages/home/info/notification_page.dart @@ -66,11 +66,15 @@ class NotificationPageState extends State return GestureDetector( onLongPress: () { Utils.shareTo("${notification.info.title}\n${notification.link}"); + FA.logAction('share', 'long_click', + message: '${notification.info.title}'); }, child: FlatButton( padding: EdgeInsets.all(0.0), onPressed: () { Utils.launchUrl(notification.link); + FA.logAction('notification_link"', 'click', + message: '${notification.info.title}'); }, child: Container( width: double.infinity, @@ -126,9 +130,11 @@ class NotificationPageState extends State child: CircularProgressIndicator(), alignment: Alignment.center); case _State.error: case _State.empty: - //TODO 優化 + //TODO improve return FlatButton( - onPressed: () {}, + onPressed: () { + FA.logAction('rerty', 'click'); + }, child: HintContent( icon: Icons.assignment, content: @@ -143,6 +149,7 @@ class NotificationPageState extends State }); notificationList.clear(); _getNotifications(); + FA.logAction('refresh', 'swipe'); }, child: ListView.builder( controller: controller, diff --git a/lib/pages/home/info/phone_page.dart b/lib/pages/home/info/phone_page.dart index 8f1e85c8..66d2d73a 100644 --- a/lib/pages/home/info/phone_page.dart +++ b/lib/pages/home/info/phone_page.dart @@ -101,7 +101,13 @@ class PhonePageState extends State ), ), onPressed: () { - Utils.callPhone(phone.number); + FA.logAction('call_phone', 'click'); + try { + Utils.callPhone(phone.number); + FA.logAction('call_phone', 'status', message: 'succes'); + } catch (e) { + FA.logAction('call_phone', 'status', message: 'error'); + } }, ); } @@ -159,8 +165,8 @@ class PhonePageState extends State phoneList.add(PhoneModel("楠梓校區", "")); phoneList.add(PhoneModel("總機", "07-3617141")); phoneList.add(PhoneModel("課外活動組", "07-3617141 #22070")); - phoneList.add(PhoneModel("海洋校區", "")); - phoneList.add(PhoneModel("海洋校區", "07-8100888")); + phoneList.add(PhoneModel("旗津校區", "")); + phoneList.add(PhoneModel("旗津校區", "07-8100888")); phoneList.add(PhoneModel("學生事務處", "07-3617141 #2052")); phoneList.add(PhoneModel("課外活動組", "07-8100888 #25065")); phoneList.add(PhoneModel("生活輔導組", "07-3617141 #23967")); diff --git a/lib/pages/home/info/schedule_page.dart b/lib/pages/home/info/schedule_page.dart index ade8f7aa..b1183581 100644 --- a/lib/pages/home/info/schedule_page.dart +++ b/lib/pages/home/info/schedule_page.dart @@ -177,6 +177,7 @@ class SchedulePageState extends State return FlatButton( padding: EdgeInsets.all(0.0), onPressed: () { + FA.logAction('add_schedule', 'create'); showDialog( context: context, builder: (BuildContext context) => YesNoDialog( @@ -200,6 +201,7 @@ class SchedulePageState extends State leftActionFunction: null, rightActionFunction: () { _addToCalendar(schedule.events[index]); + FA.logAction('add_schedule', 'click'); }, ), ); diff --git a/lib/pages/home/news_content_page.dart b/lib/pages/home/news_content_page.dart index b1d4dd10..40adc0cb 100644 --- a/lib/pages/home/news_content_page.dart +++ b/lib/pages/home/news_content_page.dart @@ -144,6 +144,10 @@ class NewsContentPageState extends State ), onPressed: () { if (news.url.isNotEmpty) Utils.launchUrl(news.url); + String message = news.content.length > 12 + ? news.content + : news.content.substring(0, 12); + FA.logAction('news_link', 'click', message: message); }, padding: EdgeInsets.symmetric(vertical: 12.0, horizontal: 0.0), color: Resource.Colors.yellow, diff --git a/lib/pages/home/score_page.dart b/lib/pages/home/score_page.dart index 673ce095..e5063cc4 100644 --- a/lib/pages/home/score_page.dart +++ b/lib/pages/home/score_page.dart @@ -148,7 +148,10 @@ class ScorePageState extends State Expanded( flex: 19, child: RefreshIndicator( - onRefresh: () => _getSemesterScore(), + onRefresh: () { + _getSemesterScore(); + FA.logAction('refresh', 'swipe'); + }, child: _body(), ), ), @@ -166,8 +169,13 @@ class ScorePageState extends State case _State.error: case _State.empty: return FlatButton( - onPressed: - state == _State.error ? _getSemesterScore : _selectSemester, + onPressed: () { + if (state == _State.error) + _getSemesterScore(); + else + _selectSemester(); + FA.logAction('retry', 'click'); + }, child: HintContent( icon: Icons.assignment, content: state == _State.error ? app.clickToRetry : app.scoreEmpty, @@ -242,6 +250,7 @@ class ScorePageState extends State for (var semester in semesterData.semesters) { semesters.add(_dialogItem(semesters.length, semester.text)); } + FA.logAction('pick_yms', 'click'); showDialog( context: context, builder: (BuildContext context) => SimpleDialog( diff --git a/lib/pages/home/setting_page.dart b/lib/pages/home/setting_page.dart index 874b410c..e34c73cb 100644 --- a/lib/pages/home/setting_page.dart +++ b/lib/pages/home/setting_page.dart @@ -60,66 +60,82 @@ class SettingPageState extends State backgroundColor: Resource.Colors.blue, ), body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _titleItem(app.notificationItem), - _itemSwitch(app.courseNotify, courseNotify, () async { - if (!courseNotify) - _setupCourseNotify(context); - else { - await Utils.cancelCourseNotify(); - } - setState(() { - courseNotify = !courseNotify; - }); - prefs.setBool(Constants.PREF_COURSE_NOTIFY, courseNotify); - }), - _itemSwitch(app.busNotify, busNotify, () async { - bool bus = prefs.getBool(Constants.PREF_BUS_ENABLE) ?? true; - if (bus) { - if (!busNotify) - _setupBusNotify(context); - else { - await Utils.cancelBusNotify(); - } - setState(() { - busNotify = !busNotify; - }); - prefs.setBool(Constants.PREF_BUS_NOTIFY, busNotify); - } else { - Utils.showToast(app.canNotUseFeature); - } - }), - Container( - color: Colors.grey, - height: 0.5, - ), - _titleItem(app.otherSettings), - _itemSwitch(app.headPhotoSetting, displayPicture, () { - displayPicture = !displayPicture; - prefs.setBool(Constants.PREF_DISPLAY_PICTURE, displayPicture); - setState(() {}); - }), - Container( - color: Colors.grey, - height: 0.5, - ), - _titleItem(app.otherInfo), - _item(app.feedback, app.feedbackViaFacebook, () { - if (Platform.isAndroid) - Utils.launchUrl('fb://messaging/954175941266264').catchError( - (onError) => Utils.launchUrl( - 'https://www.facebook.com/954175941266264/')); - else - Utils.launchUrl('https://www.facebook.com/954175941266264/'); - }), - _item(app.donateTitle, app.donateContent, () { - Utils.launchUrl( - "https://payment.ecpay.com.tw/QuickCollect/PayData?mLM7iy8RpUGk%2fyBotSDMdvI0qGI5ToToqBW%2bOQbOE80%3d"); - }), - _item(app.appVersion, "v$appVersion", () {}), - ]), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: < + Widget>[ + _titleItem(app.notificationItem), + _itemSwitch(app.courseNotify, courseNotify, () async { + FA.logAction('notify_course', 'create'); + setState(() { + courseNotify = !courseNotify; + }); + if (courseNotify) + _setupCourseNotify(context); + else { + await Utils.cancelCourseNotify(); + } + FA.logAction('notify_course', 'create', message: '$courseNotify'); + prefs.setBool(Constants.PREF_COURSE_NOTIFY, courseNotify); + }), + _itemSwitch(app.busNotify, busNotify, () async { + FA.logAction('notify_bus', 'create'); + bool bus = prefs.getBool(Constants.PREF_BUS_ENABLE) ?? true; + if (bus) { + setState(() { + busNotify = !busNotify; + }); + if (busNotify) + _setupBusNotify(context); + else { + await Utils.cancelBusNotify(); + } + prefs.setBool(Constants.PREF_BUS_NOTIFY, busNotify); + FA.logAction('notify_bus', 'click', message: '$busNotify'); + } else { + Utils.showToast(app.canNotUseFeature); + FA.logAction('notify_bus', 'staus', + message: 'can\'t use feature'); + } + }), + Container( + color: Colors.grey, + height: 0.5, + ), + _titleItem(app.otherSettings), + _itemSwitch(app.headPhotoSetting, displayPicture, () { + prefs.setBool(Constants.PREF_DISPLAY_PICTURE, displayPicture); + setState(() { + displayPicture = !displayPicture; + }); + FA.logAction('head_photo', 'click'); + }), + Container( + color: Colors.grey, + height: 0.5, + ), + _titleItem(app.otherInfo), + _item(app.feedback, app.feedbackViaFacebook, () { + if (Platform.isAndroid) + Utils.launchUrl('fb://messaging/954175941266264').catchError( + (onError) => Utils.launchUrl( + 'https://www.facebook.com/954175941266264/')); + else if (Platform.isIOS) + Utils.launchUrl('https://www.facebook.com/954175941266264/'); + else { + Utils.launchUrl('https://www.facebook.com/954175941266264/') + .catchError((onError) => Utils.showToast(app.platformError)); + } + FA.logAction('feedback', 'click'); + }), + _item(app.donateTitle, app.donateContent, () { + Utils.launchUrl( + "https://payment.ecpay.com.tw/QuickCollect/PayData?mLM7iy8RpUGk%2fyBotSDMdvI0qGI5ToToqBW%2bOQbOE80%3d") + .catchError((onError) => Utils.showToast(app.platformError)); + FA.logAction('donate', 'click'); + }), + _item(app.appVersion, "v$appVersion", () { + //FA.logAction('donate', 'click'); + }), + ]), ), ); } @@ -158,11 +174,12 @@ class SettingPageState extends State _getPreference() async { prefs = await SharedPreferences.getInstance(); PackageInfo packageInfo = await PackageInfo.fromPlatform(); - appVersion = packageInfo.version; - courseNotify = prefs.getBool(Constants.PREF_COURSE_NOTIFY) ?? false; - displayPicture = prefs.getBool(Constants.PREF_DISPLAY_PICTURE) ?? true; - busNotify = prefs.getBool(Constants.PREF_BUS_NOTIFY) ?? false; - setState(() {}); + setState(() { + appVersion = packageInfo.version; + courseNotify = prefs.getBool(Constants.PREF_COURSE_NOTIFY) ?? false; + displayPicture = prefs.getBool(Constants.PREF_DISPLAY_PICTURE) ?? true; + busNotify = prefs.getBool(Constants.PREF_BUS_NOTIFY) ?? false; + }); } _item(String text, String subText, Function function) => FlatButton( @@ -242,8 +259,8 @@ class SettingPageState extends State }).catchError((e) { setState(() { courseNotify = false; - prefs.setBool(Constants.PREF_COURSE_NOTIFY, courseNotify); }); + prefs.setBool(Constants.PREF_COURSE_NOTIFY, courseNotify); if (e is DioError) { switch (e.type) { case DioErrorType.RESPONSE: @@ -275,8 +292,8 @@ class SettingPageState extends State }).catchError((e) { setState(() { busNotify = false; - prefs.setBool(Constants.PREF_BUS_NOTIFY, busNotify); }); + prefs.setBool(Constants.PREF_BUS_NOTIFY, busNotify); if (Navigator.canPop(context)) Navigator.pop(context, 'dialog'); if (e is DioError) { switch (e.type) { diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 900261a7..2e85a699 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -62,6 +62,10 @@ class HomePageState extends State { child: GestureDetector( onTap: () { Navigator.of(context).push(NewsContentPageRoute(news)); + String message = news.content.length > 12 + ? news.content + : news.content.substring(0, 12); + FA.logAction('news_image', 'click', message: message); }, child: Hero( tag: news.hashCode, @@ -119,6 +123,7 @@ class HomePageState extends State { setState(() { _currentNewsIndex = current; }); + FA.logAction('news_image', 'swipe'); }, ), SizedBox(height: orientation == Orientation.portrait ? 16.0 : 4.0), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index ead17e18..c39ce1bf 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -187,7 +187,10 @@ class LoginPageState extends State ), ), padding: EdgeInsets.all(14.0), - onPressed: _login, + onPressed: () { + FA.logAction('login', 'click'); + _login(); + }, color: Colors.white, child: Text( app.login, @@ -384,8 +387,6 @@ class LoginPageState extends State }), barrierDismissible: false); prefs.setString(Constants.PREF_USERNAME, _username.text); - if (isRememberPassword) - prefs.setString(Constants.PREF_PASSWORD, _password.text); Helper.instance .login(_username.text, _password.text) .then((LoginResponse response) async { @@ -409,6 +410,7 @@ class LoginPageState extends State switch (e.type) { case DioErrorType.RESPONSE: Utils.showToast(app.loginFail); + Utils.handleResponseError(context, 'login', mounted, e); break; case DioErrorType.CANCEL: break; diff --git a/lib/utils/app_localizations.dart b/lib/utils/app_localizations.dart index 369b04b7..133e6a33 100644 --- a/lib/utils/app_localizations.dart +++ b/lib/utils/app_localizations.dart @@ -20,8 +20,7 @@ class AppLocalizations { 'en': { 'app_name': 'NKUST AP', 'update_note_title': 'Update Notes', - 'update_note_content': - '1.Fix some crash.\n2.Fix Calculate Units error.\n3.Update dialog style.\n4.Fix home page slider.\n5.Add bus rule page.', + 'update_note_content': '1.Fix some crash.\n2.Add bus page cancel bus.', 'splash_content': '我們全都包了\n只剩下學校不包我們', 'share': 'Share', 'teacher_confirm_title': 'Are you a teacher?', @@ -268,12 +267,12 @@ class AppLocalizations { 'load_offline_data': 'Load offline data', 'reserve_deadline': 'Reserve Deadline', 'bus_rule': 'Bus Rule', + 'platform_error': 'Current platform can\'t use this feature.', }, 'zh': { 'app_name': '高科校務通', 'update_note_title': '更新日誌', - 'update_note_content': - '1.修正部分崩潰.\n2.修正學分計算錯誤\n3.修改對話框風格\n4.修改首頁輪播\n5.新增校車規則說明', + 'update_note_content': '1.修正部分崩潰.\n2.新增校車預定頁面可取消預約', 'splash_content': '我們全都包了\n只剩下學校不包我們', 'share': '分享', 'teacher_confirm_title': '您是老師嗎?', @@ -507,6 +506,7 @@ class AppLocalizations { 'load_offline_data': '載入離線資料', 'reserve_deadline': '預約截止時間', 'bus_rule': '校車搭乘規則', + 'platform_error': '此平台無法使用此功能', }, }; @@ -905,6 +905,8 @@ class AppLocalizations { String get offlineCourse => _vocabularies['offline_course']; String get busRule => _vocabularies['bus_rule']; + + String get platformError => _vocabularies['platform_error']; } class AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/utils/firebase_analytics_utils.dart b/lib/utils/firebase_analytics_utils.dart index 0a8d66f9..cd73b32a 100644 --- a/lib/utils/firebase_analytics_utils.dart +++ b/lib/utils/firebase_analytics_utils.dart @@ -9,62 +9,84 @@ class FA { static Future setCurrentScreen( String screenName, String screenClassOverride) async { - await analytics.setCurrentScreen( - screenName: screenName, - screenClassOverride: screenClassOverride, - ); + if (Platform.isIOS || Platform.isAndroid) + await analytics.setCurrentScreen( + screenName: screenName, + screenClassOverride: screenClassOverride, + ); } static Future setUserId(String id) async { - await analytics.setUserId(id); + if (Platform.isIOS || Platform.isAndroid) await analytics.setUserId(id); print('setUserId succeeded'); } static Future setUserProperty(String name, String value) async { - await analytics.setUserProperty( - name: name, - value: value, - ); + if (Platform.isIOS || Platform.isAndroid) + await analytics.setUserProperty( + name: name, + value: value, + ); print('setUserProperty succeeded'); } - static Future logApiEvent(String type, int status) async { + static Future logApiEvent(String type, int status, + {String message}) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); - await analytics.logEvent( - name: 'ap_api', - parameters: { - 'type': type, - 'status': status, - 'version': packageInfo.version, - 'platform': Platform.operatingSystem, - }, - ); + if (Platform.isIOS || Platform.isAndroid) + await analytics.logEvent( + name: 'ap_api', + parameters: { + 'type': type, + 'status': status, + 'message': message, + 'version': packageInfo.version, + 'platform': Platform.operatingSystem, + }, + ); print('logEvent succeeded'); } static Future logAESErrorEvent(String encryptPassword) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); - await analytics.logEvent( - name: 'aes_error', - parameters: { - 'type': encryptPassword, - 'version': packageInfo.version, - 'platform': Platform.operatingSystem, - }, - ); + if (Platform.isIOS || Platform.isAndroid) + await analytics.logEvent( + name: 'aes_error', + parameters: { + 'encryptPassword': encryptPassword, + 'version': packageInfo.version, + 'platform': Platform.operatingSystem, + }, + ); print('log encryptPassword succeeded'); } static Future logCalculateUnits(double seconds) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); - await analytics.logEvent( - name: 'calculate_units_time', - parameters: { - 'time': seconds, - 'version': packageInfo.version, - 'platform': Platform.operatingSystem, - }, - ); + if (Platform.isIOS || Platform.isAndroid) + await analytics.logEvent( + name: 'calculate_units_time', + parameters: { + 'time': seconds, + 'version': packageInfo.version, + 'platform': Platform.operatingSystem, + }, + ); print('log CalculateUnits succeeded'); } + + static Future logAction(String name, String action, + {String message}) async { + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + if (Platform.isIOS || Platform.isAndroid) + await analytics.logEvent( + name: name, + parameters: { + 'action': action, + 'message': message, + 'version': packageInfo.version, + 'platform': Platform.operatingSystem, + }, + ); + } } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index eefdc00d..e75f9ed1 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -36,14 +36,15 @@ class Utils { static void handleResponseError( BuildContext context, String type, bool mounted, DioError e) { var app = AppLocalizations.of(context); - FA.logApiEvent(type, e.response.statusCode); + FA.logApiEvent(type, e.response.statusCode, message: e.message); if (e.response.statusCode == 401) { Utils.showToast(app.tokenExpiredContent); if (mounted) Navigator.popUntil( context, ModalRoute.withName(Navigator.defaultRouteName)); - } else + } else { Utils.showToast(app.somethingError); + } } static void showToast(String message) { diff --git a/lib/widgets/drawer_body.dart b/lib/widgets/drawer_body.dart index 271f4c6d..57cb3f5d 100644 --- a/lib/widgets/drawer_body.dart +++ b/lib/widgets/drawer_body.dart @@ -95,7 +95,11 @@ class DrawerBodyState extends State { image: new DecorationImage( fit: BoxFit.fitWidth, image: CachedNetworkImageProvider( - pictureUrl), + pictureUrl, + errorListener: () { + print('error'); + }, + ), ), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index d107be22..50e9a71b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: nkust_ap description: A new Flutter application. -version: 3.1.2+30102 +version: 3.1.3+30103 environment: sdk: ">=2.1.0 <3.0.0"