diff --git a/lib/data/models/company_model.dart b/lib/data/models/company_model.dart index 514e04470..28e5749ec 100644 --- a/lib/data/models/company_model.dart +++ b/lib/data/models/company_model.dart @@ -569,6 +569,8 @@ abstract class CompanyEntity extends Object bool get isSmall => !isLarge; + bool get hasName => (settings?.name ?? '').isNotEmpty; + bool get hasCustomSurcharge => hasCustomField(CustomFieldType.surcharge1) || hasCustomField(CustomFieldType.surcharge2) || diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index 78c63fa92..1d2ee8f43 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -192,6 +192,16 @@ abstract class AppState implements Built { return color.isNotEmpty; } + Map get apiTokens { + final map = {}; + for (var userCompany in userCompanyStates) { + if (userCompany.company.hasName) { + map[userCompany.token.token] = userCompany.company.settings.name; + } + } + return map; + } + bool get showReviewApp => !prefState.hideReviewApp && company.daysActive > 60; bool get showOneYearReviewApp => diff --git a/lib/ui/app/menu_drawer.dart b/lib/ui/app/menu_drawer.dart index 399119acb..d8b4343bb 100644 --- a/lib/ui/app/menu_drawer.dart +++ b/lib/ui/app/menu_drawer.dart @@ -14,6 +14,7 @@ import 'package:invoiceninja_flutter/redux/reports/reports_actions.dart'; import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart'; import 'package:invoiceninja_flutter/ui/app/sms_verification.dart'; import 'package:invoiceninja_flutter/ui/app/upgrade_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/window_manager.dart'; import 'package:invoiceninja_flutter/utils/app_review.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; @@ -49,6 +50,7 @@ import 'package:invoiceninja_flutter/utils/icons.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/strings.dart'; +import 'package:widget_kit_plugin/widget_kit_plugin.dart'; class MenuDrawer extends StatefulWidget { const MenuDrawer({ @@ -1389,7 +1391,7 @@ void _showAbout(BuildContext context) async { showToast(localization.copiedToClipboard .replaceFirst(':value', state.appVersion)); }, - onLongPress: () { + onLongPress: () async { if (kReleaseMode) { showMessageDialog( context: context, @@ -1403,10 +1405,20 @@ void _showAbout(BuildContext context) async { ), ]); } else { + print("## reloadAllTimelines"); + + await UserDefaults.setString( + 'widgetData', + jsonEncode(WidgetData(state.apiTokens)), + 'group.com.invoiceninja.app'); + await WidgetKit.reloadAllTimelines(); + + /* showDialog( context: context, builder: (context) => UpgradeDialog(), ); + */ } }, ), diff --git a/lib/ui/app/window_manager.dart b/lib/ui/app/window_manager.dart index 17d69ac81..b52c9a0f4 100644 --- a/lib/ui/app/window_manager.dart +++ b/lib/ui/app/window_manager.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:invoiceninja_flutter/constants.dart'; @@ -6,6 +8,8 @@ import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:widget_kit_plugin/user_defaults/user_defaults.dart'; +import 'package:widget_kit_plugin/widget_kit/widget_kit.dart'; import 'package:window_manager/window_manager.dart'; class WindowManager extends StatefulWidget { @@ -22,17 +26,27 @@ class _WindowManagerState extends State with WindowListener { void initState() { if (isDesktopOS()) { windowManager.addListener(this); - _init(); + _initManager(); + } + + if (isApple()) { + _initWidgets(); } super.initState(); } - void _init() async { + void _initManager() async { await windowManager.setPreventClose(true); setState(() {}); } + void _initWidgets() async { + //print("## SET DATA"); + //await UserDefaults.setString('widgetData', 'hello', 'group.com.invoiceninja.app'); + //await WidgetKit.reloadAllTimelines(); + } + @override void onWindowResize() async { if (!isDesktopOS()) { @@ -75,3 +89,13 @@ class _WindowManagerState extends State with WindowListener { @override Widget build(BuildContext context) => widget.child; } + +class WidgetData { + WidgetData(this.tokens); + + final Map tokens; + + WidgetData.fromJson(Map json) : tokens = json['tokens']; + + Map toJson() => {'tokens': tokens}; +} \ No newline at end of file diff --git a/macos/DashboardWidget/Assets.xcassets/AccentColor.colorset/Contents.json b/macos/DashboardWidget/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/macos/DashboardWidget/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/macos/DashboardWidget/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/DashboardWidget/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..3f00db43e --- /dev/null +++ b/macos/DashboardWidget/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/macos/DashboardWidget/Assets.xcassets/Contents.json b/macos/DashboardWidget/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/macos/DashboardWidget/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/macos/DashboardWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/macos/DashboardWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/macos/DashboardWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/macos/DashboardWidget/DashboardWidget.entitlements b/macos/DashboardWidget/DashboardWidget.entitlements new file mode 100644 index 000000000..d59f66b26 --- /dev/null +++ b/macos/DashboardWidget/DashboardWidget.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.application-groups + + group.com.invoiceninja.app + + + diff --git a/macos/DashboardWidget/DashboardWidget.intentdefinition b/macos/DashboardWidget/DashboardWidget.intentdefinition new file mode 100644 index 000000000..42d946c47 --- /dev/null +++ b/macos/DashboardWidget/DashboardWidget.intentdefinition @@ -0,0 +1,173 @@ + + + + + INEnums + + + INEnumDisplayName + Field + INEnumDisplayNameID + a7k58J + INEnumGeneratesHeader + + INEnumName + Field + INEnumType + Regular + INEnumValues + + + INEnumValueDisplayName + unknown + INEnumValueDisplayNameID + lwYuqc + INEnumValueName + unknown + + + INEnumValueDisplayName + Invoices + INEnumValueDisplayNameID + z5NmCf + INEnumValueIndex + 1 + INEnumValueName + invoices + + + INEnumValueDisplayName + Payments + INEnumValueDisplayNameID + 4DiypI + INEnumValueIndex + 2 + INEnumValueName + payments + + + INEnumValueDisplayName + Expenses + INEnumValueDisplayNameID + AldHP3 + INEnumValueIndex + 3 + INEnumValueName + expenses + + + + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + 88xZPY + INIntentDefinitionSystemVersion + 21G115 + INIntentDefinitionToolsBuildVersion + 14C18 + INIntentDefinitionToolsVersion + 14.2 + INIntents + + + INIntentCategory + information + INIntentDescriptionID + tVvJ9c + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentLastParameterTag + 2 + INIntentName + Configuration + INIntentParameters + + + INIntentParameterConfigurable + + INIntentParameterDisplayName + Field + INIntentParameterDisplayNameID + t2MezO + INIntentParameterDisplayPriority + 1 + INIntentParameterEnumType + Field + INIntentParameterEnumTypeNamespace + 88xZPY + INIntentParameterName + field + INIntentParameterPromptDialogs + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Configuration + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Primary + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogFormatString + There are ${count} options matching ‘${field}’. + INIntentParameterPromptDialogFormatStringID + 3UOOUA + INIntentParameterPromptDialogType + DisambiguationIntroduction + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogFormatString + Just to confirm, you wanted ‘${field}’? + INIntentParameterPromptDialogFormatStringID + 4sG08t + INIntentParameterPromptDialogType + Confirmation + + + INIntentParameterTag + 2 + INIntentParameterType + Integer + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Configuration + INIntentTitleID + gpCwrM + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + diff --git a/macos/DashboardWidget/DashboardWidget.swift b/macos/DashboardWidget/DashboardWidget.swift new file mode 100644 index 000000000..886a82e5d --- /dev/null +++ b/macos/DashboardWidget/DashboardWidget.swift @@ -0,0 +1,90 @@ +// +// DashboardWidget.swift +// DashboardWidget +// +// Created by hillel on 12/06/2023. +// + +import WidgetKit +import SwiftUI +import Intents + +struct Provider: IntentTimelineProvider { + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(date: Date(), configuration: ConfigurationIntent(), widgetData: WidgetData(tokens: ["plk": "ply"])) + } + + func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { + let entry = SimpleEntry(date: Date(), configuration: configuration, widgetData: WidgetData(tokens: ["sk": "sy"])) + completion(entry) + } + + func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { + print("## getTimeline") + var entries: [SimpleEntry] = [] + + let sharedDefaults = UserDefaults.init(suiteName: "group.com.invoiceninja.app") + var exampleData: WidgetData? = nil + + if sharedDefaults != nil { + do { + let shared = sharedDefaults!.string(forKey: "widgetData") + if shared != nil { + let decoder = JSONDecoder() + exampleData = try decoder.decode(WidgetData.self, from: shared!.data(using: .utf8)!) + } + } catch { + print(error) + } + } + + print("## DATA IS: \(exampleData)") + let currentDate = Date() + let entryDate = Calendar.current.date(byAdding: .hour, value: 24, to: currentDate)! + let entry = SimpleEntry(date: entryDate, configuration: configuration, widgetData: exampleData) + entries.append(entry) + + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } +} + +struct WidgetData: Decodable, Hashable { + let tokens: [String: String] +} + +struct SimpleEntry: TimelineEntry { + let date: Date + let configuration: ConfigurationIntent + let widgetData: WidgetData? +} + +struct DashboardWidgetEntryView : View { + var entry: Provider.Entry + + var body: some View { + //Text(entry.widgetData?.tokens.keys.joined() ?? "BLANK") + Text("TEST \(entry.configuration.field.rawValue)") + } +} + +@main +struct DashboardWidget: Widget { + let kind: String = "DashboardWidget" + + var body: some WidgetConfiguration { + IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in + DashboardWidgetEntryView(entry: entry) + } + .configurationDisplayName("Dashboard") + .description("View total from dashboard.") + .supportedFamilies([.systemSmall,]) + } +} + +struct DashboardWidget_Previews: PreviewProvider { + static var previews: some View { + DashboardWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), widgetData: WidgetData(tokens: ["pk": "py"]))) + .previewContext(WidgetPreviewContext(family: .systemSmall)) + } +} diff --git a/macos/DashboardWidget/Info.plist b/macos/DashboardWidget/Info.plist new file mode 100644 index 000000000..0f118fb75 --- /dev/null +++ b/macos/DashboardWidget/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/macos/Podfile b/macos/Podfile index 9ec46f8cd..f9ebb8dcb 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.15' +platform :osx, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 5c286b525..bbd80f04b 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - desktop_drop (0.0.1): + - FlutterMacOS - FlutterMacOS (1.0.0) - FMDB (2.7.5): - FMDB/standard (= 2.7.5) @@ -38,10 +40,13 @@ PODS: - FMDB (>= 2.7.5) - url_launcher_macos (0.0.1): - FlutterMacOS + - widget_kit_plugin (0.0.1): + - FlutterMacOS - window_manager (0.2.0): - FlutterMacOS DEPENDENCIES: + - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - in_app_purchase_storekit (from `Flutter/ephemeral/.symlinks/plugins/in_app_purchase_storekit/macos`) - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) @@ -57,6 +62,7 @@ DEPENDENCIES: - smart_auth (from `Flutter/ephemeral/.symlinks/plugins/smart_auth/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + - widget_kit_plugin (from `Flutter/ephemeral/.symlinks/plugins/widget_kit_plugin/macos`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) SPEC REPOS: @@ -65,6 +71,8 @@ SPEC REPOS: - Sentry EXTERNAL SOURCES: + desktop_drop: + :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos FlutterMacOS: :path: Flutter/ephemeral in_app_purchase_storekit: @@ -95,10 +103,13 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + widget_kit_plugin: + :path: Flutter/ephemeral/.symlinks/plugins/widget_kit_plugin/macos window_manager: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: + desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a in_app_purchase_storekit: 4fb7ee9e824b1f09107fbfbbce8c4b276366dc43 @@ -116,8 +127,9 @@ SPEC CHECKSUMS: smart_auth: b38e3ab4bfe089eacb1e233aca1a2340f96c28e9 sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 + widget_kit_plugin: 9658611f1ba5faaaa9e8221d94fce53733a6911c window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 -PODFILE CHECKSUM: 0d3963a09fc94f580682bd88480486da345dc3f0 +PODFILE CHECKSUM: 8d40c19d3cbdb380d870685c3a564c989f1efa52 COCOAPODS: 1.11.3 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index fbb2189ae..5fbd1d6b6 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,13 @@ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 4087BE1AA12C2B9DAE44C2E5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C97F7E2DD0B37EAB27D4CC1C /* Pods_Runner.framework */; }; + F9395F9C2A3A30DC0066F1E7 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9395F9B2A3A30DC0066F1E7 /* WidgetKit.framework */; }; + F9395F9E2A3A30DC0066F1E7 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9395F9D2A3A30DC0066F1E7 /* SwiftUI.framework */; }; + F9395FA12A3A30DD0066F1E7 /* DashboardWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9395FA02A3A30DD0066F1E7 /* DashboardWidget.swift */; }; + F9395FA42A3A30DE0066F1E7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F9395FA32A3A30DE0066F1E7 /* Assets.xcassets */; }; + F9395FA72A3A30DE0066F1E7 /* DashboardWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F9395FA22A3A30DD0066F1E7 /* DashboardWidget.intentdefinition */; }; + F9395FA82A3A30DE0066F1E7 /* DashboardWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F9395FA22A3A30DD0066F1E7 /* DashboardWidget.intentdefinition */; }; + F9395FAB2A3A30DE0066F1E7 /* DashboardWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F9395F9A2A3A30DC0066F1E7 /* DashboardWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -37,6 +44,13 @@ remoteGlobalIDString = 33CC111A2044C6BA0003C045; remoteInfo = FLX; }; + F9395FA92A3A30DE0066F1E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F9395F992A3A30DC0066F1E7; + remoteInfo = DashboardWidgetExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -50,6 +64,17 @@ name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; }; + F9395FAC2A3A30DF0066F1E7 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + F9395FAB2A3A30DE0066F1E7 /* DashboardWidgetExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -73,6 +98,14 @@ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; C97F7E2DD0B37EAB27D4CC1C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DE32488957F10B0CF6745675 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + F9395F9A2A3A30DC0066F1E7 /* DashboardWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = DashboardWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F9395F9B2A3A30DC0066F1E7 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + F9395F9D2A3A30DC0066F1E7 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + F9395FA02A3A30DD0066F1E7 /* DashboardWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardWidget.swift; sourceTree = ""; }; + F9395FA22A3A30DD0066F1E7 /* DashboardWidget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = DashboardWidget.intentdefinition; sourceTree = ""; }; + F9395FA32A3A30DE0066F1E7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F9395FA52A3A30DE0066F1E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F9395FA62A3A30DE0066F1E7 /* DashboardWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DashboardWidget.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -84,6 +117,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F9395F972A3A30DC0066F1E7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F9395F9E2A3A30DC0066F1E7 /* SwiftUI.framework in Frameworks */, + F9395F9C2A3A30DC0066F1E7 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -103,6 +145,7 @@ children = ( 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, + F9395F9F2A3A30DD0066F1E7 /* DashboardWidget */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, 8B71285C2494B6F379ADA2F4 /* Pods */, @@ -113,6 +156,7 @@ isa = PBXGroup; children = ( 33CC10ED2044A3C60003C045 /* Invoice Ninja.app */, + F9395F9A2A3A30DC0066F1E7 /* DashboardWidgetExtension.appex */, ); name = Products; sourceTree = ""; @@ -166,10 +210,24 @@ isa = PBXGroup; children = ( C97F7E2DD0B37EAB27D4CC1C /* Pods_Runner.framework */, + F9395F9B2A3A30DC0066F1E7 /* WidgetKit.framework */, + F9395F9D2A3A30DC0066F1E7 /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; }; + F9395F9F2A3A30DD0066F1E7 /* DashboardWidget */ = { + isa = PBXGroup; + children = ( + F9395FA02A3A30DD0066F1E7 /* DashboardWidget.swift */, + F9395FA22A3A30DD0066F1E7 /* DashboardWidget.intentdefinition */, + F9395FA32A3A30DE0066F1E7 /* Assets.xcassets */, + F9395FA52A3A30DE0066F1E7 /* Info.plist */, + F9395FA62A3A30DE0066F1E7 /* DashboardWidget.entitlements */, + ); + path = DashboardWidget; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -184,24 +242,43 @@ 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, 4A8F10BFEE9B664055EA40D7 /* [CP] Embed Pods Frameworks */, + F9395FAC2A3A30DF0066F1E7 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( 33CC11202044C79F0003C045 /* PBXTargetDependency */, + F9395FAA2A3A30DE0066F1E7 /* PBXTargetDependency */, ); name = Runner; productName = Runner; productReference = 33CC10ED2044A3C60003C045 /* Invoice Ninja.app */; productType = "com.apple.product-type.application"; }; + F9395F992A3A30DC0066F1E7 /* DashboardWidgetExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = F9395FB02A3A30DF0066F1E7 /* Build configuration list for PBXNativeTarget "DashboardWidgetExtension" */; + buildPhases = ( + F9395F962A3A30DC0066F1E7 /* Sources */, + F9395F972A3A30DC0066F1E7 /* Frameworks */, + F9395F982A3A30DC0066F1E7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DashboardWidgetExtension; + productName = DashboardWidgetExtension; + productReference = F9395F9A2A3A30DC0066F1E7 /* DashboardWidgetExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 33CC10E52044A3C60003C045 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0920; + LastSwiftUpdateCheck = 1420; LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { @@ -219,6 +296,9 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Manual; }; + F9395F992A3A30DC0066F1E7 = { + CreatedOnToolsVersion = 14.2; + }; }; }; buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; @@ -236,6 +316,7 @@ targets = ( 33CC10EC2044A3C60003C045 /* Runner */, 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + F9395F992A3A30DC0066F1E7 /* DashboardWidgetExtension */, ); }; /* End PBXProject section */ @@ -250,6 +331,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F9395F982A3A30DC0066F1E7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F9395FA42A3A30DE0066F1E7 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -339,10 +428,20 @@ files = ( 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + F9395FA82A3A30DE0066F1E7 /* DashboardWidget.intentdefinition in Sources */, 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + F9395F962A3A30DC0066F1E7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F9395FA72A3A30DE0066F1E7 /* DashboardWidget.intentdefinition in Sources */, + F9395FA12A3A30DD0066F1E7 /* DashboardWidget.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -351,6 +450,11 @@ target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; }; + F9395FAA2A3A30DE0066F1E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F9395F992A3A30DC0066F1E7 /* DashboardWidgetExtension */; + targetProxy = F9395FA92A3A30DE0066F1E7 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -416,6 +520,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; @@ -430,7 +535,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -548,6 +653,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; @@ -562,7 +668,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -574,6 +680,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; @@ -588,7 +695,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -611,6 +718,130 @@ }; name = Release; }; + F9395FAD2A3A30DF0066F1E7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = DashboardWidget/DashboardWidget.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NPC44Y2C98; + ENABLE_HARDENED_RUNTIME = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DashboardWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = DashboardWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@executable_path/../../../../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.6; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.invoiceninja.app.DashboardWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + F9395FAE2A3A30DF0066F1E7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = DashboardWidget/DashboardWidget.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NPC44Y2C98; + ENABLE_HARDENED_RUNTIME = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DashboardWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = DashboardWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@executable_path/../../../../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.6; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.invoiceninja.app.DashboardWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + F9395FAF2A3A30DF0066F1E7 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = DashboardWidget/DashboardWidget.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NPC44Y2C98; + ENABLE_HARDENED_RUNTIME = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DashboardWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = DashboardWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@executable_path/../../../../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.6; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.invoiceninja.app.DashboardWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -644,6 +875,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F9395FB02A3A30DF0066F1E7 /* Build configuration list for PBXNativeTarget "DashboardWidgetExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F9395FAD2A3A30DF0066F1E7 /* Debug */, + F9395FAE2A3A30DF0066F1E7 /* Release */, + F9395FAF2A3A30DF0066F1E7 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 33CC10E52044A3C60003C045 /* Project object */; diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements index 9e82eb73d..3a08c9402 100644 --- a/macos/Runner/DebugProfile.entitlements +++ b/macos/Runner/DebugProfile.entitlements @@ -8,6 +8,10 @@ com.apple.security.app-sandbox + com.apple.security.application-groups + + group.com.invoiceninja.app + com.apple.security.cs.allow-jit com.apple.security.files.downloads.read-write diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist index eb01cb7cc..8f4594c44 100644 --- a/macos/Runner/Info.plist +++ b/macos/Runner/Info.plist @@ -49,6 +49,10 @@ The photo library is used to upload documents NSPrincipalClass NSApplication + NSUserActivityTypes + + ConfigurationIntent + io.flutter.embedded_views_preview diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index 616091689..91d0d7732 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -8,6 +8,10 @@ com.apple.security.app-sandbox + com.apple.security.application-groups + + group.com.invoiceninja.app + com.apple.security.files.downloads.read-write com.apple.security.network.client diff --git a/pubspec.foss.yaml b/pubspec.foss.yaml index b656ab6a2..6bfe812ea 100644 --- a/pubspec.foss.yaml +++ b/pubspec.foss.yaml @@ -79,6 +79,7 @@ dependencies: intl_phone_field: ^3.1.0 flutter_staggered_grid_view: ^0.6.2 desktop_drop: ^0.4.1 + widget_kit_plugin: ^0.1.1 # quick_actions: ^0.2.1 # idb_shim: ^1.11.1+1 diff --git a/pubspec.lock b/pubspec.lock index afd3f4335..1a56b8ff2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1727,6 +1727,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.9.5" + widget_kit_plugin: + dependency: "direct main" + description: + name: widget_kit_plugin + sha256: d3b0036a841b34a30dd07d79404c51d5755b3047af4d95a1d7c74c7fcadb0058 + url: "https://pub.dev" + source: hosted + version: "0.1.1" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e939ef30b..ec606765d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -85,6 +85,7 @@ dependencies: intl_phone_field: ^3.1.0 flutter_staggered_grid_view: ^0.6.2 desktop_drop: ^0.4.1 + widget_kit_plugin: ^0.1.1 # quick_actions: ^0.2.1 # idb_shim: ^1.11.1+1