mattermost-mobile/libraries/@mattermost/rnutils/ios/RNUtilsWrapper.swift
Elias Nahum b8c088cc70
Upgrade RN as well as update or replace other dependencies (#8011)
* start upgrade to RN 74

* migrate react-native-fs to expo-file-system

* exclude expo-asset module

* fix database manager remove directory

* fix: android network helper

* include expo on android

* temporarily disable android dep lock

* replace react-native-create-thumbnail with expo-video-thumnails

* update patches file version

* fix android build on 74

* create local library to replace MattermostManaged, Notifications and SplitView modules with new arch support

* migrate app to use new mattermost-rnutils library

* remove unused flipper class for android unsigned

* fix mattermost-rnutils android foldedObserver lifecycle

* use mattermost-rnutils on Android

* use mattermost-rnutils on iOS

* path react-native-navigation to not crash when activity is not NavigationActivity

* create local library for android share extension with new arch support

* Replace ShareModule with @mattermost/rnshare library

* remove ShareModule from android native code

* update react-intl

* update nodejs to 20.x.x npm to 10.x.x and dev deps

* update @gorhom/bottom-sheet

* use MattermostShare conditionally based on the platform

* update @react-native-camera-roll/camera-roll

* remove unused react-native-calendars

* fix metro config

* fix terminate session race condition

* remove unused analytics

* replace react-native-device-info with expo-application and expo-device

* update @react-native-clipboard/clipboard

* update @react-native-community/datetimepicker

* update @react-native-community/netinfo

* update @sentry/react-native

* update react-native-document-picker

* update react-native-gesture-handler

* update react-native-share

* update react-native-svg and react-native-svg-transformer

* update react-native-vector-icons

* update babel

* update react-native-shadow-2

* update semver

* remove react-native-svg-transformer and convert svg files to svg components

* fix @mattermost/rnshare new-arch build on android

* remove react-native-create-thumbnail resolution in build.gradle

* create @mattermost/hardware-keyboard library to replace hw-keyboard-events

* fix hardware-keyboard library

* fix rnutils library

* create @mattermost/keyboard-tracker library

* replace react-native-keyboard-tracking-view with @mattermost/keyboard-tracker

* fix: rnutils to not crash on lateinit context

* fix: rnutils delete database

* revert changes to session_manager

* Removed react-native-webview and added expo-web-browser instead

With expo-web-browser we no longer need the webview for SSO login
the SSO login is now done by using "custom Chrome tabs" on Android
and ASWebAuthenticationSession on iOS

* remove patch for react-native-keyboard-tracking-view

* replace react-native-linear-gradient with expo-linear-gradient

* replace react-native-in-app-review with expo-store-review

* fix: shared group database directory on ios

* replace react-native-fast-image with expo-image

* remove unusued type def for react-native-keyboard-tracking-view

* replace react-native-elements and react-native-button with @rneui

* node version

* update sizzling methods

* fix tests using jest-expo

* replace jail-monkey with expo-device

* update babel deps

* update typescript eslint

* update rn and expo

* react-native-document-picker @react-native-camera-roll/camera-roll @react-native-community/datetimepicker react-native-reanimated react-native-safe-area-context

* update patches

* update @sentry/react-native

* upgrade react-native-navigation

* update expo & expo-image

* upgrade to working version of @sentry/react-native

* update node, cocoapods, bundler, fastlane versions

* @testing-library/react-native and eslint-plugin-jest

* fix: FloatingTextInput causing a crash with reanimated

* update sentry, localize, @types/lodash and uuid

* fix floating text input label

* update react-native-video

* fix: cannot calculate shadow efficiently on some components

* fix: reduce motion warning for bottomSheet

* fix: shadow on YouTube component

* update react-native-webrtc expo and @typescript-eslint

* audit fix

* fix swizzling bad merge

* temp use of github dependency for @mattermost libraries

* feedback review

* feedback review

* npm audit fix

* update bundle deps

* update @mattermost/react-native-turbo-log

* update deps
2024-06-19 09:33:45 +08:00

224 lines
7.8 KiB
Swift

import Foundation
import React
@objc public class RNUtilsWrapper: NSObject {
@objc public weak var delegate: RNUtilsDelegate? = nil
deinit {
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name.RCTUserInterfaceStyleDidChange,
object: nil)
}
func getSharedDirectory() -> URL? {
let fileManager = FileManager.default
return fileManager.containerURL(forSecurityApplicationGroupIdentifier: getAppGroupId())
}
func getDatabasePath() -> String {
guard let sharedDirectory = getSharedDirectory() else {
return ""
}
return sharedDirectory.appendingPathComponent("databases").path
}
func isRunningInFullScreen() -> Bool {
guard let w = UIApplication.shared.delegate?.window, let window = w else { return false }
let screenSize = window.screen.bounds.size.width
let frameSize = window.frame.size.width
let shouldBeConsideredFullScreen = frameSize >= (screenSize * 0.6)
return shouldBeConsideredFullScreen
}
@objc public func captureEvents() {
NotificationCenter.default.addObserver(self,
selector: #selector(isSplitView), name: NSNotification.Name.RCTUserInterfaceStyleDidChange,
object: nil)
}
@objc func isSplitView() {
if UIDevice.current.userInterfaceIdiom == .pad {
delegate?.sendEvent(name: "SplitViewChanged", result: [
"isSplitView": !isRunningInFullScreen(),
"isTablet": UIDevice.current.userInterfaceIdiom == .pad,
])
}
}
@objc public func getAppGroupId() -> String {
let bundle = Bundle.main
guard let appGroupId = bundle.object(forInfoDictionaryKey: "AppGroupIdentifier") as? String else {
return ""
}
return appGroupId
}
@objc public func appGroupSharedDirectory() -> Dictionary<String, Any> {
let fileManager = FileManager.default
let sharedDirectory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: getAppGroupId())
let databasePath = sharedDirectory?.appendingPathComponent("databases")
var results = Dictionary<String, Any>()
guard let dbPath = databasePath,
let shared = sharedDirectory else {
results["sharedDirectory"] = ""
results["databasePath"] = ""
return results
}
try? fileManager.createDirectory(at: dbPath, withIntermediateDirectories: true, attributes: nil)
results["sharedDirectory"] = shared.path
results["databasePath"] = dbPath.path
return results
}
@objc public func deleteDatabaseDirectory(databaseName: String?, shouldRemoveDirectory: Bool) -> Dictionary<String, Any> {
let appGroupDatabaseDir = getDatabasePath()
guard !appGroupDatabaseDir.isEmpty else {
return [
"error": "No app group directory found",
"success": false
]
}
guard let name = databaseName, !name.isEmpty else {
return [
"error": "database name should not be null or empty",
"success": false
]
}
let databaseFile = "\(appGroupDatabaseDir)/\(name).db"
let databaseDirOrFile = shouldRemoveDirectory ? appGroupDatabaseDir : databaseFile
let fileManager = FileManager.default
let walFile = "\(databaseFile)-wal"
if !shouldRemoveDirectory && fileManager.fileExists(atPath: walFile) {
try? fileManager.removeItem(atPath: walFile)
}
let shmFile = "\(databaseFile)-shm"
if !shouldRemoveDirectory && fileManager.fileExists(atPath: shmFile) {
try? fileManager.removeItem(atPath: shmFile)
}
do {
try fileManager.removeItem(atPath: databaseDirOrFile)
return [
"error": "",
"success": true
]
} catch {
return [
"error": error.localizedDescription,
"success": false
]
}
}
@objc public func renameDatabase(databaseName: String?, newDatabaseName: String?) -> Dictionary<String, Any> {
guard let appGroupDir = getSharedDirectory() else {
return [
"error": "No app group directory found",
"success": false
]
}
guard let name = databaseName,
let newName = newDatabaseName,
!name.isEmpty, !newName.isEmpty else {
return [
"error": "database name and the new database name should not be null or empty",
"success": false
]
}
let fileManager = FileManager.default
let databaseDir = "\(appGroupDir.path)/\(name).db"
let walFile = "\(databaseDir)-wal"
let shmFile = "\(databaseDir)-shm"
if !fileManager.fileExists(atPath: databaseDir) {
return [
"error": "database file is not does not exists",
"success": false
]
}
let newDatabaseDir = "\(appGroupDir.path)/\(newName).db"
let destinationFileExists = fileManager.fileExists(atPath: newDatabaseDir)
let dstWal = "\(newDatabaseDir)-wal"
let dstShm = "\(newDatabaseDir)-shm"
if !destinationFileExists && fileManager.fileExists(atPath: walFile) {
try? fileManager.moveItem(atPath: walFile, toPath: dstWal)
}
if !destinationFileExists && fileManager.fileExists(atPath: shmFile) {
try? fileManager.moveItem(atPath: shmFile, toPath: dstShm)
}
do {
try fileManager.moveItem(atPath: databaseDir, toPath: newDatabaseDir)
return [
"error": "",
"success": true
]
} catch {
return [
"error": error.localizedDescription,
"success": false
]
}
}
@objc public func deleteEntitiesFile() -> NSNumber {
guard let appGroupDir = getSharedDirectory() else {
return NSNumber(false)
}
let file = "\(appGroupDir)/entities"
do {
try FileManager.default.removeItem(atPath: file)
return NSNumber(true)
} catch {
return NSNumber(false)
}
}
@objc public func isRunningInSplitView() -> Dictionary<String, Any> {
let queue = DispatchQueue.main
let group = DispatchGroup()
var shouldBeConsideredFullScreen = true
group.enter()
queue.async(group: group) { [weak self] in
shouldBeConsideredFullScreen = self?.isRunningInFullScreen() ?? true
group.leave()
}
group.wait()
return [
"isSplit": !shouldBeConsideredFullScreen,
"isTablet": UIDevice.current.userInterfaceIdiom == .pad,
]
}
@objc public func unlockOrientation() {
DispatchQueue.main.async {
OrientationManager.shared.unlockOrientation()
UIDevice.current.setValue(UIInterfaceOrientation.unknown.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
@objc public func lockOrientation() {
DispatchQueue.main.async {
OrientationManager.shared.lockOrientation()
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
}