react-native-ios-widget 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +5 -0
- package/README.md +100 -0
- package/_widgets/EmojiRanger/AdventureActivityConfiguration.swift +71 -0
- package/_widgets/EmojiRanger/AllCharactersView.swift +43 -0
- package/_widgets/EmojiRanger/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/_widgets/EmojiRanger/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/_widgets/EmojiRanger/Assets.xcassets/Contents.json +6 -0
- package/_widgets/EmojiRanger/Assets.xcassets/WidgetBackground.colorset/Contents.json +11 -0
- package/_widgets/EmojiRanger/Attributes.swift +21 -0
- package/_widgets/EmojiRanger/EmojiRanger.swift +248 -0
- package/_widgets/EmojiRanger/EmojiRangersWidget.intentdefinition +118 -0
- package/_widgets/EmojiRanger/EmojiRangersWidget.swift +189 -0
- package/_widgets/EmojiRanger/EmojiRangersWidgetBundle.swift +21 -0
- package/_widgets/EmojiRanger/ImageURLProtocol.swift +66 -0
- package/_widgets/EmojiRanger/Info.plist +11 -0
- package/_widgets/EmojiRanger/LeaderboardWidget.swift +93 -0
- package/_widgets/EmojiRanger/Module.swift +94 -0
- package/_widgets/PizzaDelivery/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/_widgets/PizzaDelivery/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/_widgets/PizzaDelivery/Assets.xcassets/Contents.json +6 -0
- package/_widgets/PizzaDelivery/Assets.xcassets/WidgetBackground.colorset/Contents.json +11 -0
- package/_widgets/PizzaDelivery/Attributes.swift +15 -0
- package/_widgets/PizzaDelivery/Info.plist +11 -0
- package/_widgets/PizzaDelivery/LiveActivity.swift +108 -0
- package/_widgets/PizzaDelivery/Module.swift +94 -0
- package/_widgets/PizzaDelivery/WidgetBundle.swift +13 -0
- package/_widgets/PizzaDelivery/Widgets.swift +59 -0
- package/app.plugin.js +1 -0
- package/build/ExpoWidget.d.ts +3 -0
- package/build/ExpoWidget.d.ts.map +1 -0
- package/build/ExpoWidget.js +3 -0
- package/build/ExpoWidget.js.map +1 -0
- package/build/ReactNativeWidgetExtensionModule.d.ts +3 -0
- package/build/ReactNativeWidgetExtensionModule.d.ts.map +1 -0
- package/build/ReactNativeWidgetExtensionModule.js +5 -0
- package/build/ReactNativeWidgetExtensionModule.js.map +1 -0
- package/build/Widget.d.ts +2 -0
- package/build/Widget.d.ts.map +1 -0
- package/build/Widget.js +19 -0
- package/build/Widget.js.map +1 -0
- package/expo-module.config.json +6 -0
- package/ios/ReactNativeWidgetExtension.podspec +27 -0
- package/package.json +48 -0
- package/plugin/build/android/index.d.ts +10 -0
- package/plugin/build/android/index.js +18 -0
- package/plugin/build/android/withWidgetAndroidManifest.d.ts +5 -0
- package/plugin/build/android/withWidgetAndroidManifest.js +55 -0
- package/plugin/build/android/withWidgetAppBuildGradle.d.ts +7 -0
- package/plugin/build/android/withWidgetAppBuildGradle.js +20 -0
- package/plugin/build/android/withWidgetProjectBuildGradle.d.ts +8 -0
- package/plugin/build/android/withWidgetProjectBuildGradle.js +21 -0
- package/plugin/build/android/withWidgetSourceCode.d.ts +5 -0
- package/plugin/build/android/withWidgetSourceCode.js +51 -0
- package/plugin/build/index.d.ts +10 -0
- package/plugin/build/index.js +34 -0
- package/plugin/build/ios/index.d.ts +9 -0
- package/plugin/build/ios/index.js +34 -0
- package/plugin/build/ios/withConfig.d.ts +6 -0
- package/plugin/build/ios/withConfig.js +55 -0
- package/plugin/build/ios/withPodfile.d.ts +5 -0
- package/plugin/build/ios/withPodfile.js +83 -0
- package/plugin/build/ios/withWidgetExtensionEntitlements.d.ts +7 -0
- package/plugin/build/ios/withWidgetExtensionEntitlements.js +47 -0
- package/plugin/build/ios/withXcode.d.ts +7 -0
- package/plugin/build/ios/withXcode.js +79 -0
- package/plugin/build/lib/getWidgetExtensionEntitlements.d.ts +5 -0
- package/plugin/build/lib/getWidgetExtensionEntitlements.js +20 -0
- package/plugin/build/lib/getWidgetFiles.d.ts +9 -0
- package/plugin/build/lib/getWidgetFiles.js +117 -0
- package/plugin/build/withConfig.d.ts +6 -0
- package/plugin/build/withConfig.js +55 -0
- package/plugin/build/withPodfile.d.ts +5 -0
- package/plugin/build/withPodfile.js +83 -0
- package/plugin/build/withWidgetExtensionEntitlements.d.ts +7 -0
- package/plugin/build/withWidgetExtensionEntitlements.js +47 -0
- package/plugin/build/withXcode.d.ts +7 -0
- package/plugin/build/withXcode.js +79 -0
- package/plugin/build/xcode/addBuildPhases.d.ts +13 -0
- package/plugin/build/xcode/addBuildPhases.js +48 -0
- package/plugin/build/xcode/addPbxGroup.d.ts +6 -0
- package/plugin/build/xcode/addPbxGroup.js +25 -0
- package/plugin/build/xcode/addProductFile.d.ts +5 -0
- package/plugin/build/xcode/addProductFile.js +22 -0
- package/plugin/build/xcode/addTargetDependency.d.ts +4 -0
- package/plugin/build/xcode/addTargetDependency.js +15 -0
- package/plugin/build/xcode/addToPbxNativeTargetSection.d.ts +24 -0
- package/plugin/build/xcode/addToPbxNativeTargetSection.js +30 -0
- package/plugin/build/xcode/addToPbxProjectSection.d.ts +4 -0
- package/plugin/build/xcode/addToPbxProjectSection.js +15 -0
- package/plugin/build/xcode/addXCConfigurationList.d.ts +8 -0
- package/plugin/build/xcode/addXCConfigurationList.js +62 -0
- package/plugin/src/index.ts +52 -0
- package/plugin/src/lib/getWidgetExtensionEntitlements.ts +33 -0
- package/plugin/src/lib/getWidgetFiles.ts +109 -0
- package/plugin/src/withConfig.ts +71 -0
- package/plugin/src/withPodfile.ts +73 -0
- package/plugin/src/withWidgetExtensionEntitlements.ts +30 -0
- package/plugin/src/withXcode.ts +73 -0
- package/plugin/src/xcode/addBuildPhases.ts +83 -0
- package/plugin/src/xcode/addPbxGroup.ts +46 -0
- package/plugin/src/xcode/addProductFile.ts +25 -0
- package/plugin/src/xcode/addTargetDependency.ts +17 -0
- package/plugin/src/xcode/addToPbxNativeTargetSection.ts +46 -0
- package/plugin/src/xcode/addToPbxProjectSection.ts +23 -0
- package/plugin/src/xcode/addXCConfigurationList.ts +83 -0
- package/plugin/tsconfig.json +16 -0
- package/src/ReactNativeWidgetExtensionModule.ts +5 -0
- package/src/Widget.ts +25 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import ActivityKit
|
|
3
|
+
|
|
4
|
+
internal class MissingCurrentWindowSceneException: Exception {
|
|
5
|
+
override var reason: String {
|
|
6
|
+
"Cannot determine the current window scene in which to present the modal for requesting a review."
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public class ReactNativeWidgetExtensionModule: Module {
|
|
11
|
+
// Each module class must implement the definition function. The definition consists of components
|
|
12
|
+
// that describes the module's functionality and behavior.
|
|
13
|
+
// See https://docs.expo.dev/modules/module-api for more details about available components.
|
|
14
|
+
public func definition() -> ModuleDefinition {
|
|
15
|
+
// Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument.
|
|
16
|
+
// Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
|
|
17
|
+
// The module will be accessible from `requireNativeModule('ReactNativeAppClip')` in JavaScript.
|
|
18
|
+
Name("ReactNativeWidgetExtension")
|
|
19
|
+
|
|
20
|
+
// Defines event names that the module can send to JavaScript.
|
|
21
|
+
Events("onChange")
|
|
22
|
+
|
|
23
|
+
Function("areActivitiesEnabled") { () -> Bool in
|
|
24
|
+
let logger = Logger()
|
|
25
|
+
logger.info("areActivitiesEnabled()")
|
|
26
|
+
|
|
27
|
+
if #available(iOS 16.2, *) {
|
|
28
|
+
return ActivityAuthorizationInfo().areActivitiesEnabled
|
|
29
|
+
} else {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Function("startActivity") { (numberOfPizzas: Int, totalAmount: String, orderNumber: String, driverName: String, minutes: Int, seconds: Int) -> Void in
|
|
35
|
+
let logger = Logger()
|
|
36
|
+
logger.info("startActivity()")
|
|
37
|
+
|
|
38
|
+
if #available(iOS 16.2, *) {
|
|
39
|
+
var future = Calendar.current.date(byAdding: .minute, value: (Int(minutes) ?? 0), to: Date())!
|
|
40
|
+
future = Calendar.current.date(byAdding: .second, value: (Int(seconds) ?? 0), to: future)!
|
|
41
|
+
let date = Date.now...future
|
|
42
|
+
let initialContentState = Attributes.ContentState(driverName: driverName, deliveryTimer: date)
|
|
43
|
+
let activityAttributes = Attributes(numberOfPizzas: numberOfPizzas, totalAmount: totalAmount, orderNumber: orderNumber)
|
|
44
|
+
|
|
45
|
+
let activityContent = ActivityContent(state: initialContentState, staleDate: Calendar.current.date(byAdding: .minute, value: 30, to: Date())!)
|
|
46
|
+
|
|
47
|
+
do {
|
|
48
|
+
let deliveryActivity = try Activity.request(attributes: activityAttributes, content: activityContent)
|
|
49
|
+
logger.info("Requested a pizza delivery Live Activity \(String(describing: deliveryActivity.id)).")
|
|
50
|
+
} catch (let error) {
|
|
51
|
+
logger.info("Error requesting pizza delivery Live Activity \(error.localizedDescription).")
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Function("updateActivity") { (driverName: String, minutes: Int, seconds: Int) -> Void in
|
|
57
|
+
let logger = Logger()
|
|
58
|
+
logger.info("updateActivity()")
|
|
59
|
+
|
|
60
|
+
if #available(iOS 16.2, *) {
|
|
61
|
+
var future = Calendar.current.date(byAdding: .minute, value: (Int(minutes) ?? 0), to: Date())!
|
|
62
|
+
future = Calendar.current.date(byAdding: .second, value: (Int(seconds) ?? 0), to: future)!
|
|
63
|
+
let date = Date.now...future
|
|
64
|
+
let updatedDeliveryStatus = Attributes.PizzaDeliveryStatus(driverName: driverName, deliveryTimer: date)
|
|
65
|
+
let alertConfiguration = AlertConfiguration(title: "Delivery update", body: "Your pizza order will arrive soon.", sound: .default)
|
|
66
|
+
let updatedContent = ActivityContent(state: updatedDeliveryStatus, staleDate: nil)
|
|
67
|
+
|
|
68
|
+
Task {
|
|
69
|
+
for activity in Activity<Attributes>.activities {
|
|
70
|
+
await activity.update(updatedContent, alertConfiguration: alertConfiguration)
|
|
71
|
+
logger.info("Updated the Live Activity: \(activity.id)")
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Function("endActivity") { (driverName: String) -> Void in
|
|
78
|
+
let logger = Logger()
|
|
79
|
+
logger.info("endActivity()")
|
|
80
|
+
|
|
81
|
+
if #available(iOS 16.2, *) {
|
|
82
|
+
let finalDeliveryStatus = Attributes.PizzaDeliveryStatus(driverName: driverName, deliveryTimer: Date.now...Date())
|
|
83
|
+
let finalContent = ActivityContent(state: finalDeliveryStatus, staleDate: nil)
|
|
84
|
+
|
|
85
|
+
Task {
|
|
86
|
+
for activity in Activity<Attributes>.activities {
|
|
87
|
+
await activity.end(finalContent, dismissalPolicy: .default)
|
|
88
|
+
logger.info("Ending the Live Activity: \(activity.id)")
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import WidgetKit
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
struct Provider: TimelineProvider {
|
|
5
|
+
func placeholder(in context: Context) -> SimpleEntry {
|
|
6
|
+
SimpleEntry(date: Date())
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
|
|
10
|
+
let entry = SimpleEntry(date: Date())
|
|
11
|
+
completion(entry)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
|
15
|
+
var entries: [SimpleEntry] = []
|
|
16
|
+
|
|
17
|
+
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
|
|
18
|
+
let currentDate = Date()
|
|
19
|
+
for hourOffset in 0 ..< 5 {
|
|
20
|
+
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
|
|
21
|
+
let entry = SimpleEntry(date: entryDate)
|
|
22
|
+
entries.append(entry)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let timeline = Timeline(entries: entries, policy: .atEnd)
|
|
26
|
+
completion(timeline)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
struct SimpleEntry: TimelineEntry {
|
|
31
|
+
let date: Date
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
struct PizzaDeliveryWidgetsEntryView : View {
|
|
35
|
+
var entry: Provider.Entry
|
|
36
|
+
|
|
37
|
+
var body: some View {
|
|
38
|
+
Text(entry.date, style: .time)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
struct PizzaDeliveryWidgets: Widget {
|
|
43
|
+
let kind: String = "PizzaDeliveryWidgets"
|
|
44
|
+
|
|
45
|
+
var body: some WidgetConfiguration {
|
|
46
|
+
StaticConfiguration(kind: kind, provider: Provider()) { entry in
|
|
47
|
+
PizzaDeliveryWidgetsEntryView(entry: entry)
|
|
48
|
+
}
|
|
49
|
+
.configurationDisplayName("My Widget")
|
|
50
|
+
.description("This is an example widget.")
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
struct PizzaDeliveryWidgets_Previews: PreviewProvider {
|
|
55
|
+
static var previews: some View {
|
|
56
|
+
PizzaDeliveryWidgetsEntryView(entry: SimpleEntry(date: Date()))
|
|
57
|
+
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
|
58
|
+
}
|
|
59
|
+
}
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("./plugin/build");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoWidget.d.ts","sourceRoot":"","sources":["../src/ExpoWidget.ts"],"names":[],"mappings":";AACA,wBAAiE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoWidget.js","sourceRoot":"","sources":["../src/ExpoWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,eAAe,mBAAmB,CAAC,4BAA4B,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from \"expo-modules-core\";\nexport default requireNativeModule(\"ReactNativeWidgetExtension\");\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactNativeWidgetExtensionModule.d.ts","sourceRoot":"","sources":["../src/ReactNativeWidgetExtensionModule.ts"],"names":[],"mappings":";AAIA,wBAAiE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { requireNativeModule } from "expo-modules-core";
|
|
2
|
+
// It loads the native module object from the JSI or falls back to
|
|
3
|
+
// the bridge module (from NativeModulesProxy) if the remote debugger is on.
|
|
4
|
+
export default requireNativeModule("ReactNativeWidgetExtension");
|
|
5
|
+
//# sourceMappingURL=ReactNativeWidgetExtensionModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactNativeWidgetExtensionModule.js","sourceRoot":"","sources":["../src/ReactNativeWidgetExtensionModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,kEAAkE;AAClE,4EAA4E;AAC5E,eAAe,mBAAmB,CAAC,4BAA4B,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from \"expo-modules-core\";\n\n// It loads the native module object from the JSI or falls back to\n// the bridge module (from NativeModulesProxy) if the remote debugger is on.\nexport default requireNativeModule(\"ReactNativeWidgetExtension\");\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Widget.d.ts","sourceRoot":"","sources":["../src/Widget.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,kBAAkB,qBAM9B,CAAC"}
|
package/build/Widget.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
import { requireNativeModule } from "expo-modules-core";
|
|
3
|
+
const ExpoWidget = Platform.OS === "ios"
|
|
4
|
+
? requireNativeModule("ReactNativeWidgetExtension")
|
|
5
|
+
: undefined;
|
|
6
|
+
const checkWidgetSupport = () => {
|
|
7
|
+
if (Platform.OS === "ios") {
|
|
8
|
+
return parseInt(Platform.Version, 10) >= 14;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
};
|
|
12
|
+
const supportWidgets = checkWidgetSupport();
|
|
13
|
+
export const reloadAllTimelines = async () => {
|
|
14
|
+
if (!supportWidgets || !ExpoWidget) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await ExpoWidget.reloadAllTimelines();
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=Widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Widget.js","sourceRoot":"","sources":["../src/Widget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,UAAU,GACd,QAAQ,CAAC,EAAE,KAAK,KAAK;IACnB,CAAC,CAAC,mBAAmB,CAAC,4BAA4B,CAAC;IACnD,CAAC,CAAC,SAAS,CAAC;AAEhB,MAAM,kBAAkB,GAAG,GAAG,EAAE;IAC9B,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;KAC7C;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,kBAAkB,EAAE,CAAC;AAE5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;IAC3C,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,EAAE;QAClC,OAAO;KACR;IAED,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import { Platform } from \"react-native\";\nimport { requireNativeModule } from \"expo-modules-core\";\n\nconst ExpoWidget =\n Platform.OS === \"ios\"\n ? requireNativeModule(\"ReactNativeWidgetExtension\")\n : undefined;\n\nconst checkWidgetSupport = () => {\n if (Platform.OS === \"ios\") {\n return parseInt(Platform.Version, 10) >= 14;\n }\n\n return false;\n};\n\nconst supportWidgets = checkWidgetSupport();\n\nexport const reloadAllTimelines = async () => {\n if (!supportWidgets || !ExpoWidget) {\n return;\n }\n\n await ExpoWidget.reloadAllTimelines();\n};\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'ReactNativeWidgetExtension'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.description = package['description']
|
|
10
|
+
s.license = package['license']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.homepage = package['homepage']
|
|
13
|
+
s.platform = :ios, '13.0'
|
|
14
|
+
s.swift_version = '5.4'
|
|
15
|
+
s.source = { git: 'https://github.com/bndkt/react-native-widget-extension' }
|
|
16
|
+
s.static_framework = true
|
|
17
|
+
|
|
18
|
+
s.dependency 'ExpoModulesCore'
|
|
19
|
+
|
|
20
|
+
# Swift/Objective-C compatibility
|
|
21
|
+
s.pod_target_xcconfig = {
|
|
22
|
+
'DEFINES_MODULE' => 'YES',
|
|
23
|
+
'SWIFT_COMPILATION_MODE' => 'wholemodule'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
s.source_files = "**/*.{h,m,swift}"
|
|
27
|
+
end
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-ios-widget",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Expo config plugin to add widgets to a React Native app",
|
|
5
|
+
"main": "build/Widget.js",
|
|
6
|
+
"types": "build/Widget.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc --build ./ ./plugin",
|
|
9
|
+
"dev": "tsc --build ./ ./plugin --watch"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"react-native",
|
|
13
|
+
"expo",
|
|
14
|
+
"react-native-ios-widget",
|
|
15
|
+
"ReactNativeIosWidget"
|
|
16
|
+
],
|
|
17
|
+
"repository": "https://github.com/adrianso/react-native-ios-widget",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/adrianso/react-native-ios-widget/issues"
|
|
20
|
+
},
|
|
21
|
+
"author": "Adrian So <adrian@sld.co.nz>",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"homepage": "https://github.com/adrianso/react-native-ios-widget",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@expo/config-plugins": "^6.0.2"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/jest": "^29.5.2",
|
|
29
|
+
"@types/node": "20.2.5",
|
|
30
|
+
"@types/react": "18.2.8",
|
|
31
|
+
"@types/react-native": "0.72.2",
|
|
32
|
+
"expo": "~48.0.19",
|
|
33
|
+
"expo-module-scripts": "3.0.9",
|
|
34
|
+
"expo-modules-core": "1.2.7",
|
|
35
|
+
"jest": "^29.5.0",
|
|
36
|
+
"react": "18.2.0",
|
|
37
|
+
"react-native": "0.72.0-rc.5",
|
|
38
|
+
"typescript": "^5.0.4"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"expo": "*",
|
|
42
|
+
"react": "*",
|
|
43
|
+
"react-native": "*"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.16.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withWidgetAndroid = void 0;
|
|
4
|
+
const withWidgetAndroidManifest_1 = require("./withWidgetAndroidManifest");
|
|
5
|
+
const withWidgetSourceCode_1 = require("./withWidgetSourceCode");
|
|
6
|
+
/**
|
|
7
|
+
* @param config
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
const withWidgetAndroid = (config, { widgetName, widgetsFolder }) => {
|
|
11
|
+
config = (0, withWidgetAndroidManifest_1.withWidgetAndroidManifest)(config, { widgetName });
|
|
12
|
+
// config = withWidgetProjectBuildGradle(config);
|
|
13
|
+
// config = withWidgetAppBuildGradle(config);
|
|
14
|
+
config = (0, withWidgetSourceCode_1.withWidgetSourceCode)(config, { widgetsFolder });
|
|
15
|
+
return config;
|
|
16
|
+
};
|
|
17
|
+
exports.withWidgetAndroid = withWidgetAndroid;
|
|
18
|
+
exports.default = exports.withWidgetAndroid;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withWidgetAndroidManifest = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
const buildWidgetsReceivers = async (widgetName) => {
|
|
6
|
+
return [
|
|
7
|
+
{
|
|
8
|
+
$: {
|
|
9
|
+
"android:name": widgetName,
|
|
10
|
+
"android:exported": "false",
|
|
11
|
+
},
|
|
12
|
+
"intent-filter": [
|
|
13
|
+
{
|
|
14
|
+
action: [
|
|
15
|
+
{
|
|
16
|
+
$: {
|
|
17
|
+
"android:name": "android.appwidget.action.APPWIDGET_UPDATE",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
"meta-data": [
|
|
24
|
+
{
|
|
25
|
+
$: {
|
|
26
|
+
"android:name": "android.appwidget.provider",
|
|
27
|
+
"android:resource": "@xml/widget_info",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
/*
|
|
34
|
+
<receiver
|
|
35
|
+
android:name=".SampleWidget"
|
|
36
|
+
android:exported="false">
|
|
37
|
+
<intent-filter>
|
|
38
|
+
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
|
39
|
+
</intent-filter>
|
|
40
|
+
|
|
41
|
+
<meta-data
|
|
42
|
+
android:name="android.appwidget.provider"
|
|
43
|
+
android:resource="@xml/sample_widget_info" />
|
|
44
|
+
</receiver>
|
|
45
|
+
*/
|
|
46
|
+
};
|
|
47
|
+
const withWidgetAndroidManifest = (config, { widgetName }) => {
|
|
48
|
+
return (0, config_plugins_1.withAndroidManifest)(config, async (newConfig) => {
|
|
49
|
+
const mainApplication = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(newConfig.modResults);
|
|
50
|
+
const widgetReceivers = await buildWidgetsReceivers(widgetName);
|
|
51
|
+
mainApplication.receiver = widgetReceivers;
|
|
52
|
+
return newConfig;
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
exports.withWidgetAndroidManifest = withWidgetAndroidManifest;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withWidgetAppBuildGradle = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
/**
|
|
6
|
+
* Add "apply plugin: kotlin-android" to app build.gradle
|
|
7
|
+
* @param config
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
const withWidgetAppBuildGradle = (config) => {
|
|
11
|
+
return (0, config_plugins_1.withAppBuildGradle)(config, async (newConfig) => {
|
|
12
|
+
const buildGradle = newConfig.modResults.contents;
|
|
13
|
+
const search = /(apply plugin: "com\.android\.application"\n)/gm;
|
|
14
|
+
const replace = `$1apply plugin: "kotlin-android"\n`;
|
|
15
|
+
const newBuildGradle = buildGradle.replace(search, replace);
|
|
16
|
+
newConfig.modResults.contents = newBuildGradle;
|
|
17
|
+
return newConfig;
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
exports.withWidgetAppBuildGradle = withWidgetAppBuildGradle;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withWidgetProjectBuildGradle = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
/**
|
|
6
|
+
* Add configuration of kotlin-gradle-plugin
|
|
7
|
+
* @param config
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
const withWidgetProjectBuildGradle = (config) => {
|
|
11
|
+
return (0, config_plugins_1.withProjectBuildGradle)(config, async (newConfig) => {
|
|
12
|
+
const buildGradle = newConfig.modResults.contents;
|
|
13
|
+
const search = /dependencies\s?{/;
|
|
14
|
+
const replace = `dependencies {
|
|
15
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:\${project.ext.kotlinVersion}"`;
|
|
16
|
+
const newBuildGradle = buildGradle.replace(search, replace);
|
|
17
|
+
newConfig.modResults.contents = newBuildGradle;
|
|
18
|
+
return newConfig;
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
exports.withWidgetProjectBuildGradle = withWidgetProjectBuildGradle;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.withWidgetSourceCode = void 0;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
8
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const glob_1 = require("glob");
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const copyResourceFiles = (widgetSourceDir, platformRoot) => {
|
|
13
|
+
const source = path_1.default.join(widgetSourceDir, "src", "main", "res");
|
|
14
|
+
const resDest = path_1.default.join(platformRoot, "app", "src", "main", "res");
|
|
15
|
+
console.log(`copy the res files from ${source} to ${resDest}`);
|
|
16
|
+
fs_extra_1.default.copySync(source, resDest);
|
|
17
|
+
};
|
|
18
|
+
const copyAssetFiles = (widgetSourceDir, platformRoot) => {
|
|
19
|
+
const source = path_1.default.join(widgetSourceDir, "src", "main", "assets");
|
|
20
|
+
const resDest = path_1.default.join(platformRoot, "app", "src", "main", "assets");
|
|
21
|
+
console.log(`copy the asset files from ${source} to ${resDest}`);
|
|
22
|
+
fs_extra_1.default.copySync(source, resDest);
|
|
23
|
+
};
|
|
24
|
+
const prepareSourceCodes = async (widgetSourceDir, platformRoot, packageName) => {
|
|
25
|
+
const source = path_1.default.join(widgetSourceDir, `src/main/java`);
|
|
26
|
+
const dest = path_1.default.join(platformRoot, "app/src/main/java");
|
|
27
|
+
console.log(`copy the kotlin codes from ${source} to ${dest}`);
|
|
28
|
+
fs_extra_1.default.copySync(source, dest);
|
|
29
|
+
const files = (0, glob_1.globSync)(`${dest}/**/*.java`);
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const content = fs_extra_1.default.readFileSync(file, "utf8");
|
|
32
|
+
const newContent = content.replace(/^package .*\s/, `package ${packageName};\n`);
|
|
33
|
+
fs_extra_1.default.writeFileSync(file, newContent);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const withWidgetSourceCode = (config, { widgetsFolder }) => {
|
|
37
|
+
return (0, config_plugins_1.withDangerousMod)(config, [
|
|
38
|
+
"android",
|
|
39
|
+
async (newConfig) => {
|
|
40
|
+
const projectRoot = newConfig.modRequest.projectRoot;
|
|
41
|
+
const platformRoot = newConfig.modRequest.platformProjectRoot;
|
|
42
|
+
const widgetDir = path_1.default.join(projectRoot, widgetsFolder);
|
|
43
|
+
copyResourceFiles(widgetDir, platformRoot);
|
|
44
|
+
copyAssetFiles(widgetDir, platformRoot);
|
|
45
|
+
const packageName = config.android?.package;
|
|
46
|
+
prepareSourceCodes(widgetDir, platformRoot, packageName);
|
|
47
|
+
return newConfig;
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
};
|
|
51
|
+
exports.withWidgetSourceCode = withWidgetSourceCode;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
declare const withWidget: ConfigPlugin<{
|
|
3
|
+
frequentUpdates?: boolean;
|
|
4
|
+
widgetsFolder?: string;
|
|
5
|
+
deploymentTarget?: string;
|
|
6
|
+
groupIdentifier?: string;
|
|
7
|
+
pods?: string[];
|
|
8
|
+
widgetName: string;
|
|
9
|
+
}>;
|
|
10
|
+
export default withWidget;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
4
|
+
const withXcode_1 = require("./withXcode");
|
|
5
|
+
const withWidgetExtensionEntitlements_1 = require("./withWidgetExtensionEntitlements");
|
|
6
|
+
const withPodfile_1 = require("./withPodfile");
|
|
7
|
+
const withConfig_1 = require("./withConfig");
|
|
8
|
+
const withWidget = (config, { frequentUpdates, deploymentTarget = "14.0", widgetsFolder = "widgets", groupIdentifier, pods, }) => {
|
|
9
|
+
const targetName = "WidgetsExtension";
|
|
10
|
+
const bundleIdentifier = `${config.ios?.bundleIdentifier}.Widgets`;
|
|
11
|
+
config.ios = {
|
|
12
|
+
...config.ios,
|
|
13
|
+
infoPlist: {
|
|
14
|
+
...config.ios?.infoPlist,
|
|
15
|
+
NSSupportsLiveActivities: true,
|
|
16
|
+
NSSupportsLiveActivitiesFrequentUpdates: frequentUpdates,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return (0, config_plugins_1.withPlugins)(config, [
|
|
20
|
+
[
|
|
21
|
+
withXcode_1.withXcode,
|
|
22
|
+
{
|
|
23
|
+
targetName,
|
|
24
|
+
bundleIdentifier,
|
|
25
|
+
deploymentTarget,
|
|
26
|
+
widgetsFolder,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
[withWidgetExtensionEntitlements_1.withWidgetExtensionEntitlements, { targetName, groupIdentifier }],
|
|
30
|
+
[withPodfile_1.withPodfile, { targetName, pods }],
|
|
31
|
+
[withConfig_1.withConfig, { targetName, bundleIdentifier, groupIdentifier }],
|
|
32
|
+
]);
|
|
33
|
+
};
|
|
34
|
+
exports.default = withWidget;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
declare const withWidgetIos: ConfigPlugin<{
|
|
3
|
+
frequentUpdates?: boolean;
|
|
4
|
+
widgetsFolder?: string;
|
|
5
|
+
deploymentTarget?: string;
|
|
6
|
+
groupIdentifier?: string;
|
|
7
|
+
pods?: string[];
|
|
8
|
+
}>;
|
|
9
|
+
export default withWidgetIos;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
4
|
+
const withConfig_1 = require("./withConfig");
|
|
5
|
+
const withPodfile_1 = require("./withPodfile");
|
|
6
|
+
const withXcode_1 = require("./withXcode");
|
|
7
|
+
const withWidgetExtensionEntitlements_1 = require("./withWidgetExtensionEntitlements");
|
|
8
|
+
const withWidgetIos = (config, { frequentUpdates, deploymentTarget = "14.0", widgetsFolder = "widgets", groupIdentifier, pods, }) => {
|
|
9
|
+
const targetName = "WidgetsExtension";
|
|
10
|
+
const bundleIdentifier = `${config.ios?.bundleIdentifier}.Widgets`;
|
|
11
|
+
config.ios = {
|
|
12
|
+
...config.ios,
|
|
13
|
+
infoPlist: {
|
|
14
|
+
...config.ios?.infoPlist,
|
|
15
|
+
NSSupportsLiveActivities: true,
|
|
16
|
+
NSSupportsLiveActivitiesFrequentUpdates: frequentUpdates,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return (0, config_plugins_1.withPlugins)(config, [
|
|
20
|
+
[
|
|
21
|
+
withXcode_1.withXcode,
|
|
22
|
+
{
|
|
23
|
+
targetName,
|
|
24
|
+
bundleIdentifier,
|
|
25
|
+
deploymentTarget,
|
|
26
|
+
widgetsFolder,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
[withWidgetExtensionEntitlements_1.withWidgetExtensionEntitlements, { targetName, groupIdentifier }],
|
|
30
|
+
[withPodfile_1.withPodfile, { targetName, pods }],
|
|
31
|
+
[withConfig_1.withConfig, { targetName, bundleIdentifier, groupIdentifier }],
|
|
32
|
+
]);
|
|
33
|
+
};
|
|
34
|
+
exports.default = withWidgetIos;
|