deer social fork for personal usage. but you might see a use idk. github mirror

Lint native files (#4768)

authored by hailey.at and committed by GitHub 2397104a b433469a

Changed files
+385 -367
modules
BlueskyNSE
Share-with-Bluesky
expo-background-notification-handler
expo-bluesky-gif-view
expo-bluesky-swiss-army
android
src
main
java
expo
modules
blueskyswissarmy
expo-receive-android-intents
android
src
main
java
xyz
blueskyweb
app
exporeceiveandroidintents
expo-scroll-forwarder
+2
.editorconfig
··· 1 + [*.{kt,kts}] 2 + indent_size=2
+9 -9
modules/BlueskyNSE/NotificationService.swift
··· 13 13 contentHandler(request.content) 14 14 return 15 15 } 16 - 16 + 17 17 if reason == "chat-message" { 18 18 mutateWithChatMessage(bestAttempt) 19 19 } else { 20 20 mutateWithBadge(bestAttempt) 21 21 } 22 - 22 + 23 23 contentHandler(bestAttempt) 24 24 } 25 - 25 + 26 26 override func serviceExtensionTimeWillExpire() { 27 27 // If for some reason the alloted time expires, we don't actually want to display a notification 28 28 } 29 - 29 + 30 30 func createCopy(_ content: UNNotificationContent) -> UNMutableNotificationContent? { 31 31 return content.mutableCopy() as? UNMutableNotificationContent 32 32 } 33 - 33 + 34 34 func mutateWithBadge(_ content: UNMutableNotificationContent) { 35 35 var count = prefs?.integer(forKey: "badgeCount") ?? 0 36 36 count += 1 37 - 37 + 38 38 // Set the new badge number for the notification, then store that value for using later 39 39 content.badge = NSNumber(value: count) 40 40 prefs?.setValue(count, forKey: "badgeCount") 41 41 } 42 - 42 + 43 43 func mutateWithChatMessage(_ content: UNMutableNotificationContent) { 44 44 if self.prefs?.bool(forKey: "playSoundChat") == true { 45 45 mutateWithDmSound(content) 46 46 } 47 47 } 48 - 48 + 49 49 func mutateWithDefaultSound(_ content: UNMutableNotificationContent) { 50 50 content.sound = UNNotificationSound.default 51 51 } 52 - 52 + 53 53 func mutateWithDmSound(_ content: UNMutableNotificationContent) { 54 54 content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "dm.aiff")) 55 55 }
+10 -15
modules/Share-with-Bluesky/ShareViewController.swift
··· 30 30 } 31 31 } 32 32 33 - private func handleText(item: NSItemProvider) async -> Void { 33 + private func handleText(item: NSItemProvider) async { 34 34 do { 35 35 if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String { 36 36 if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), 37 - let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") 38 - { 37 + let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") { 39 38 _ = self.openURL(url) 40 39 } 41 40 } ··· 45 44 } 46 45 } 47 46 48 - private func handleUrl(item: NSItemProvider) async -> Void { 47 + private func handleUrl(item: NSItemProvider) async { 49 48 do { 50 49 if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL { 51 50 if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), 52 - let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") 53 - { 51 + let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") { 54 52 _ = self.openURL(url) 55 53 } 56 54 } ··· 60 58 } 61 59 } 62 60 63 - private func handleImages(items: [NSItemProvider]) async -> Void { 61 + private func handleImages(items: [NSItemProvider]) async { 64 62 let firstFourItems: [NSItemProvider] 65 63 if items.count < 4 { 66 64 firstFourItems = items ··· 72 70 var imageUris = "" 73 71 74 72 for (index, item) in firstFourItems.enumerated() { 75 - var imageUriInfo: String? = nil 73 + var imageUriInfo: String? 76 74 77 75 do { 78 76 if let dataUri = try await item.loadItem(forTypeIdentifier: "public.image") as? URL { ··· 100 98 101 99 if valid, 102 100 let encoded = imageUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), 103 - let url = URL(string: "\(self.appScheme)://intent/compose?imageUris=\(encoded)") 104 - { 101 + let url = URL(string: "\(self.appScheme)://intent/compose?imageUris=\(encoded)") { 105 102 _ = self.openURL(url) 106 103 } 107 104 ··· 119 116 // extension does. 120 117 if let dir = FileManager() 121 118 .containerURL( 122 - forSecurityApplicationGroupIdentifier: "group.app.bsky") 123 - { 119 + forSecurityApplicationGroupIdentifier: "group.app.bsky") { 124 120 let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg" 125 121 126 122 if let newUri = URL(string: filePath), 127 - let jpegData = image.jpegData(compressionQuality: 1) 128 - { 123 + let jpegData = image.jpegData(compressionQuality: 1) { 129 124 try jpegData.write(to: newUri) 130 125 return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)" 131 126 } ··· 136 131 } 137 132 } 138 133 139 - private func completeRequest() -> Void { 134 + private func completeRequest() { 140 135 self.extensionContext?.completeRequest(returningItems: nil) 141 136 } 142 137
+1 -1
modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt
··· 5 5 6 6 class BackgroundNotificationHandler( 7 7 private val context: Context, 8 - private val notifInterface: BackgroundNotificationHandlerInterface 8 + private val notifInterface: BackgroundNotificationHandlerInterface, 9 9 ) { 10 10 fun handleMessage(remoteMessage: RemoteMessage) { 11 11 if (ExpoBackgroundNotificationHandlerModule.isForegrounded) {
+48 -47
modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt
··· 8 8 var isForegrounded = false 9 9 } 10 10 11 - override fun definition() = ModuleDefinition { 12 - Name("ExpoBackgroundNotificationHandler") 11 + override fun definition() = 12 + ModuleDefinition { 13 + Name("ExpoBackgroundNotificationHandler") 13 14 14 - OnCreate { 15 - NotificationPrefs(appContext.reactContext).initialize() 16 - } 15 + OnCreate { 16 + NotificationPrefs(appContext.reactContext).initialize() 17 + } 17 18 18 - OnActivityEntersForeground { 19 - isForegrounded = true 20 - } 19 + OnActivityEntersForeground { 20 + isForegrounded = true 21 + } 21 22 22 - OnActivityEntersBackground { 23 - isForegrounded = false 24 - } 23 + OnActivityEntersBackground { 24 + isForegrounded = false 25 + } 25 26 26 - AsyncFunction("getAllPrefsAsync") { 27 - return@AsyncFunction NotificationPrefs(appContext.reactContext).getAllPrefs() 28 - } 27 + AsyncFunction("getAllPrefsAsync") { 28 + return@AsyncFunction NotificationPrefs(appContext.reactContext).getAllPrefs() 29 + } 29 30 30 - AsyncFunction("getBoolAsync") { forKey: String -> 31 - return@AsyncFunction NotificationPrefs(appContext.reactContext).getBoolean(forKey) 32 - } 31 + AsyncFunction("getBoolAsync") { forKey: String -> 32 + return@AsyncFunction NotificationPrefs(appContext.reactContext).getBoolean(forKey) 33 + } 33 34 34 - AsyncFunction("getStringAsync") { forKey: String -> 35 - return@AsyncFunction NotificationPrefs(appContext.reactContext).getString(forKey) 36 - } 35 + AsyncFunction("getStringAsync") { forKey: String -> 36 + return@AsyncFunction NotificationPrefs(appContext.reactContext).getString(forKey) 37 + } 37 38 38 - AsyncFunction("getStringArrayAsync") { forKey: String -> 39 - return@AsyncFunction NotificationPrefs(appContext.reactContext).getStringArray(forKey) 40 - } 39 + AsyncFunction("getStringArrayAsync") { forKey: String -> 40 + return@AsyncFunction NotificationPrefs(appContext.reactContext).getStringArray(forKey) 41 + } 41 42 42 - AsyncFunction("setBoolAsync") { forKey: String, value: Boolean -> 43 - NotificationPrefs(appContext.reactContext).setBoolean(forKey, value) 44 - } 43 + AsyncFunction("setBoolAsync") { forKey: String, value: Boolean -> 44 + NotificationPrefs(appContext.reactContext).setBoolean(forKey, value) 45 + } 45 46 46 - AsyncFunction("setStringAsync") { forKey: String, value: String -> 47 - NotificationPrefs(appContext.reactContext).setString(forKey, value) 48 - } 47 + AsyncFunction("setStringAsync") { forKey: String, value: String -> 48 + NotificationPrefs(appContext.reactContext).setString(forKey, value) 49 + } 49 50 50 - AsyncFunction("setStringArrayAsync") { forKey: String, value: Array<String> -> 51 - NotificationPrefs(appContext.reactContext).setStringArray(forKey, value) 52 - } 51 + AsyncFunction("setStringArrayAsync") { forKey: String, value: Array<String> -> 52 + NotificationPrefs(appContext.reactContext).setStringArray(forKey, value) 53 + } 53 54 54 - AsyncFunction("addToStringArrayAsync") { forKey: String, string: String -> 55 - NotificationPrefs(appContext.reactContext).addToStringArray(forKey, string) 56 - } 55 + AsyncFunction("addToStringArrayAsync") { forKey: String, string: String -> 56 + NotificationPrefs(appContext.reactContext).addToStringArray(forKey, string) 57 + } 57 58 58 - AsyncFunction("removeFromStringArrayAsync") { forKey: String, string: String -> 59 - NotificationPrefs(appContext.reactContext).removeFromStringArray(forKey, string) 60 - } 59 + AsyncFunction("removeFromStringArrayAsync") { forKey: String, string: String -> 60 + NotificationPrefs(appContext.reactContext).removeFromStringArray(forKey, string) 61 + } 61 62 62 - AsyncFunction("addManyToStringArrayAsync") { forKey: String, strings: Array<String> -> 63 - NotificationPrefs(appContext.reactContext).addManyToStringArray(forKey, strings) 64 - } 63 + AsyncFunction("addManyToStringArrayAsync") { forKey: String, strings: Array<String> -> 64 + NotificationPrefs(appContext.reactContext).addManyToStringArray(forKey, strings) 65 + } 65 66 66 - AsyncFunction("removeManyFromStringArrayAsync") { forKey: String, strings: Array<String> -> 67 - NotificationPrefs(appContext.reactContext).removeManyFromStringArray(forKey, strings) 68 - } 67 + AsyncFunction("removeManyFromStringArrayAsync") { forKey: String, strings: Array<String> -> 68 + NotificationPrefs(appContext.reactContext).removeManyFromStringArray(forKey, strings) 69 + } 69 70 70 - AsyncFunction("setBadgeCountAsync") { _: Int -> 71 - // This does nothing on Android 71 + AsyncFunction("setBadgeCountAsync") { _: Int -> 72 + // This does nothing on Android 73 + } 72 74 } 73 - } 74 75 }
+58 -49
modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt
··· 2 2 3 3 import android.content.Context 4 4 5 - val DEFAULTS = mapOf<String, Any>( 6 - "playSoundChat" to true, 7 - "playSoundFollow" to false, 8 - "playSoundLike" to false, 9 - "playSoundMention" to false, 10 - "playSoundQuote" to false, 11 - "playSoundReply" to false, 12 - "playSoundRepost" to false, 13 - "mutedThreads" to mapOf<String, List<String>>() 14 - ) 5 + val DEFAULTS = 6 + mapOf<String, Any>( 7 + "playSoundChat" to true, 8 + "playSoundFollow" to false, 9 + "playSoundLike" to false, 10 + "playSoundMention" to false, 11 + "playSoundQuote" to false, 12 + "playSoundReply" to false, 13 + "playSoundRepost" to false, 14 + "mutedThreads" to mapOf<String, List<String>>(), 15 + ) 15 16 16 - class NotificationPrefs (private val context: Context?) { 17 - private val prefs = context?.getSharedPreferences("xyz.blueskyweb.app", Context.MODE_PRIVATE) 18 - ?: throw Error("Context is null") 17 + class NotificationPrefs( 18 + private val context: Context?, 19 + ) { 20 + private val prefs = 21 + context?.getSharedPreferences("xyz.blueskyweb.app", Context.MODE_PRIVATE) 22 + ?: throw Error("Context is null") 19 23 20 24 fun initialize() { 21 25 prefs ··· 41 45 } 42 46 } 43 47 } 44 - } 45 - .apply() 48 + }.apply() 46 49 } 47 50 48 - fun getAllPrefs(): MutableMap<String, *> { 49 - return prefs.all 50 - } 51 + fun getAllPrefs(): MutableMap<String, *> = prefs.all 51 52 52 - fun getBoolean(key: String): Boolean { 53 - return prefs.getBoolean(key, false) 54 - } 53 + fun getBoolean(key: String): Boolean = prefs.getBoolean(key, false) 55 54 56 - fun getString(key: String): String? { 57 - return prefs.getString(key, null) 58 - } 55 + fun getString(key: String): String? = prefs.getString(key, null) 59 56 60 - fun getStringArray(key: String): Array<String>? { 61 - return prefs.getStringSet(key, null)?.toTypedArray() 62 - } 57 + fun getStringArray(key: String): Array<String>? = prefs.getStringSet(key, null)?.toTypedArray() 63 58 64 - fun setBoolean(key: String, value: Boolean) { 59 + fun setBoolean( 60 + key: String, 61 + value: Boolean, 62 + ) { 65 63 prefs 66 64 .edit() 67 65 .apply { 68 66 putBoolean(key, value) 69 - } 70 - .apply() 67 + }.apply() 71 68 } 72 69 73 - fun setString(key: String, value: String) { 70 + fun setString( 71 + key: String, 72 + value: String, 73 + ) { 74 74 prefs 75 75 .edit() 76 76 .apply { 77 77 putString(key, value) 78 - } 79 - .apply() 78 + }.apply() 80 79 } 81 80 82 - fun setStringArray(key: String, value: Array<String>) { 81 + fun setStringArray( 82 + key: String, 83 + value: Array<String>, 84 + ) { 83 85 prefs 84 86 .edit() 85 87 .apply { 86 88 putStringSet(key, value.toSet()) 87 - } 88 - .apply() 89 + }.apply() 89 90 } 90 91 91 - fun addToStringArray(key: String, string: String) { 92 + fun addToStringArray( 93 + key: String, 94 + string: String, 95 + ) { 92 96 prefs 93 97 .edit() 94 98 .apply { 95 99 val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf() 96 100 set.add(string) 97 101 putStringSet(key, set) 98 - } 99 - .apply() 102 + }.apply() 100 103 } 101 104 102 - fun removeFromStringArray(key: String, string: String) { 105 + fun removeFromStringArray( 106 + key: String, 107 + string: String, 108 + ) { 103 109 prefs 104 110 .edit() 105 111 .apply { 106 112 val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf() 107 113 set.remove(string) 108 114 putStringSet(key, set) 109 - } 110 - .apply() 115 + }.apply() 111 116 } 112 117 113 - fun addManyToStringArray(key: String, strings: Array<String>) { 118 + fun addManyToStringArray( 119 + key: String, 120 + strings: Array<String>, 121 + ) { 114 122 prefs 115 123 .edit() 116 124 .apply { 117 125 val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf() 118 126 set.addAll(strings.toSet()) 119 127 putStringSet(key, set) 120 - } 121 - .apply() 128 + }.apply() 122 129 } 123 130 124 - fun removeManyFromStringArray(key: String, strings: Array<String>) { 131 + fun removeManyFromStringArray( 132 + key: String, 133 + strings: Array<String>, 134 + ) { 125 135 prefs 126 136 .edit() 127 137 .apply { 128 138 val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf() 129 139 set.removeAll(strings.toSet()) 130 140 putStringSet(key, set) 131 - } 132 - .apply() 141 + }.apply() 133 142 } 134 - } 143 + }
+23 -24
modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift
··· 2 2 3 3 let APP_GROUP = "group.app.bsky" 4 4 5 - let DEFAULTS: [String:Any] = [ 6 - "playSoundChat" : true, 5 + let DEFAULTS: [String: Any] = [ 6 + "playSoundChat": true, 7 7 "playSoundFollow": false, 8 8 "playSoundLike": false, 9 9 "playSoundMention": false, 10 10 "playSoundQuote": false, 11 11 "playSoundReply": false, 12 12 "playSoundRepost": false, 13 - "mutedThreads": [:] as! [String:[String]], 14 - "badgeCount": 0, 13 + "mutedThreads": [:] as! [String: [String]], 14 + "badgeCount": 0 15 15 ] 16 16 17 17 /* ··· 23 23 */ 24 24 public class ExpoBackgroundNotificationHandlerModule: Module { 25 25 let userDefaults = UserDefaults(suiteName: APP_GROUP) 26 - 26 + 27 27 public func definition() -> ModuleDefinition { 28 28 Name("ExpoBackgroundNotificationHandler") 29 - 29 + 30 30 OnCreate { 31 31 DEFAULTS.forEach { p in 32 32 if userDefaults?.value(forKey: p.key) == nil { ··· 34 34 } 35 35 } 36 36 } 37 - 38 - AsyncFunction("getAllPrefsAsync") { () -> [String:Any]? in 37 + 38 + AsyncFunction("getAllPrefsAsync") { () -> [String: Any]? in 39 39 var keys: [String] = [] 40 40 DEFAULTS.forEach { p in 41 41 keys.append(p.key) 42 42 } 43 43 return userDefaults?.dictionaryWithValues(forKeys: keys) 44 44 } 45 - 45 + 46 46 AsyncFunction("getBoolAsync") { (forKey: String) -> Bool in 47 47 if let pref = userDefaults?.bool(forKey: forKey) { 48 48 return pref 49 49 } 50 50 return false 51 51 } 52 - 52 + 53 53 AsyncFunction("getStringAsync") { (forKey: String) -> String? in 54 54 if let pref = userDefaults?.string(forKey: forKey) { 55 55 return pref 56 56 } 57 57 return nil 58 58 } 59 - 59 + 60 60 AsyncFunction("getStringArrayAsync") { (forKey: String) -> [String]? in 61 61 if let pref = userDefaults?.stringArray(forKey: forKey) { 62 62 return pref 63 63 } 64 64 return nil 65 65 } 66 - 67 - AsyncFunction("setBoolAsync") { (forKey: String, value: Bool) -> Void in 66 + 67 + AsyncFunction("setBoolAsync") { (forKey: String, value: Bool) in 68 68 userDefaults?.setValue(value, forKey: forKey) 69 69 } 70 - 71 - AsyncFunction("setStringAsync") { (forKey: String, value: String) -> Void in 70 + 71 + AsyncFunction("setStringAsync") { (forKey: String, value: String) in 72 72 userDefaults?.setValue(value, forKey: forKey) 73 73 } 74 - 75 - AsyncFunction("setStringArrayAsync") { (forKey: String, value: [String]) -> Void in 74 + 75 + AsyncFunction("setStringArrayAsync") { (forKey: String, value: [String]) in 76 76 userDefaults?.setValue(value, forKey: forKey) 77 77 } 78 - 78 + 79 79 AsyncFunction("addToStringArrayAsync") { (forKey: String, string: String) in 80 80 if var curr = userDefaults?.stringArray(forKey: forKey), 81 - !curr.contains(string) 82 - { 81 + !curr.contains(string) { 83 82 curr.append(string) 84 83 userDefaults?.setValue(curr, forKey: forKey) 85 84 } 86 85 } 87 - 86 + 88 87 AsyncFunction("removeFromStringArrayAsync") { (forKey: String, string: String) in 89 88 if var curr = userDefaults?.stringArray(forKey: forKey) { 90 89 curr.removeAll { s in ··· 93 92 userDefaults?.setValue(curr, forKey: forKey) 94 93 } 95 94 } 96 - 95 + 97 96 AsyncFunction("addManyToStringArrayAsync") { (forKey: String, strings: [String]) in 98 97 if var curr = userDefaults?.stringArray(forKey: forKey) { 99 98 strings.forEach { s in ··· 104 103 userDefaults?.setValue(curr, forKey: forKey) 105 104 } 106 105 } 107 - 106 + 108 107 AsyncFunction("removeManyFromStringArrayAsync") { (forKey: String, strings: [String]) in 109 108 if var curr = userDefaults?.stringArray(forKey: forKey) { 110 109 strings.forEach { s in ··· 113 112 userDefaults?.setValue(curr, forKey: forKey) 114 113 } 115 114 } 116 - 115 + 117 116 AsyncFunction("setBadgeCountAsync") { (count: Int) in 118 117 userDefaults?.setValue(count, forKey: "badgeCount") 119 118 }
+5 -2
modules/expo-bluesky-gif-view/android/src/main/java/expo/modules/blueskygifview/AppCompatImageViewExtended.kt
··· 5 5 import android.graphics.drawable.Animatable 6 6 import androidx.appcompat.widget.AppCompatImageView 7 7 8 - class AppCompatImageViewExtended(context: Context, private val parent: GifView): AppCompatImageView(context) { 8 + class AppCompatImageViewExtended( 9 + context: Context, 10 + private val parent: GifView, 11 + ) : AppCompatImageView(context) { 9 12 override fun onDraw(canvas: Canvas) { 10 13 super.onDraw(canvas) 11 14 ··· 34 37 drawable.start() 35 38 } 36 39 } 37 - } 40 + }
+34 -33
modules/expo-bluesky-gif-view/android/src/main/java/expo/modules/blueskygifview/ExpoBlueskyGifViewModule.kt
··· 6 6 import expo.modules.kotlin.modules.ModuleDefinition 7 7 8 8 class ExpoBlueskyGifViewModule : Module() { 9 - override fun definition() = ModuleDefinition { 10 - Name("ExpoBlueskyGifView") 9 + override fun definition() = 10 + ModuleDefinition { 11 + Name("ExpoBlueskyGifView") 11 12 12 - AsyncFunction("prefetchAsync") { sources: List<String> -> 13 - val activity = appContext.currentActivity ?: return@AsyncFunction 14 - val glide = Glide.with(activity) 13 + AsyncFunction("prefetchAsync") { sources: List<String> -> 14 + val activity = appContext.currentActivity ?: return@AsyncFunction 15 + val glide = Glide.with(activity) 15 16 16 - sources.forEach { source -> 17 - glide 18 - .download(source) 19 - .diskCacheStrategy(DiskCacheStrategy.DATA) 20 - .submit() 17 + sources.forEach { source -> 18 + glide 19 + .download(source) 20 + .diskCacheStrategy(DiskCacheStrategy.DATA) 21 + .submit() 22 + } 21 23 } 22 - } 23 24 24 - View(GifView::class) { 25 - Events( 26 - "onPlayerStateChange" 27 - ) 25 + View(GifView::class) { 26 + Events( 27 + "onPlayerStateChange", 28 + ) 28 29 29 - Prop("source") { view: GifView, source: String -> 30 - view.source = source 31 - } 30 + Prop("source") { view: GifView, source: String -> 31 + view.source = source 32 + } 32 33 33 - Prop("placeholderSource") { view: GifView, source: String -> 34 - view.placeholderSource = source 35 - } 34 + Prop("placeholderSource") { view: GifView, source: String -> 35 + view.placeholderSource = source 36 + } 36 37 37 - Prop("autoplay") { view: GifView, autoplay: Boolean -> 38 - view.autoplay = autoplay 39 - } 38 + Prop("autoplay") { view: GifView, autoplay: Boolean -> 39 + view.autoplay = autoplay 40 + } 40 41 41 - AsyncFunction("playAsync") { view: GifView -> 42 - view.play() 43 - } 42 + AsyncFunction("playAsync") { view: GifView -> 43 + view.play() 44 + } 44 45 45 - AsyncFunction("pauseAsync") { view: GifView -> 46 - view.pause() 47 - } 46 + AsyncFunction("pauseAsync") { view: GifView -> 47 + view.pause() 48 + } 48 49 49 - AsyncFunction("toggleAsync") { view: GifView -> 50 - view.toggle() 50 + AsyncFunction("toggleAsync") { view: GifView -> 51 + view.toggle() 52 + } 51 53 } 52 54 } 53 - } 54 55 }
+75 -70
modules/expo-bluesky-gif-view/android/src/main/java/expo/modules/blueskygifview/GifView.kt
··· 1 1 package expo.modules.blueskygifview 2 2 3 - 4 3 import android.content.Context 5 4 import android.graphics.Color 6 5 import android.graphics.drawable.Animatable ··· 15 14 import expo.modules.kotlin.viewevent.EventDispatcher 16 15 import expo.modules.kotlin.views.ExpoView 17 16 18 - class GifView(context: Context, appContext: AppContext) : ExpoView(context, appContext) { 17 + class GifView( 18 + context: Context, 19 + appContext: AppContext, 20 + ) : ExpoView(context, appContext) { 19 21 // Events 20 22 private val onPlayerStateChange by EventDispatcher() 21 23 ··· 44 46 } 45 47 } 46 48 47 - 48 - //<editor-fold desc="Lifecycle"> 49 + // <editor-fold desc="Lifecycle"> 49 50 50 51 init { 51 52 this.setBackgroundColor(Color.TRANSPARENT) ··· 70 71 super.onDetachedFromWindow() 71 72 } 72 73 73 - //</editor-fold> 74 + // </editor-fold> 74 75 75 - //<editor-fold desc="Loading"> 76 + // <editor-fold desc="Loading"> 76 77 77 78 private fun load() { 78 79 if (placeholderSource == null || source == null) { 79 80 return 80 81 } 81 82 82 - this.webpRequest = glide.load(source) 83 - .diskCacheStrategy(DiskCacheStrategy.DATA) 84 - .skipMemoryCache(false) 85 - .listener(object: RequestListener<Drawable> { 86 - override fun onResourceReady( 87 - resource: Drawable?, 88 - model: Any?, 89 - target: Target<Drawable>?, 90 - dataSource: com.bumptech.glide.load.DataSource?, 91 - isFirstResource: Boolean 92 - ): Boolean { 93 - if (placeholderRequest != null) { 94 - glide.clear(placeholderRequest) 95 - } 96 - return false 97 - } 83 + this.webpRequest = 84 + glide 85 + .load(source) 86 + .diskCacheStrategy(DiskCacheStrategy.DATA) 87 + .skipMemoryCache(false) 88 + .listener( 89 + object : RequestListener<Drawable> { 90 + override fun onResourceReady( 91 + resource: Drawable?, 92 + model: Any?, 93 + target: Target<Drawable>?, 94 + dataSource: com.bumptech.glide.load.DataSource?, 95 + isFirstResource: Boolean, 96 + ): Boolean { 97 + if (placeholderRequest != null) { 98 + glide.clear(placeholderRequest) 99 + } 100 + return false 101 + } 98 102 99 - override fun onLoadFailed( 100 - e: GlideException?, 101 - model: Any?, 102 - target: Target<Drawable>?, 103 - isFirstResource: Boolean 104 - ): Boolean { 105 - return true 106 - } 107 - }) 108 - .into(this.imageView) 103 + override fun onLoadFailed( 104 + e: GlideException?, 105 + model: Any?, 106 + target: Target<Drawable>?, 107 + isFirstResource: Boolean, 108 + ): Boolean = true 109 + }, 110 + ).into(this.imageView) 109 111 110 112 if (this.imageView.drawable == null || this.imageView.drawable !is Animatable) { 111 - this.placeholderRequest = glide.load(placeholderSource) 112 - .diskCacheStrategy(DiskCacheStrategy.DATA) 113 - // Let's not bloat the memory cache with placeholders 114 - .skipMemoryCache(true) 115 - .listener(object: RequestListener<Drawable> { 116 - override fun onResourceReady( 117 - resource: Drawable?, 118 - model: Any?, 119 - target: Target<Drawable>?, 120 - dataSource: com.bumptech.glide.load.DataSource?, 121 - isFirstResource: Boolean 122 - ): Boolean { 123 - // Incase this request finishes after the webp, let's just not set 124 - // the drawable. This shouldn't happen because the request should get cancelled 125 - if (imageView.drawable == null) { 126 - imageView.setImageDrawable(resource) 127 - } 128 - return true 129 - } 113 + this.placeholderRequest = 114 + glide 115 + .load(placeholderSource) 116 + .diskCacheStrategy(DiskCacheStrategy.DATA) 117 + // Let's not bloat the memory cache with placeholders 118 + .skipMemoryCache(true) 119 + .listener( 120 + object : RequestListener<Drawable> { 121 + override fun onResourceReady( 122 + resource: Drawable?, 123 + model: Any?, 124 + target: Target<Drawable>?, 125 + dataSource: com.bumptech.glide.load.DataSource?, 126 + isFirstResource: Boolean, 127 + ): Boolean { 128 + // Incase this request finishes after the webp, let's just not set 129 + // the drawable. This shouldn't happen because the request should get cancelled 130 + if (imageView.drawable == null) { 131 + imageView.setImageDrawable(resource) 132 + } 133 + return true 134 + } 130 135 131 - override fun onLoadFailed( 132 - e: GlideException?, 133 - model: Any?, 134 - target: Target<Drawable>?, 135 - isFirstResource: Boolean 136 - ): Boolean { 137 - return true 138 - } 139 - }) 140 - .submit() 136 + override fun onLoadFailed( 137 + e: GlideException?, 138 + model: Any?, 139 + target: Target<Drawable>?, 140 + isFirstResource: Boolean, 141 + ): Boolean = true 142 + }, 143 + ).submit() 141 144 } 142 145 } 143 146 144 - //</editor-fold> 147 + // </editor-fold> 145 148 146 - //<editor-fold desc="Controls"> 149 + // <editor-fold desc="Controls"> 147 150 148 151 fun play() { 149 152 this.imageView.play() ··· 165 168 } 166 169 } 167 170 168 - //</editor-fold> 171 + // </editor-fold> 169 172 170 - //<editor-fold desc="Util"> 173 + // <editor-fold desc="Util"> 171 174 172 175 fun firePlayerStateChange() { 173 - onPlayerStateChange(mapOf( 174 - "isPlaying" to this.isPlaying, 175 - "isLoaded" to this.isLoaded, 176 - )) 176 + onPlayerStateChange( 177 + mapOf( 178 + "isPlaying" to this.isPlaying, 179 + "isLoaded" to this.isLoaded, 180 + ), 181 + ) 177 182 } 178 183 179 - //</editor-fold> 184 + // </editor-fold> 180 185 }
+8 -8
modules/expo-bluesky-gif-view/ios/ExpoBlueskyGifViewModule.swift
··· 5 5 public class ExpoBlueskyGifViewModule: Module { 6 6 public func definition() -> ModuleDefinition { 7 7 Name("ExpoBlueskyGifView") 8 - 8 + 9 9 OnCreate { 10 10 SDImageCodersManager.shared.addCoder(SDImageGIFCoder.shared) 11 11 } 12 - 12 + 13 13 AsyncFunction("prefetchAsync") { (sources: [URL]) in 14 14 SDWebImagePrefetcher.shared.prefetchURLs(sources, context: Util.createContext(), progress: nil) 15 15 } ··· 18 18 Events( 19 19 "onPlayerStateChange" 20 20 ) 21 - 21 + 22 22 Prop("source") { (view: GifView, prop: String) in 23 23 view.source = prop 24 24 } 25 - 25 + 26 26 Prop("placeholderSource") { (view: GifView, prop: String) in 27 27 view.placeholderSource = prop 28 28 } 29 - 29 + 30 30 Prop("autoplay") { (view: GifView, prop: Bool) in 31 31 view.autoplay = prop 32 32 } 33 - 33 + 34 34 AsyncFunction("toggleAsync") { (view: GifView) in 35 35 view.toggle() 36 36 } 37 - 37 + 38 38 AsyncFunction("playAsync") { (view: GifView) in 39 39 view.play() 40 40 } 41 - 41 + 42 42 AsyncFunction("pauseAsync") { (view: GifView) in 43 43 view.pause() 44 44 }
+6 -9
modules/expo-bluesky-gif-view/ios/GifView.swift
··· 16 16 ) 17 17 private var isPlaying = true 18 18 private var isLoaded = false 19 - 19 + 20 20 // Requests 21 21 private var webpOperation: SDWebImageCombinedOperation? 22 22 private var placeholderOperation: SDWebImageCombinedOperation? 23 23 24 24 // Props 25 - var source: String? = nil 26 - var placeholderSource: String? = nil 25 + var source: String? 26 + var placeholderSource: String? 27 27 var autoplay = true { 28 28 didSet { 29 29 if !autoplay { ··· 78 78 // See: 79 79 // https://github.com/SDWebImage/SDWebImage/blob/master/Docs/HowToUse.md#using-asynchronous-image-caching-independently 80 80 if !SDImageCache.shared.diskImageDataExists(withKey: source), 81 - let url = URL(string: placeholderSource) 82 - { 81 + let url = URL(string: placeholderSource) { 83 82 self.placeholderOperation = imageManager.loadImage( 84 83 with: url, 85 84 options: [.retryFailed], ··· 132 131 if let placeholderSource = self.placeholderSource, 133 132 imageUrl?.absoluteString == placeholderSource, 134 133 self.imageView.image == nil, 135 - let image = image 136 - { 134 + let image = image { 137 135 self.setImage(image) 138 136 return 139 137 } ··· 142 140 imageUrl?.absoluteString == source, 143 141 // UIImage perf suckssss if the image is animated 144 142 let data = data, 145 - let animatedImage = SDAnimatedImage(data: data) 146 - { 143 + let animatedImage = SDAnimatedImage(data: data) { 147 144 self.placeholderOperation?.cancel() 148 145 self.isPlaying = self.autoplay 149 146 self.isLoaded = true
+4 -3
modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/deviceprefs/ExpoBlueskyDevicePrefsModule.kt
··· 4 4 import expo.modules.kotlin.modules.ModuleDefinition 5 5 6 6 class ExpoBlueskyDevicePrefsModule : Module() { 7 - override fun definition() = ModuleDefinition { 8 - Name("ExpoBlueskyDevicePrefs") 9 - } 7 + override fun definition() = 8 + ModuleDefinition { 9 + Name("ExpoBlueskyDevicePrefs") 10 + } 10 11 }
+43 -40
modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/referrer/ExpoBlueskyReferrerModule.kt
··· 3 3 import android.util.Log 4 4 import com.android.installreferrer.api.InstallReferrerClient 5 5 import com.android.installreferrer.api.InstallReferrerStateListener 6 + import expo.modules.kotlin.Promise 6 7 import expo.modules.kotlin.modules.Module 7 8 import expo.modules.kotlin.modules.ModuleDefinition 8 - import expo.modules.kotlin.Promise 9 9 10 10 class ExpoBlueskyReferrerModule : Module() { 11 - override fun definition() = ModuleDefinition { 12 - Name("ExpoBlueskyReferrer") 11 + override fun definition() = 12 + ModuleDefinition { 13 + Name("ExpoBlueskyReferrer") 13 14 14 - AsyncFunction("getGooglePlayReferrerInfoAsync") { promise: Promise -> 15 - val referrerClient = InstallReferrerClient.newBuilder(appContext.reactContext).build() 16 - referrerClient.startConnection(object : InstallReferrerStateListener { 17 - override fun onInstallReferrerSetupFinished(responseCode: Int) { 18 - if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) { 19 - Log.d("ExpoGooglePlayReferrer", "Successfully retrieved referrer info.") 15 + AsyncFunction("getGooglePlayReferrerInfoAsync") { promise: Promise -> 16 + val referrerClient = InstallReferrerClient.newBuilder(appContext.reactContext).build() 17 + referrerClient.startConnection( 18 + object : InstallReferrerStateListener { 19 + override fun onInstallReferrerSetupFinished(responseCode: Int) { 20 + if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) { 21 + Log.d("ExpoGooglePlayReferrer", "Successfully retrieved referrer info.") 20 22 21 - val response = referrerClient.installReferrer 22 - Log.d("ExpoGooglePlayReferrer", "Install referrer: ${response.installReferrer}") 23 + val response = referrerClient.installReferrer 24 + Log.d("ExpoGooglePlayReferrer", "Install referrer: ${response.installReferrer}") 25 + 26 + promise.resolve( 27 + mapOf( 28 + "installReferrer" to response.installReferrer, 29 + "clickTimestamp" to response.referrerClickTimestampSeconds, 30 + "installTimestamp" to response.installBeginTimestampSeconds, 31 + ), 32 + ) 33 + } else { 34 + Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Unknown error.") 35 + promise.reject( 36 + "ERR_GOOGLE_PLAY_REFERRER_UNKNOWN", 37 + "Failed to get referrer info", 38 + Exception("Failed to get referrer info"), 39 + ) 40 + } 41 + referrerClient.endConnection() 42 + } 23 43 24 - promise.resolve( 25 - mapOf( 26 - "installReferrer" to response.installReferrer, 27 - "clickTimestamp" to response.referrerClickTimestampSeconds, 28 - "installTimestamp" to response.installBeginTimestampSeconds 44 + override fun onInstallReferrerServiceDisconnected() { 45 + Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Service disconnected.") 46 + referrerClient.endConnection() 47 + promise.reject( 48 + "ERR_GOOGLE_PLAY_REFERRER_DISCONNECTED", 49 + "Failed to get referrer info", 50 + Exception("Failed to get referrer info"), 29 51 ) 30 - ) 31 - } else { 32 - Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Unknown error.") 33 - promise.reject( 34 - "ERR_GOOGLE_PLAY_REFERRER_UNKNOWN", 35 - "Failed to get referrer info", 36 - Exception("Failed to get referrer info") 37 - ) 38 - } 39 - referrerClient.endConnection() 40 - } 41 - 42 - override fun onInstallReferrerServiceDisconnected() { 43 - Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Service disconnected.") 44 - referrerClient.endConnection() 45 - promise.reject( 46 - "ERR_GOOGLE_PLAY_REFERRER_DISCONNECTED", 47 - "Failed to get referrer info", 48 - Exception("Failed to get referrer info") 49 - ) 50 - } 51 - }) 52 + } 53 + }, 54 + ) 55 + } 52 56 } 53 - } 54 - } 57 + }
+19 -17
modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
··· 13 13 import java.net.URLEncoder 14 14 15 15 class ExpoReceiveAndroidIntentsModule : Module() { 16 - override fun definition() = ModuleDefinition { 17 - Name("ExpoReceiveAndroidIntents") 16 + override fun definition() = 17 + ModuleDefinition { 18 + Name("ExpoReceiveAndroidIntents") 18 19 19 - OnNewIntent { 20 - handleIntent(it) 20 + OnNewIntent { 21 + handleIntent(it) 22 + } 21 23 } 22 - } 23 24 24 25 private fun handleIntent(intent: Intent?) { 25 - if(appContext.currentActivity == null || intent == null) return 26 + if (appContext.currentActivity == null || intent == null) return 26 27 27 28 if (intent.action == Intent.ACTION_SEND) { 28 29 if (intent.type == "text/plain") { ··· 40 41 private fun handleTextIntent(intent: Intent) { 41 42 intent.getStringExtra(Intent.EXTRA_TEXT)?.let { 42 43 val encoded = URLEncoder.encode(it, "UTF-8") 43 - "bluesky://intent/compose?text=${encoded}".toUri().let { uri -> 44 + "bluesky://intent/compose?text=$encoded".toUri().let { uri -> 44 45 val newIntent = Intent(Intent.ACTION_VIEW, uri) 45 46 appContext.currentActivity?.startActivity(newIntent) 46 47 } ··· 48 49 } 49 50 50 51 private fun handleImageIntent(intent: Intent) { 51 - val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 52 - intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) 53 - } else { 54 - intent.getParcelableExtra(Intent.EXTRA_STREAM) 55 - } 52 + val uri = 53 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 54 + intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) 55 + } else { 56 + intent.getParcelableExtra(Intent.EXTRA_STREAM) 57 + } 56 58 if (uri == null) return 57 59 58 60 handleImageIntents(listOf(uri)) ··· 76 78 uris.forEachIndexed { index, uri -> 77 79 val info = getImageInfo(uri) 78 80 val params = buildUriData(info) 79 - allParams = "${allParams}${params}" 81 + allParams = "${allParams}$params" 80 82 81 83 if (index < uris.count() - 1) { 82 - allParams = "${allParams}," 84 + allParams = "$allParams," 83 85 } 84 86 } 85 87 86 88 val encoded = URLEncoder.encode(allParams, "UTF-8") 87 89 88 - "bluesky://intent/compose?imageUris=${encoded}".toUri().let { 90 + "bluesky://intent/compose?imageUris=$encoded".toUri().let { 89 91 val newIntent = Intent(Intent.ACTION_VIEW, it) 90 92 appContext.currentActivity?.startActivity(newIntent) 91 93 } ··· 104 106 return mapOf( 105 107 "width" to bitmap.width, 106 108 "height" to bitmap.height, 107 - "path" to file.path.toString() 109 + "path" to file.path.toString(), 108 110 ) 109 111 } 110 112 ··· 114 116 val path = info.getValue("path") 115 117 val width = info.getValue("width") 116 118 val height = info.getValue("height") 117 - return "file://${path}|${width}|${height}" 119 + return "file://$path|$width|$height" 118 120 } 119 121 }
+1 -1
modules/expo-scroll-forwarder/ios/ExpoScrollForwarderModule.swift
··· 3 3 public class ExpoScrollForwarderModule: Module { 4 4 public func definition() -> ModuleDefinition { 5 5 Name("ExpoScrollForwarder") 6 - 6 + 7 7 View(ExpoScrollForwarderView.self) { 8 8 Prop("scrollViewTag") { (view: ExpoScrollForwarderView, prop: Int) in 9 9 view.scrollViewTag = prop
+37 -39
modules/expo-scroll-forwarder/ios/ExpoScrollForwarderView.swift
··· 8 8 self.tryFindScrollView() 9 9 } 10 10 } 11 - 11 + 12 12 private var rctScrollView: RCTScrollView? 13 13 private var rctRefreshCtrl: RCTRefreshControl? 14 14 private var cancelGestureRecognizers: [UIGestureRecognizer]? 15 15 private var animTimer: Timer? 16 16 private var initialOffset: CGFloat = 0.0 17 17 private var didImpact: Bool = false 18 - 18 + 19 19 required init(appContext: AppContext? = nil) { 20 20 super.init(appContext: appContext) 21 - 21 + 22 22 let pg = UIPanGestureRecognizer(target: self, action: #selector(callOnPan(_:))) 23 23 pg.delegate = self 24 24 self.addGestureRecognizer(pg) ··· 34 34 35 35 self.cancelGestureRecognizers = [lpg, tg] 36 36 } 37 - 38 37 39 38 // We don't want to recognize the scroll pan gesture and the swipe back gesture together 40 39 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 41 40 if gestureRecognizer is UIPanGestureRecognizer, otherGestureRecognizer is UIPanGestureRecognizer { 42 41 return false 43 42 } 44 - 43 + 45 44 return true 46 45 } 47 - 46 + 48 47 // We only want the "scroll" gesture to happen whenever the pan is vertical, otherwise it will 49 48 // interfere with the native swipe back gesture. 50 49 override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 51 50 guard let gestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else { 52 51 return true 53 52 } 54 - 53 + 55 54 let velocity = gestureRecognizer.velocity(in: self) 56 55 return abs(velocity.y) > abs(velocity.x) 57 56 } 58 - 57 + 59 58 // This will be used to cancel the scroll animation whenever we tap inside of the header. We don't need another 60 59 // recognizer for this one. 61 60 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { ··· 64 63 65 64 // This will be used to cancel the animation whenever we press inside of the scroll view. We don't want to change 66 65 // the scroll view gesture's delegate, so we add an additional recognizer to detect this. 67 - @IBAction func callOnPress(_ sender: UITapGestureRecognizer) -> Void { 66 + @IBAction func callOnPress(_ sender: UITapGestureRecognizer) { 68 67 self.stopTimer() 69 68 } 70 - 71 - @IBAction func callOnPan(_ sender: UIPanGestureRecognizer) -> Void { 69 + 70 + @IBAction func callOnPan(_ sender: UIPanGestureRecognizer) { 72 71 guard let rctsv = self.rctScrollView, let sv = rctsv.scrollView else { 73 72 return 74 73 } 75 74 76 75 let translation = sender.translation(in: self).y 77 - 76 + 78 77 if sender.state == .began { 79 78 if sv.contentOffset.y < 0 { 80 79 sv.contentOffset.y = 0 81 80 } 82 - 81 + 83 82 self.initialOffset = sv.contentOffset.y 84 83 } 85 84 86 85 if sender.state == .changed { 87 86 sv.contentOffset.y = self.dampenOffset(-translation + self.initialOffset) 88 - 87 + 89 88 if sv.contentOffset.y <= -130, !didImpact { 90 89 let generator = UIImpactFeedbackGenerator(style: .light) 91 90 generator.impactOccurred() 92 - 91 + 93 92 self.didImpact = true 94 93 } 95 94 } ··· 97 96 if sender.state == .ended { 98 97 let velocity = sender.velocity(in: self).y 99 98 self.didImpact = false 100 - 99 + 101 100 if sv.contentOffset.y <= -130 { 102 101 self.rctRefreshCtrl?.forwarderBeginRefreshing() 103 102 return ··· 108 107 if abs(velocity) < 250, sv.contentOffset.y >= 0 { 109 108 return 110 109 } 111 - 110 + 112 111 self.startDecayAnimation(translation, velocity) 113 112 } 114 113 } 115 - 114 + 116 115 func startDecayAnimation(_ translation: CGFloat, _ velocity: CGFloat) { 117 116 guard let sv = self.rctScrollView?.scrollView else { 118 117 return 119 118 } 120 - 119 + 121 120 var velocity = velocity 122 - 121 + 123 122 self.enableCancelGestureRecognizers() 124 - 123 + 125 124 if velocity > 0 { 126 125 velocity = min(velocity, 5000) 127 126 } else { 128 127 velocity = max(velocity, -5000) 129 128 } 130 - 129 + 131 130 var animTranslation = -translation 132 - self.animTimer = Timer.scheduledTimer(withTimeInterval: 1.0 / 120, repeats: true) { timer in 131 + self.animTimer = Timer.scheduledTimer(withTimeInterval: 1.0 / 120, repeats: true) { _ in 133 132 velocity *= 0.9875 134 133 animTranslation = (-velocity / 120) + animTranslation 135 - 134 + 136 135 let nextOffset = self.dampenOffset(animTranslation + self.initialOffset) 137 - 136 + 138 137 if nextOffset <= 0 { 139 138 if self.initialOffset <= 1 { 140 139 self.scrollToOffset(0) 141 140 } else { 142 141 sv.contentOffset.y = 0 143 142 } 144 - 143 + 145 144 self.stopTimer() 146 145 return 147 146 } else { ··· 153 152 } 154 153 } 155 154 } 156 - 155 + 157 156 func dampenOffset(_ offset: CGFloat) -> CGFloat { 158 157 if offset < 0 { 159 158 return offset - (offset * 0.55) 160 159 } 161 - 160 + 162 161 return offset 163 162 } 164 - 163 + 165 164 func tryFindScrollView() { 166 165 guard let scrollViewTag = scrollViewTag else { 167 166 return 168 167 } 169 - 168 + 170 169 // Before we switch to a different scrollview, we always want to remove the cancel gesture recognizer. 171 170 // Otherwise we might end up with duplicates when we switch back to that scrollview. 172 171 self.removeCancelGestureRecognizers() 173 - 172 + 174 173 self.rctScrollView = self.appContext? 175 174 .findView(withTag: scrollViewTag, ofType: RCTScrollView.self) 176 175 self.rctRefreshCtrl = self.rctScrollView?.scrollView.refreshControl as? RCTRefreshControl 177 - 176 + 178 177 self.addCancelGestureRecognizers() 179 178 } 180 - 179 + 181 180 func addCancelGestureRecognizers() { 182 181 self.cancelGestureRecognizers?.forEach { r in 183 182 self.rctScrollView?.scrollView?.addGestureRecognizer(r) 184 183 } 185 184 } 186 - 185 + 187 186 func removeCancelGestureRecognizers() { 188 187 self.cancelGestureRecognizers?.forEach { r in 189 188 self.rctScrollView?.scrollView?.removeGestureRecognizer(r) 190 189 } 191 190 } 192 191 193 - 194 192 func enableCancelGestureRecognizers() { 195 193 self.cancelGestureRecognizers?.forEach { r in 196 194 r.isEnabled = true 197 195 } 198 196 } 199 - 197 + 200 198 func disableCancelGestureRecognizers() { 201 199 self.cancelGestureRecognizers?.forEach { r in 202 200 r.isEnabled = false 203 201 } 204 202 } 205 - 206 - func scrollToOffset(_ offset: Int, animated: Bool = true) -> Void { 203 + 204 + func scrollToOffset(_ offset: Int, animated: Bool = true) { 207 205 self.rctScrollView?.scroll(toOffset: CGPoint(x: 0, y: offset), animated: animated) 208 206 } 209 207 210 - func stopTimer() -> Void { 208 + func stopTimer() { 211 209 self.disableCancelGestureRecognizers() 212 210 self.animTimer?.invalidate() 213 211 self.animTimer = nil
+2
package.json
··· 29 29 "test-ci": "NODE_ENV=test jest --ci --forceExit --reporters=default --reporters=jest-junit", 30 30 "test-coverage": "NODE_ENV=test jest --coverage", 31 31 "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx src", 32 + "lint-native": "swiftlint ./modules && ktlint ./modules", 33 + "lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules", 32 34 "typecheck": "tsc --project ./tsconfig.check.json", 33 35 "e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts", 34 36 "e2e:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",