diff --git a/packages/react-native-device-activity/ios/Labels.swift b/packages/react-native-device-activity/ios/Labels.swift new file mode 100644 index 0000000..eb19925 --- /dev/null +++ b/packages/react-native-device-activity/ios/Labels.swift @@ -0,0 +1,95 @@ +// +// ScreenTimeActivityPicker.swift +// ReactNativeDeviceActivity +// +// Created by Robert Herber on 2023-07-05. +// + +import ExpoModulesCore +import FamilyControls +import Foundation +import ManagedSettings +import SwiftUI + +@available(iOS 15.2, *) +struct ActivityCategoryLabel: View { + var token: ActivityCategoryToken + + var body: some View { + Label(token) + } +} + +@available(iOS 15.2, *) +struct ApplicationLabel: View { + var token: ApplicationToken? + + var body: some View { + if let token = token { + Label(token) + } + } +} + +@available(iOS 15.2, *) +struct WebDomainLabel: View { + var token: Token? + + var body: some View { + if let token = token { + Label(token) + } + } +} + +@available(iOS 15.2, *) +struct AnyTokenLabel: View { + var token: Token? + + var body: some View { + if let token = token { + if let webDomainToken = token as? Token { + WebDomainLabel(token: webDomainToken) + } else if let applicationToken = token as? Token { + ApplicationLabel(token: applicationToken) + } else if let activityCategoryToken = token as? Token { + ActivityCategoryLabel(token: activityCategoryToken) + } + } + } +} + +@available(iOS 15.2, *) +class WebDomainLabelView: ExpoView { + private var _token: WebDomainToken? + var token: WebDomainToken? { + get { _token } + set { + _token = newValue + contentView.rootView.token = newValue + } + } + + let contentView: UIHostingController + + required init(appContext: AppContext? = nil) { + contentView = UIHostingController( + rootView: WebDomainLabel(token: _token) + ) + + super.init(appContext: appContext) + + clipsToBounds = true + backgroundColor = .clear + isUserInteractionEnabled = false + + contentView.view.backgroundColor = .clear + contentView.view.isUserInteractionEnabled = false + + self.addSubview(contentView.view) + } + + override func layoutSubviews() { + contentView.view.frame = bounds + } +} diff --git a/packages/react-native-device-activity/ios/ReactNativeDeviceActivityModule.swift b/packages/react-native-device-activity/ios/ReactNativeDeviceActivityModule.swift index 655ce1b..20c8f82 100644 --- a/packages/react-native-device-activity/ios/ReactNativeDeviceActivityModule.swift +++ b/packages/react-native-device-activity/ios/ReactNativeDeviceActivityModule.swift @@ -688,7 +688,7 @@ public class ReactNativeDeviceActivityModule: Module { let activitySelection = parseActivitySelectionInput(input: familyActivitySelection) - try blockSelectedApps( + blockSelectedApps( blockSelection: activitySelection, triggeredBy: triggeredBy ) @@ -810,15 +810,18 @@ public class ReactNativeDeviceActivityModule: Module { } Prop("footerText") { (view: ReactNativeDeviceActivityView, prop: String?) in - view.model.footerText = prop - } Prop("headerText") { (view: ReactNativeDeviceActivityView, prop: String?) in - view.model.headerText = prop + } + } + View(WebDomainLabelView.self) { + // Defines a setter for the `name` prop. + Prop("token") { (view: WebDomainLabelView, token: String) in + view.token = deserializeToken(tokenStr: token) } } } diff --git a/packages/react-native-device-activity/ios/ReactNativeDeviceActivityViewPersisted.swift b/packages/react-native-device-activity/ios/ReactNativeDeviceActivityViewPersisted.swift index ea3cde0..6690acc 100644 --- a/packages/react-native-device-activity/ios/ReactNativeDeviceActivityViewPersisted.swift +++ b/packages/react-native-device-activity/ios/ReactNativeDeviceActivityViewPersisted.swift @@ -4,6 +4,27 @@ import FamilyControls import SwiftUI import UIKit +let selection = FamilyActivitySelection() + +/*@available(iOS 15.2, *) +class ExpoWebView: ExpoView { + let webView = Label(selection.categoryTokens.first!) + + required init(appContext: AppContext? = nil) { + super.init(appContext: appContext) + clipsToBounds = true + addSubview(webView) + + let url = URL(string:"https://docs.expo.dev/modules/")! + let urlRequest = URLRequest(url:url) + webView.load(urlRequest) + } + + override func layoutSubviews() { + webView.frame = bounds + } +}*/ + @available(iOS 15.0, *) class ReactNativeDeviceActivityViewPersisted: ExpoView { diff --git a/packages/react-native-device-activity/ios/ScreenTimeActivityPicker.swift b/packages/react-native-device-activity/ios/ScreenTimeActivityPicker.swift index b175a1b..df1e456 100644 --- a/packages/react-native-device-activity/ios/ScreenTimeActivityPicker.swift +++ b/packages/react-native-device-activity/ios/ScreenTimeActivityPicker.swift @@ -39,6 +39,16 @@ struct ActivityPicker: View { ) .allowsHitTesting(false) .background(Color.clear) + if let firstCategory = model.activitySelection.categoryTokens.first { + Label(firstCategory) + } + if let applicationToken = model.activitySelection.applicationTokens.first { + Label(applicationToken) + } + if let webdomain = model.activitySelection.webDomainTokens.first { + Label(webdomain) + } + } else { FamilyActivityPicker( selection: $model.activitySelection diff --git a/packages/react-native-device-activity/ios/Shared.swift b/packages/react-native-device-activity/ios/Shared.swift index 44f48b6..955ddac 100644 --- a/packages/react-native-device-activity/ios/Shared.swift +++ b/packages/react-native-device-activity/ios/Shared.swift @@ -743,6 +743,21 @@ func deserializeFamilyActivitySelection(familyActivitySelectionStr: String) return activitySelection } +@available(iOS 15.0, *) +func deserializeToken(tokenStr: String) + -> Token? { + let decoder = JSONDecoder() + let data = Data(base64Encoded: tokenStr) + do { + var token = try decoder.decode(Token.self, from: data!) + return token + } catch { + logger.log("decode error \(error.localizedDescription, privacy: .public)") + } + + return nil +} + @available(iOS 15.0, *) func serializeFamilyActivitySelection(selection: FamilyActivitySelection) -> String { let encoder = JSONEncoder() @@ -756,6 +771,19 @@ func serializeFamilyActivitySelection(selection: FamilyActivitySelection) -> Str } } +@available(iOS 15.0, *) +func serializeToken(token: Token) -> String { + let encoder = JSONEncoder() + do { + let json = try encoder.encode(token) + let jsonString = json.base64EncodedString() + + return jsonString + } catch { + return "" + } +} + @available(iOS 15.0, *) func enableBlockAllMode(triggeredBy: String) { userDefaults?.set(true, forKey: IS_BLOCKING_ALL)