vxrn 2.0.0-beta.96.1 → 2.0.0-beta.97.1
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/dist/exports/prebuildWithoutExpo.mjs +289 -68
- package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
- package/dist/exports/prebuildWithoutExpo.native.js +298 -77
- package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
- package/dist/plugins/reactNativeDevServer.mjs +96 -0
- package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
- package/dist/plugins/reactNativeDevServer.native.js +98 -0
- package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
- package/dist/utils/createNativeDevEngine.mjs +1 -1
- package/dist/utils/createNativeDevEngine.mjs.map +1 -1
- package/dist/utils/createNativeDevEngine.native.js +2 -1
- package/dist/utils/createNativeDevEngine.native.js.map +1 -1
- package/package.json +11 -11
- package/src/exports/prebuildWithoutExpo.test.ts +215 -0
- package/src/exports/prebuildWithoutExpo.ts +292 -69
- package/src/plugins/reactNativeDevServer.ts +95 -0
- package/src/utils/createNativeDevEngine.test.ts +1 -1
- package/src/utils/createNativeDevEngine.ts +1 -1
- package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
- package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
|
@@ -333,7 +333,7 @@ ${anchor}`);
|
|
|
333
333
|
${ids.dependency} /* PBXTargetDependency */ = {isa = PBXTargetDependency; target = ${ids.target} /* OneWidgets */; targetProxy = ${ids.proxy} /* PBXContainerItemProxy */; };
|
|
334
334
|
/* End PBXTargetDependency section */
|
|
335
335
|
`);
|
|
336
|
-
const config = (id, mode) => ` ${id} /* ${mode} */ = {isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = OneWidgets/OneWidgets.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = ${app.ios?.buildNumber || "1"}; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = OneWidgets/WidgetInfo.plist; IPHONEOS_DEPLOYMENT_TARGET = ${deploymentTarget}; MARKETING_VERSION = "${app.version || "1.0"}"; PRODUCT_BUNDLE_IDENTIFIER = ${bundleId}.widgets; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1"; }; name = ${mode}; };`;
|
|
336
|
+
const config = (id, mode) => ` ${id} /* ${mode} */ = {isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = OneWidgets/OneWidgets.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = ${app.ios?.buildNumber || "1"}; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = OneWidgets/WidgetInfo.plist; IPHONEOS_DEPLOYMENT_TARGET = ${deploymentTarget}; MARKETING_VERSION = "${app.version || "1.0"}"; PRODUCT_BUNDLE_IDENTIFIER = ${bundleId}.widgets; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "${app.ios?.tablet ? "1,2" : "1"}"; }; name = ${mode}; };`;
|
|
337
337
|
insert("/* End XCBuildConfiguration section */", `${config(ids.debug, "Debug")}
|
|
338
338
|
${config(ids.release, "Release")}`);
|
|
339
339
|
insert("/* End XCConfigurationList section */", ` ${ids.config} /* Build configuration list for PBXNativeTarget "OneWidgets" */ = {isa = XCConfigurationList; buildConfigurations = (${ids.debug} /* Debug */, ${ids.release} /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; };`);
|
|
@@ -367,20 +367,13 @@ function generateSceneDelegate(args) {
|
|
|
367
367
|
const { dest, platform, app } = args;
|
|
368
368
|
if (platform !== "ios") return;
|
|
369
369
|
FSExtra.writeFileSync(path.join(dest, app.name, "SceneDelegate.swift"), renderSceneDelegateSwift(app.name));
|
|
370
|
-
if (app.notifications?.push === true) {
|
|
370
|
+
if (app.notifications?.push === true && !app.ios?.widgets) {
|
|
371
371
|
FSExtra.writeFileSync(path.join(dest, app.name, `${app.name}.entitlements`), renderPushEntitlements());
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
function generateIosWidgets(dest, app) {
|
|
375
375
|
const widgets = app.ios?.widgets;
|
|
376
376
|
if (!widgets) return;
|
|
377
|
-
if (widgets.jsx) {
|
|
378
|
-
try {
|
|
379
|
-
module.createRequire(dest + "/").resolve("@use-voltra/ios-client/package.json");
|
|
380
|
-
} catch {
|
|
381
|
-
throw new Error("[vxrn] native.app.ios.widgets.jsx requires @use-voltra/ios-client");
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
377
|
const appDir = path.join(dest, app.name);
|
|
385
378
|
const extensionDir = path.join(dest, "OneWidgets");
|
|
386
379
|
FSExtra.mkdirSync(extensionDir, { recursive: true });
|
|
@@ -388,7 +381,7 @@ function generateIosWidgets(dest, app) {
|
|
|
388
381
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
389
382
|
<plist version="1.0"><dict><key>com.apple.security.application-groups</key><array><string>${escapeXml(widgets.appGroup)}</string></array></dict></plist>
|
|
390
383
|
`;
|
|
391
|
-
FSExtra.writeFileSync(path.join(appDir, "OneAppWidgets.entitlements"), widgets.pushNotifications ? entitlements.replace("</dict></plist>", "<key>aps-environment</key><string>development</string></dict></plist>") : entitlements);
|
|
384
|
+
FSExtra.writeFileSync(path.join(appDir, "OneAppWidgets.entitlements"), widgets.pushNotifications || app.notifications?.push ? entitlements.replace("</dict></plist>", "<key>aps-environment</key><string>development</string></dict></plist>") : entitlements);
|
|
392
385
|
FSExtra.writeFileSync(path.join(extensionDir, "OneWidgets.entitlements"), entitlements);
|
|
393
386
|
FSExtra.writeFileSync(path.join(extensionDir, "WidgetInfo.plist"), `<?xml version="1.0" encoding="UTF-8"?>
|
|
394
387
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -403,7 +396,6 @@ function generateIosWidgets(dest, app) {
|
|
|
403
396
|
<key>CFBundleShortVersionString</key><string>${escapeXml(app.version || "1.0")}</string>
|
|
404
397
|
<key>CFBundleVersion</key><string>${escapeXml(app.ios?.buildNumber || "1")}</string>
|
|
405
398
|
<key>NSExtension</key><dict><key>NSExtensionPointIdentifier</key><string>com.apple.widgetkit-extension</string></dict>
|
|
406
|
-
${widgets.jsx ? `<key>Voltra_AppGroupIdentifier</key><string>${escapeXml(widgets.appGroup)}</string>` : ""}
|
|
407
399
|
</dict></plist>
|
|
408
400
|
`);
|
|
409
401
|
FSExtra.writeFileSync(path.join(appDir, "OneWidgetContract.swift"), `import Foundation
|
|
@@ -418,12 +410,14 @@ enum OneWidgetContract {
|
|
|
418
410
|
let title: String
|
|
419
411
|
let value: String
|
|
420
412
|
let subtitle: String
|
|
413
|
+
let layout: String?
|
|
421
414
|
}
|
|
422
415
|
|
|
423
416
|
struct Attributes: ActivityAttributes {
|
|
424
417
|
struct ContentState: Codable, Hashable {
|
|
425
418
|
let status: String
|
|
426
419
|
let value: String
|
|
420
|
+
let layout: String?
|
|
427
421
|
}
|
|
428
422
|
let title: String
|
|
429
423
|
}
|
|
@@ -432,7 +426,163 @@ enum OneWidgetContract {
|
|
|
432
426
|
FSExtra.writeFileSync(path.join(extensionDir, "OneWidget.swift"), `import SwiftUI
|
|
433
427
|
import WidgetKit
|
|
434
428
|
import ActivityKit
|
|
435
|
-
|
|
429
|
+
|
|
430
|
+
struct OneWidgetNode: Decodable {
|
|
431
|
+
let type: String
|
|
432
|
+
let text: String?
|
|
433
|
+
let style: Style?
|
|
434
|
+
let children: [OneWidgetNode]?
|
|
435
|
+
let systemName: String?
|
|
436
|
+
let value: Double?
|
|
437
|
+
let total: Double?
|
|
438
|
+
let fill: String?
|
|
439
|
+
let cornerRadius: Double?
|
|
440
|
+
let url: String?
|
|
441
|
+
|
|
442
|
+
struct Style: Decodable {
|
|
443
|
+
let color: String?
|
|
444
|
+
let backgroundColor: String?
|
|
445
|
+
let fontSize: Double?
|
|
446
|
+
let fontWeight: String?
|
|
447
|
+
let fontDesign: String?
|
|
448
|
+
let padding: Double?
|
|
449
|
+
let borderRadius: Double?
|
|
450
|
+
let spacing: Double?
|
|
451
|
+
let width: Double?
|
|
452
|
+
let height: Double?
|
|
453
|
+
let opacity: Double?
|
|
454
|
+
let lineLimit: Int?
|
|
455
|
+
let alignment: String?
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
struct OneActivityView: Decodable {
|
|
460
|
+
let lockScreen: OneWidgetNode
|
|
461
|
+
let compactLeading: OneWidgetNode?
|
|
462
|
+
let compactTrailing: OneWidgetNode?
|
|
463
|
+
let minimal: OneWidgetNode?
|
|
464
|
+
let expandedLeading: OneWidgetNode?
|
|
465
|
+
let expandedTrailing: OneWidgetNode?
|
|
466
|
+
let expandedBottom: OneWidgetNode?
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
private func oneDecode<T: Decodable>(_ value: String?, as type: T.Type) -> T? {
|
|
470
|
+
guard let value, let data = value.data(using: .utf8) else { return nil }
|
|
471
|
+
return try? JSONDecoder().decode(type, from: data)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private func oneColor(_ hex: String?) -> Color? {
|
|
475
|
+
guard let hex, hex.count == 7, hex.first == "#",
|
|
476
|
+
let rgb = Int(hex.dropFirst(), radix: 16) else { return nil }
|
|
477
|
+
return Color(red: Double((rgb >> 16) & 255) / 255,
|
|
478
|
+
green: Double((rgb >> 8) & 255) / 255,
|
|
479
|
+
blue: Double(rgb & 255) / 255)
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
struct OneWidgetRendered: View {
|
|
483
|
+
let node: OneWidgetNode
|
|
484
|
+
|
|
485
|
+
private var alignment: Alignment {
|
|
486
|
+
switch node.style?.alignment {
|
|
487
|
+
case "leading": .leading
|
|
488
|
+
case "trailing": .trailing
|
|
489
|
+
default: .center
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
private var horizontalAlignment: HorizontalAlignment {
|
|
494
|
+
switch node.style?.alignment {
|
|
495
|
+
case "center": .center
|
|
496
|
+
case "trailing": .trailing
|
|
497
|
+
default: .leading
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
private var weight: Font.Weight {
|
|
502
|
+
switch node.style?.fontWeight {
|
|
503
|
+
case "medium": .medium
|
|
504
|
+
case "semibold": .semibold
|
|
505
|
+
case "bold": .bold
|
|
506
|
+
default: .regular
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
private var design: Font.Design {
|
|
511
|
+
switch node.style?.fontDesign {
|
|
512
|
+
case "rounded": .rounded
|
|
513
|
+
case "serif": .serif
|
|
514
|
+
case "monospaced": .monospaced
|
|
515
|
+
default: .default
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
var body: some View {
|
|
520
|
+
Group {
|
|
521
|
+
switch node.type {
|
|
522
|
+
case "text":
|
|
523
|
+
Text(node.text ?? "")
|
|
524
|
+
.font(.system(size: CGFloat(node.style?.fontSize ?? 16), weight: weight, design: design))
|
|
525
|
+
case "vstack":
|
|
526
|
+
VStack(alignment: horizontalAlignment, spacing: CGFloat(node.style?.spacing ?? 8)) {
|
|
527
|
+
ForEach(Array((node.children ?? []).enumerated()), id: \\.offset) { _, child in
|
|
528
|
+
OneWidgetRendered(node: child)
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
case "hstack":
|
|
532
|
+
HStack(spacing: CGFloat(node.style?.spacing ?? 8)) {
|
|
533
|
+
ForEach(Array((node.children ?? []).enumerated()), id: \\.offset) { _, child in
|
|
534
|
+
OneWidgetRendered(node: child)
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
case "zstack":
|
|
538
|
+
ZStack(alignment: alignment) {
|
|
539
|
+
ForEach(Array((node.children ?? []).enumerated()), id: \\.offset) { _, child in
|
|
540
|
+
OneWidgetRendered(node: child)
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
case "spacer": Spacer(minLength: 0)
|
|
544
|
+
case "divider": Divider()
|
|
545
|
+
case "image":
|
|
546
|
+
if let systemName = node.systemName {
|
|
547
|
+
Image(systemName: systemName)
|
|
548
|
+
.font(.system(size: CGFloat(node.style?.fontSize ?? 20), weight: weight))
|
|
549
|
+
}
|
|
550
|
+
case "progress":
|
|
551
|
+
ProgressView(value: node.value ?? 0, total: node.total ?? 1)
|
|
552
|
+
.tint(oneColor(node.style?.color))
|
|
553
|
+
case "gauge":
|
|
554
|
+
Gauge(value: node.value ?? 0, in: 0...(node.total ?? 1)) { EmptyView() }
|
|
555
|
+
.gaugeStyle(.accessoryCircular)
|
|
556
|
+
.tint(oneColor(node.style?.color))
|
|
557
|
+
case "circle":
|
|
558
|
+
Circle().fill(oneColor(node.fill) ?? .primary)
|
|
559
|
+
case "rectangle":
|
|
560
|
+
Rectangle().fill(oneColor(node.fill) ?? .primary)
|
|
561
|
+
case "rounded-rectangle":
|
|
562
|
+
RoundedRectangle(cornerRadius: CGFloat(node.cornerRadius ?? 8))
|
|
563
|
+
.fill(oneColor(node.fill) ?? .primary)
|
|
564
|
+
case "link":
|
|
565
|
+
if let url = node.url.flatMap(URL.init(string:)) {
|
|
566
|
+
Link(destination: url) {
|
|
567
|
+
ForEach(Array((node.children ?? []).enumerated()), id: \\.offset) { _, child in
|
|
568
|
+
OneWidgetRendered(node: child)
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
default: EmptyView()
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
.foregroundColor(oneColor(node.style?.color))
|
|
576
|
+
.lineLimit(node.style?.lineLimit)
|
|
577
|
+
.frame(width: node.style?.width.map { CGFloat($0) },
|
|
578
|
+
height: node.style?.height.map { CGFloat($0) },
|
|
579
|
+
alignment: alignment)
|
|
580
|
+
.opacity(node.style?.opacity ?? 1)
|
|
581
|
+
.padding(CGFloat(node.style?.padding ?? 0))
|
|
582
|
+
.background { if let fill = oneColor(node.style?.backgroundColor) { fill } }
|
|
583
|
+
.clipShape(RoundedRectangle(cornerRadius: CGFloat(node.style?.borderRadius ?? 0)))
|
|
584
|
+
}
|
|
585
|
+
}
|
|
436
586
|
|
|
437
587
|
struct OneWidgetEntry: TimelineEntry {
|
|
438
588
|
let date: Date
|
|
@@ -441,7 +591,7 @@ struct OneWidgetEntry: TimelineEntry {
|
|
|
441
591
|
|
|
442
592
|
struct OneWidgetProvider: TimelineProvider {
|
|
443
593
|
func placeholder(in context: Context) -> OneWidgetEntry {
|
|
444
|
-
OneWidgetEntry(date: .now, data: .init(title: ${JSON.stringify(widgets.displayName)}, value: "", subtitle: ""))
|
|
594
|
+
OneWidgetEntry(date: .now, data: .init(title: ${JSON.stringify(widgets.displayName)}, value: "", subtitle: "", layout: nil))
|
|
445
595
|
}
|
|
446
596
|
|
|
447
597
|
func getSnapshot(in context: Context, completion: @escaping (OneWidgetEntry) -> Void) {
|
|
@@ -455,7 +605,7 @@ struct OneWidgetProvider: TimelineProvider {
|
|
|
455
605
|
private func entry() -> OneWidgetEntry {
|
|
456
606
|
let stored = UserDefaults(suiteName: OneWidgetContract.appGroup)?.data(forKey: OneWidgetContract.dataKey)
|
|
457
607
|
let data = stored.flatMap { try? JSONDecoder().decode(OneWidgetContract.Data.self, from: $0) }
|
|
458
|
-
?? .init(title: ${JSON.stringify(widgets.displayName)}, value: "", subtitle: "")
|
|
608
|
+
?? .init(title: ${JSON.stringify(widgets.displayName)}, value: "", subtitle: "", layout: nil)
|
|
459
609
|
return OneWidgetEntry(date: .now, data: data)
|
|
460
610
|
}
|
|
461
611
|
}
|
|
@@ -463,10 +613,16 @@ struct OneWidgetProvider: TimelineProvider {
|
|
|
463
613
|
struct OneWidget: Widget {
|
|
464
614
|
var body: some WidgetConfiguration {
|
|
465
615
|
StaticConfiguration(kind: OneWidgetContract.kind, provider: OneWidgetProvider()) { entry in
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
616
|
+
Group {
|
|
617
|
+
if let layout = oneDecode(entry.data.layout, as: OneWidgetNode.self) {
|
|
618
|
+
OneWidgetRendered(node: layout)
|
|
619
|
+
} else {
|
|
620
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
621
|
+
Text(entry.data.title).font(.headline)
|
|
622
|
+
Text(entry.data.value).font(.title2).bold()
|
|
623
|
+
Text(entry.data.subtitle).font(.caption)
|
|
624
|
+
}
|
|
625
|
+
}
|
|
470
626
|
}
|
|
471
627
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
|
|
472
628
|
.containerBackground(.fill.tertiary, for: .widget)
|
|
@@ -480,53 +636,78 @@ struct OneWidget: Widget {
|
|
|
480
636
|
struct OneLiveActivity: Widget {
|
|
481
637
|
var body: some WidgetConfiguration {
|
|
482
638
|
ActivityConfiguration(for: OneWidgetContract.Attributes.self) { context in
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
639
|
+
Group {
|
|
640
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self) {
|
|
641
|
+
OneWidgetRendered(node: layout.lockScreen)
|
|
642
|
+
} else {
|
|
643
|
+
HStack {
|
|
644
|
+
VStack(alignment: .leading) {
|
|
645
|
+
Text(context.attributes.title).font(.headline)
|
|
646
|
+
Text(context.state.status)
|
|
647
|
+
}
|
|
648
|
+
Spacer()
|
|
649
|
+
Text(context.state.value).bold()
|
|
650
|
+
}
|
|
487
651
|
}
|
|
488
|
-
Spacer()
|
|
489
|
-
Text(context.state.value).bold()
|
|
490
652
|
}
|
|
491
653
|
.padding()
|
|
492
654
|
.activityBackgroundTint(.blue.opacity(0.2))
|
|
493
655
|
} dynamicIsland: { context in
|
|
494
656
|
DynamicIsland {
|
|
495
|
-
DynamicIslandExpandedRegion(.leading) {
|
|
496
|
-
|
|
497
|
-
|
|
657
|
+
DynamicIslandExpandedRegion(.leading) {
|
|
658
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self),
|
|
659
|
+
let leading = layout.expandedLeading {
|
|
660
|
+
OneWidgetRendered(node: leading)
|
|
661
|
+
} else {
|
|
662
|
+
Text(context.attributes.title)
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
DynamicIslandExpandedRegion(.trailing) {
|
|
666
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self),
|
|
667
|
+
let trailing = layout.expandedTrailing {
|
|
668
|
+
OneWidgetRendered(node: trailing)
|
|
669
|
+
} else {
|
|
670
|
+
Text(context.state.value)
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
DynamicIslandExpandedRegion(.bottom) {
|
|
674
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self) {
|
|
675
|
+
OneWidgetRendered(node: layout.expandedBottom ?? layout.lockScreen)
|
|
676
|
+
} else {
|
|
677
|
+
Text(context.state.status)
|
|
678
|
+
}
|
|
679
|
+
}
|
|
498
680
|
} compactLeading: {
|
|
499
|
-
|
|
681
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self),
|
|
682
|
+
let leading = layout.compactLeading {
|
|
683
|
+
OneWidgetRendered(node: leading)
|
|
684
|
+
} else {
|
|
685
|
+
Text(context.attributes.title)
|
|
686
|
+
}
|
|
500
687
|
} compactTrailing: {
|
|
501
|
-
|
|
688
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self),
|
|
689
|
+
let trailing = layout.compactTrailing {
|
|
690
|
+
OneWidgetRendered(node: trailing)
|
|
691
|
+
} else {
|
|
692
|
+
Text(context.state.value)
|
|
693
|
+
}
|
|
502
694
|
} minimal: {
|
|
503
|
-
|
|
695
|
+
if let layout = oneDecode(context.state.layout, as: OneActivityView.self),
|
|
696
|
+
let minimal = layout.minimal {
|
|
697
|
+
OneWidgetRendered(node: minimal)
|
|
698
|
+
} else {
|
|
699
|
+
Text(context.state.value)
|
|
700
|
+
}
|
|
504
701
|
}
|
|
505
702
|
}
|
|
506
703
|
}
|
|
507
704
|
}
|
|
508
705
|
|
|
509
|
-
${widgets.jsx ? `struct OneJSXWidget: Widget {
|
|
510
|
-
private let widgetId = ${JSON.stringify(widgets.jsx.id)}
|
|
511
|
-
|
|
512
|
-
var body: some WidgetConfiguration {
|
|
513
|
-
StaticConfiguration(kind: "Voltra_Widget_${widgets.jsx.id}", provider: VoltraHomeWidgetProvider(widgetId: widgetId)) { entry in
|
|
514
|
-
VoltraHomeWidgetView(entry: entry)
|
|
515
|
-
}
|
|
516
|
-
.configurationDisplayName(${JSON.stringify(widgets.jsx.displayName)})
|
|
517
|
-
.description(${JSON.stringify(widgets.jsx.description)})
|
|
518
|
-
.supportedFamilies([.systemSmall, .systemMedium])
|
|
519
|
-
.contentMarginsDisabled()
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
` : ""}
|
|
523
|
-
|
|
524
706
|
@main
|
|
525
707
|
struct OneWidgetsBundle: WidgetBundle {
|
|
526
708
|
var body: some Widget {
|
|
527
709
|
OneWidget()
|
|
528
710
|
OneLiveActivity()
|
|
529
|
-
${widgets.jsx ? "OneJSXWidget()\n VoltraWidget()" : ""}
|
|
530
711
|
}
|
|
531
712
|
}
|
|
532
713
|
`);
|
|
@@ -535,8 +716,11 @@ struct OneWidgetsBundle: WidgetBundle {
|
|
|
535
716
|
|
|
536
717
|
@interface RCT_EXTERN_MODULE(OneWidgetsBridge, RCTEventEmitter)
|
|
537
718
|
RCT_EXTERN_METHOD(writeWidget:(NSString *)title value:(NSString *)value subtitle:(NSString *)subtitle resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
719
|
+
RCT_EXTERN_METHOD(writeView:(NSString *)layout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
538
720
|
RCT_EXTERN_METHOD(start:(NSString *)title status:(NSString *)status value:(NSString *)value push:(BOOL)push resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
721
|
+
RCT_EXTERN_METHOD(startView:(NSString *)title layout:(NSString *)layout push:(BOOL)push resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
539
722
|
RCT_EXTERN_METHOD(update:(NSString *)identifier status:(NSString *)status value:(NSString *)value resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
723
|
+
RCT_EXTERN_METHOD(updateView:(NSString *)identifier layout:(NSString *)layout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
540
724
|
RCT_EXTERN_METHOD(end:(NSString *)identifier resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
541
725
|
RCT_EXTERN_METHOD(pushToken:(NSString *)identifier resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
542
726
|
@end
|
|
@@ -583,7 +767,24 @@ class OneWidgetsBridge: RCTEventEmitter {
|
|
|
583
767
|
return
|
|
584
768
|
}
|
|
585
769
|
do {
|
|
586
|
-
defaults.set(try JSONEncoder().encode(OneWidgetContract.Data(title: title, value: value, subtitle: subtitle)),
|
|
770
|
+
defaults.set(try JSONEncoder().encode(OneWidgetContract.Data(title: title, value: value, subtitle: subtitle, layout: nil)),
|
|
771
|
+
forKey: OneWidgetContract.dataKey)
|
|
772
|
+
WidgetCenter.shared.reloadTimelines(ofKind: OneWidgetContract.kind)
|
|
773
|
+
resolve(nil)
|
|
774
|
+
} catch {
|
|
775
|
+
reject("widget_write", error.localizedDescription, error)
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
@objc(writeView:resolver:rejecter:)
|
|
780
|
+
func writeView(_ layout: String, resolver resolve: RCTPromiseResolveBlock,
|
|
781
|
+
rejecter reject: RCTPromiseRejectBlock) {
|
|
782
|
+
guard let defaults = UserDefaults(suiteName: OneWidgetContract.appGroup) else {
|
|
783
|
+
reject("app_group", "Cannot open the configured App Group", nil)
|
|
784
|
+
return
|
|
785
|
+
}
|
|
786
|
+
do {
|
|
787
|
+
defaults.set(try JSONEncoder().encode(OneWidgetContract.Data(title: "", value: "", subtitle: "", layout: layout)),
|
|
587
788
|
forKey: OneWidgetContract.dataKey)
|
|
588
789
|
WidgetCenter.shared.reloadTimelines(ofKind: OneWidgetContract.kind)
|
|
589
790
|
resolve(nil)
|
|
@@ -602,7 +803,27 @@ class OneWidgetsBridge: RCTEventEmitter {
|
|
|
602
803
|
do {
|
|
603
804
|
let activity = try Activity<OneWidgetContract.Attributes>.request(
|
|
604
805
|
attributes: .init(title: title),
|
|
605
|
-
content: .init(state: .init(status: status, value: value), staleDate: nil),
|
|
806
|
+
content: .init(state: .init(status: status, value: value, layout: nil), staleDate: nil),
|
|
807
|
+
pushType: push ? .token : nil
|
|
808
|
+
)
|
|
809
|
+
observeToken(activity)
|
|
810
|
+
resolve(activity.id)
|
|
811
|
+
} catch {
|
|
812
|
+
reject("activity_start", error.localizedDescription, error)
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
@objc(startView:layout:push:resolver:rejecter:)
|
|
817
|
+
func startView(_ title: String, layout: String, push: Bool,
|
|
818
|
+
resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
|
|
819
|
+
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
|
|
820
|
+
reject("activities_disabled", "Live Activities are disabled", nil)
|
|
821
|
+
return
|
|
822
|
+
}
|
|
823
|
+
do {
|
|
824
|
+
let activity = try Activity<OneWidgetContract.Attributes>.request(
|
|
825
|
+
attributes: .init(title: title),
|
|
826
|
+
content: .init(state: .init(status: "", value: "", layout: layout), staleDate: nil),
|
|
606
827
|
pushType: push ? .token : nil
|
|
607
828
|
)
|
|
608
829
|
observeToken(activity)
|
|
@@ -620,7 +841,20 @@ class OneWidgetsBridge: RCTEventEmitter {
|
|
|
620
841
|
return
|
|
621
842
|
}
|
|
622
843
|
Task {
|
|
623
|
-
await activity.update(.init(state: .init(status: status, value: value), staleDate: nil))
|
|
844
|
+
await activity.update(.init(state: .init(status: status, value: value, layout: nil), staleDate: nil))
|
|
845
|
+
resolve(nil)
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
@objc(updateView:layout:resolver:rejecter:)
|
|
850
|
+
func updateView(_ identifier: String, layout: String,
|
|
851
|
+
resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
852
|
+
guard let activity = Activity<OneWidgetContract.Attributes>.activities.first(where: { $0.id == identifier }) else {
|
|
853
|
+
reject("activity_missing", "Live Activity not found", nil)
|
|
854
|
+
return
|
|
855
|
+
}
|
|
856
|
+
Task {
|
|
857
|
+
await activity.update(.init(state: .init(status: "", value: "", layout: layout), staleDate: nil))
|
|
624
858
|
resolve(nil)
|
|
625
859
|
}
|
|
626
860
|
}
|
|
@@ -646,7 +880,11 @@ class OneWidgetsBridge: RCTEventEmitter {
|
|
|
646
880
|
reject("activity_missing", "Live Activity not found", nil)
|
|
647
881
|
return
|
|
648
882
|
}
|
|
649
|
-
|
|
883
|
+
if let data = activity.pushToken {
|
|
884
|
+
resolve(data.map { String(format: "%02x", $0) }.joined())
|
|
885
|
+
} else {
|
|
886
|
+
resolve(NSNull())
|
|
887
|
+
}
|
|
650
888
|
}
|
|
651
889
|
}
|
|
652
890
|
`);
|
|
@@ -869,13 +1107,6 @@ ${schemes.map((scheme) => ` <string>${scheme}</string>`).join("\n")}
|
|
|
869
1107
|
}
|
|
870
1108
|
if (app.ios?.widgets) {
|
|
871
1109
|
stamps.push(" <key>NSSupportsLiveActivities</key>\n <true/>");
|
|
872
|
-
if (app.ios.widgets.jsx) {
|
|
873
|
-
stamps.push(` <key>Voltra_AppGroupIdentifier</key>
|
|
874
|
-
<string>${escapeXml(app.ios.widgets.appGroup)}</string>`);
|
|
875
|
-
if (app.ios.widgets.pushNotifications) {
|
|
876
|
-
stamps.push(" <key>Voltra_EnablePushNotifications</key>\n <true/>");
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
1110
|
}
|
|
880
1111
|
if (stamps.length) {
|
|
881
1112
|
const anchor = " <key>LSRequiresIPhoneOS</key>";
|
|
@@ -1000,7 +1231,7 @@ end`);
|
|
|
1000
1231
|
if (platform === "ios" && relativePath.endsWith(".xcodeproj/project.pbxproj")) {
|
|
1001
1232
|
rendered = patchIosBundlePhase(rendered);
|
|
1002
1233
|
rendered = patchIosPbxprojSceneDelegate(rendered, appName);
|
|
1003
|
-
if (app.notifications?.push === true) {
|
|
1234
|
+
if (app.notifications?.push === true && !app.ios?.widgets) {
|
|
1004
1235
|
rendered = patchIosPbxprojPushEntitlements(rendered, appName);
|
|
1005
1236
|
}
|
|
1006
1237
|
if (app.ios?.widgets) rendered = patchIosPbxprojWidgets(rendered, app);
|
|
@@ -1019,16 +1250,6 @@ use_frameworks! :linkage => :${app.ios.useFrameworks}`);
|
|
|
1019
1250
|
rendered = nativeProjectPatches.injectOneSwiftPackagesIntoPodfile(rendered);
|
|
1020
1251
|
if (nitroWebImage) rendered = nativeProjectPatches.injectNitroWebImageModularHeaderIntoPodfile(rendered);
|
|
1021
1252
|
rendered = nativeProjectPatches.injectHermesMinificationPatchIntoPodfile(rendered);
|
|
1022
|
-
if (app.ios?.widgets?.jsx) {
|
|
1023
|
-
rendered += `
|
|
1024
|
-
# jsx widgets use Voltra's SwiftUI renderer in One's generated extension
|
|
1025
|
-
target 'OneWidgets' do
|
|
1026
|
-
client = \`node --print "require.resolve('@use-voltra/ios-client/package.json', {paths: ['#{Pod::Config.instance.installation_root}/..']})"\`.strip
|
|
1027
|
-
raise 'Install @use-voltra/ios-client to build the JSX widget' if client.empty?
|
|
1028
|
-
pod 'VoltraWidget', :path => File.join(File.dirname(client), 'ios')
|
|
1029
|
-
end
|
|
1030
|
-
`;
|
|
1031
|
-
}
|
|
1032
1253
|
if (!rendered.includes("[vxrn/one] fmt c++17 fix") || !rendered.includes("[vxrn/one] minify iOS Hermes Release bundle input")) {
|
|
1033
1254
|
throw new Error("[vxrn] failed to apply required iOS Podfile patches");
|
|
1034
1255
|
}
|