Lint native files (#4768)
parent
b433469ab9
commit
2397104ad6
|
@ -0,0 +1,2 @@
|
||||||
|
[*.{kt,kts}]
|
||||||
|
indent_size=2
|
|
@ -30,12 +30,11 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleText(item: NSItemProvider) async -> Void {
|
private func handleText(item: NSItemProvider) async {
|
||||||
do {
|
do {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
||||||
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)")
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
{
|
|
||||||
_ = self.openURL(url)
|
_ = self.openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,12 +44,11 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleUrl(item: NSItemProvider) async -> Void {
|
private func handleUrl(item: NSItemProvider) async {
|
||||||
do {
|
do {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
||||||
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)")
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
{
|
|
||||||
_ = self.openURL(url)
|
_ = self.openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +58,7 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleImages(items: [NSItemProvider]) async -> Void {
|
private func handleImages(items: [NSItemProvider]) async {
|
||||||
let firstFourItems: [NSItemProvider]
|
let firstFourItems: [NSItemProvider]
|
||||||
if items.count < 4 {
|
if items.count < 4 {
|
||||||
firstFourItems = items
|
firstFourItems = items
|
||||||
|
@ -72,7 +70,7 @@ class ShareViewController: UIViewController {
|
||||||
var imageUris = ""
|
var imageUris = ""
|
||||||
|
|
||||||
for (index, item) in firstFourItems.enumerated() {
|
for (index, item) in firstFourItems.enumerated() {
|
||||||
var imageUriInfo: String? = nil
|
var imageUriInfo: String?
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if let dataUri = try await item.loadItem(forTypeIdentifier: "public.image") as? URL {
|
if let dataUri = try await item.loadItem(forTypeIdentifier: "public.image") as? URL {
|
||||||
|
@ -100,8 +98,7 @@ class ShareViewController: UIViewController {
|
||||||
|
|
||||||
if valid,
|
if valid,
|
||||||
let encoded = imageUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
let encoded = imageUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?imageUris=\(encoded)")
|
let url = URL(string: "\(self.appScheme)://intent/compose?imageUris=\(encoded)") {
|
||||||
{
|
|
||||||
_ = self.openURL(url)
|
_ = self.openURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,13 +116,11 @@ class ShareViewController: UIViewController {
|
||||||
// extension does.
|
// extension does.
|
||||||
if let dir = FileManager()
|
if let dir = FileManager()
|
||||||
.containerURL(
|
.containerURL(
|
||||||
forSecurityApplicationGroupIdentifier: "group.app.bsky")
|
forSecurityApplicationGroupIdentifier: "group.app.bsky") {
|
||||||
{
|
|
||||||
let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg"
|
let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg"
|
||||||
|
|
||||||
if let newUri = URL(string: filePath),
|
if let newUri = URL(string: filePath),
|
||||||
let jpegData = image.jpegData(compressionQuality: 1)
|
let jpegData = image.jpegData(compressionQuality: 1) {
|
||||||
{
|
|
||||||
try jpegData.write(to: newUri)
|
try jpegData.write(to: newUri)
|
||||||
return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)"
|
return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)"
|
||||||
}
|
}
|
||||||
|
@ -136,7 +131,7 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func completeRequest() -> Void {
|
private func completeRequest() {
|
||||||
self.extensionContext?.completeRequest(returningItems: nil)
|
self.extensionContext?.completeRequest(returningItems: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.google.firebase.messaging.RemoteMessage
|
||||||
|
|
||||||
class BackgroundNotificationHandler(
|
class BackgroundNotificationHandler(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val notifInterface: BackgroundNotificationHandlerInterface
|
private val notifInterface: BackgroundNotificationHandlerInterface,
|
||||||
) {
|
) {
|
||||||
fun handleMessage(remoteMessage: RemoteMessage) {
|
fun handleMessage(remoteMessage: RemoteMessage) {
|
||||||
if (ExpoBackgroundNotificationHandlerModule.isForegrounded) {
|
if (ExpoBackgroundNotificationHandlerModule.isForegrounded) {
|
||||||
|
|
|
@ -8,7 +8,8 @@ class ExpoBackgroundNotificationHandlerModule : Module() {
|
||||||
var isForegrounded = false
|
var isForegrounded = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun definition() = ModuleDefinition {
|
override fun definition() =
|
||||||
|
ModuleDefinition {
|
||||||
Name("ExpoBackgroundNotificationHandler")
|
Name("ExpoBackgroundNotificationHandler")
|
||||||
|
|
||||||
OnCreate {
|
OnCreate {
|
||||||
|
|
|
@ -2,7 +2,8 @@ package expo.modules.backgroundnotificationhandler
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
val DEFAULTS = mapOf<String, Any>(
|
val DEFAULTS =
|
||||||
|
mapOf<String, Any>(
|
||||||
"playSoundChat" to true,
|
"playSoundChat" to true,
|
||||||
"playSoundFollow" to false,
|
"playSoundFollow" to false,
|
||||||
"playSoundLike" to false,
|
"playSoundLike" to false,
|
||||||
|
@ -10,11 +11,14 @@ val DEFAULTS = mapOf<String, Any>(
|
||||||
"playSoundQuote" to false,
|
"playSoundQuote" to false,
|
||||||
"playSoundReply" to false,
|
"playSoundReply" to false,
|
||||||
"playSoundRepost" to false,
|
"playSoundRepost" to false,
|
||||||
"mutedThreads" to mapOf<String, List<String>>()
|
"mutedThreads" to mapOf<String, List<String>>(),
|
||||||
)
|
)
|
||||||
|
|
||||||
class NotificationPrefs (private val context: Context?) {
|
class NotificationPrefs(
|
||||||
private val prefs = context?.getSharedPreferences("xyz.blueskyweb.app", Context.MODE_PRIVATE)
|
private val context: Context?,
|
||||||
|
) {
|
||||||
|
private val prefs =
|
||||||
|
context?.getSharedPreferences("xyz.blueskyweb.app", Context.MODE_PRIVATE)
|
||||||
?: throw Error("Context is null")
|
?: throw Error("Context is null")
|
||||||
|
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
|
@ -41,94 +45,99 @@ class NotificationPrefs (private val context: Context?) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAllPrefs(): MutableMap<String, *> {
|
fun getAllPrefs(): MutableMap<String, *> = prefs.all
|
||||||
return prefs.all
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBoolean(key: String): Boolean {
|
fun getBoolean(key: String): Boolean = prefs.getBoolean(key, false)
|
||||||
return prefs.getBoolean(key, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getString(key: String): String? {
|
fun getString(key: String): String? = prefs.getString(key, null)
|
||||||
return prefs.getString(key, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getStringArray(key: String): Array<String>? {
|
fun getStringArray(key: String): Array<String>? = prefs.getStringSet(key, null)?.toTypedArray()
|
||||||
return prefs.getStringSet(key, null)?.toTypedArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setBoolean(key: String, value: Boolean) {
|
fun setBoolean(
|
||||||
|
key: String,
|
||||||
|
value: Boolean,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
putBoolean(key, value)
|
putBoolean(key, value)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setString(key: String, value: String) {
|
fun setString(
|
||||||
|
key: String,
|
||||||
|
value: String,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
putString(key, value)
|
putString(key, value)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setStringArray(key: String, value: Array<String>) {
|
fun setStringArray(
|
||||||
|
key: String,
|
||||||
|
value: Array<String>,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
putStringSet(key, value.toSet())
|
putStringSet(key, value.toSet())
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addToStringArray(key: String, string: String) {
|
fun addToStringArray(
|
||||||
|
key: String,
|
||||||
|
string: String,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
||||||
set.add(string)
|
set.add(string)
|
||||||
putStringSet(key, set)
|
putStringSet(key, set)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeFromStringArray(key: String, string: String) {
|
fun removeFromStringArray(
|
||||||
|
key: String,
|
||||||
|
string: String,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
||||||
set.remove(string)
|
set.remove(string)
|
||||||
putStringSet(key, set)
|
putStringSet(key, set)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addManyToStringArray(key: String, strings: Array<String>) {
|
fun addManyToStringArray(
|
||||||
|
key: String,
|
||||||
|
strings: Array<String>,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
||||||
set.addAll(strings.toSet())
|
set.addAll(strings.toSet())
|
||||||
putStringSet(key, set)
|
putStringSet(key, set)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeManyFromStringArray(key: String, strings: Array<String>) {
|
fun removeManyFromStringArray(
|
||||||
|
key: String,
|
||||||
|
strings: Array<String>,
|
||||||
|
) {
|
||||||
prefs
|
prefs
|
||||||
.edit()
|
.edit()
|
||||||
.apply {
|
.apply {
|
||||||
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
|
||||||
set.removeAll(strings.toSet())
|
set.removeAll(strings.toSet())
|
||||||
putStringSet(key, set)
|
putStringSet(key, set)
|
||||||
}
|
}.apply()
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ let DEFAULTS: [String:Any] = [
|
||||||
"playSoundReply": false,
|
"playSoundReply": false,
|
||||||
"playSoundRepost": false,
|
"playSoundRepost": false,
|
||||||
"mutedThreads": [:] as! [String: [String]],
|
"mutedThreads": [:] as! [String: [String]],
|
||||||
"badgeCount": 0,
|
"badgeCount": 0
|
||||||
]
|
]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -64,22 +64,21 @@ public class ExpoBackgroundNotificationHandlerModule: Module {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFunction("setBoolAsync") { (forKey: String, value: Bool) -> Void in
|
AsyncFunction("setBoolAsync") { (forKey: String, value: Bool) in
|
||||||
userDefaults?.setValue(value, forKey: forKey)
|
userDefaults?.setValue(value, forKey: forKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFunction("setStringAsync") { (forKey: String, value: String) -> Void in
|
AsyncFunction("setStringAsync") { (forKey: String, value: String) in
|
||||||
userDefaults?.setValue(value, forKey: forKey)
|
userDefaults?.setValue(value, forKey: forKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFunction("setStringArrayAsync") { (forKey: String, value: [String]) -> Void in
|
AsyncFunction("setStringArrayAsync") { (forKey: String, value: [String]) in
|
||||||
userDefaults?.setValue(value, forKey: forKey)
|
userDefaults?.setValue(value, forKey: forKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFunction("addToStringArrayAsync") { (forKey: String, string: String) in
|
AsyncFunction("addToStringArrayAsync") { (forKey: String, string: String) in
|
||||||
if var curr = userDefaults?.stringArray(forKey: forKey),
|
if var curr = userDefaults?.stringArray(forKey: forKey),
|
||||||
!curr.contains(string)
|
!curr.contains(string) {
|
||||||
{
|
|
||||||
curr.append(string)
|
curr.append(string)
|
||||||
userDefaults?.setValue(curr, forKey: forKey)
|
userDefaults?.setValue(curr, forKey: forKey)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,10 @@ import android.graphics.Canvas
|
||||||
import android.graphics.drawable.Animatable
|
import android.graphics.drawable.Animatable
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
|
|
||||||
class AppCompatImageViewExtended(context: Context, private val parent: GifView): AppCompatImageView(context) {
|
class AppCompatImageViewExtended(
|
||||||
|
context: Context,
|
||||||
|
private val parent: GifView,
|
||||||
|
) : AppCompatImageView(context) {
|
||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
super.onDraw(canvas)
|
super.onDraw(canvas)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ import expo.modules.kotlin.modules.Module
|
||||||
import expo.modules.kotlin.modules.ModuleDefinition
|
import expo.modules.kotlin.modules.ModuleDefinition
|
||||||
|
|
||||||
class ExpoBlueskyGifViewModule : Module() {
|
class ExpoBlueskyGifViewModule : Module() {
|
||||||
override fun definition() = ModuleDefinition {
|
override fun definition() =
|
||||||
|
ModuleDefinition {
|
||||||
Name("ExpoBlueskyGifView")
|
Name("ExpoBlueskyGifView")
|
||||||
|
|
||||||
AsyncFunction("prefetchAsync") { sources: List<String> ->
|
AsyncFunction("prefetchAsync") { sources: List<String> ->
|
||||||
|
@ -23,7 +24,7 @@ class ExpoBlueskyGifViewModule : Module() {
|
||||||
|
|
||||||
View(GifView::class) {
|
View(GifView::class) {
|
||||||
Events(
|
Events(
|
||||||
"onPlayerStateChange"
|
"onPlayerStateChange",
|
||||||
)
|
)
|
||||||
|
|
||||||
Prop("source") { view: GifView, source: String ->
|
Prop("source") { view: GifView, source: String ->
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package expo.modules.blueskygifview
|
package expo.modules.blueskygifview
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Animatable
|
import android.graphics.drawable.Animatable
|
||||||
|
@ -15,7 +14,10 @@ import expo.modules.kotlin.exception.Exceptions
|
||||||
import expo.modules.kotlin.viewevent.EventDispatcher
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
||||||
import expo.modules.kotlin.views.ExpoView
|
import expo.modules.kotlin.views.ExpoView
|
||||||
|
|
||||||
class GifView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
|
class GifView(
|
||||||
|
context: Context,
|
||||||
|
appContext: AppContext,
|
||||||
|
) : ExpoView(context, appContext) {
|
||||||
// Events
|
// Events
|
||||||
private val onPlayerStateChange by EventDispatcher()
|
private val onPlayerStateChange by EventDispatcher()
|
||||||
|
|
||||||
|
@ -44,7 +46,6 @@ class GifView(context: Context, appContext: AppContext) : ExpoView(context, appC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// <editor-fold desc="Lifecycle">
|
// <editor-fold desc="Lifecycle">
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -79,16 +80,19 @@ class GifView(context: Context, appContext: AppContext) : ExpoView(context, appC
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.webpRequest = glide.load(source)
|
this.webpRequest =
|
||||||
|
glide
|
||||||
|
.load(source)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
||||||
.skipMemoryCache(false)
|
.skipMemoryCache(false)
|
||||||
.listener(object: RequestListener<Drawable> {
|
.listener(
|
||||||
|
object : RequestListener<Drawable> {
|
||||||
override fun onResourceReady(
|
override fun onResourceReady(
|
||||||
resource: Drawable?,
|
resource: Drawable?,
|
||||||
model: Any?,
|
model: Any?,
|
||||||
target: Target<Drawable>?,
|
target: Target<Drawable>?,
|
||||||
dataSource: com.bumptech.glide.load.DataSource?,
|
dataSource: com.bumptech.glide.load.DataSource?,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (placeholderRequest != null) {
|
if (placeholderRequest != null) {
|
||||||
glide.clear(placeholderRequest)
|
glide.clear(placeholderRequest)
|
||||||
|
@ -100,25 +104,26 @@ class GifView(context: Context, appContext: AppContext) : ExpoView(context, appC
|
||||||
e: GlideException?,
|
e: GlideException?,
|
||||||
model: Any?,
|
model: Any?,
|
||||||
target: Target<Drawable>?,
|
target: Target<Drawable>?,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean = true
|
||||||
return true
|
},
|
||||||
}
|
).into(this.imageView)
|
||||||
})
|
|
||||||
.into(this.imageView)
|
|
||||||
|
|
||||||
if (this.imageView.drawable == null || this.imageView.drawable !is Animatable) {
|
if (this.imageView.drawable == null || this.imageView.drawable !is Animatable) {
|
||||||
this.placeholderRequest = glide.load(placeholderSource)
|
this.placeholderRequest =
|
||||||
|
glide
|
||||||
|
.load(placeholderSource)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
||||||
// Let's not bloat the memory cache with placeholders
|
// Let's not bloat the memory cache with placeholders
|
||||||
.skipMemoryCache(true)
|
.skipMemoryCache(true)
|
||||||
.listener(object: RequestListener<Drawable> {
|
.listener(
|
||||||
|
object : RequestListener<Drawable> {
|
||||||
override fun onResourceReady(
|
override fun onResourceReady(
|
||||||
resource: Drawable?,
|
resource: Drawable?,
|
||||||
model: Any?,
|
model: Any?,
|
||||||
target: Target<Drawable>?,
|
target: Target<Drawable>?,
|
||||||
dataSource: com.bumptech.glide.load.DataSource?,
|
dataSource: com.bumptech.glide.load.DataSource?,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// Incase this request finishes after the webp, let's just not set
|
// Incase this request finishes after the webp, let's just not set
|
||||||
// the drawable. This shouldn't happen because the request should get cancelled
|
// the drawable. This shouldn't happen because the request should get cancelled
|
||||||
|
@ -132,12 +137,10 @@ class GifView(context: Context, appContext: AppContext) : ExpoView(context, appC
|
||||||
e: GlideException?,
|
e: GlideException?,
|
||||||
model: Any?,
|
model: Any?,
|
||||||
target: Target<Drawable>?,
|
target: Target<Drawable>?,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean = true
|
||||||
return true
|
},
|
||||||
}
|
).submit()
|
||||||
})
|
|
||||||
.submit()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,10 +173,12 @@ class GifView(context: Context, appContext: AppContext) : ExpoView(context, appC
|
||||||
// <editor-fold desc="Util">
|
// <editor-fold desc="Util">
|
||||||
|
|
||||||
fun firePlayerStateChange() {
|
fun firePlayerStateChange() {
|
||||||
onPlayerStateChange(mapOf(
|
onPlayerStateChange(
|
||||||
|
mapOf(
|
||||||
"isPlaying" to this.isPlaying,
|
"isPlaying" to this.isPlaying,
|
||||||
"isLoaded" to this.isLoaded,
|
"isLoaded" to this.isLoaded,
|
||||||
))
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
|
@ -22,8 +22,8 @@ public class GifView: ExpoView, AVPlayerViewControllerDelegate {
|
||||||
private var placeholderOperation: SDWebImageCombinedOperation?
|
private var placeholderOperation: SDWebImageCombinedOperation?
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
var source: String? = nil
|
var source: String?
|
||||||
var placeholderSource: String? = nil
|
var placeholderSource: String?
|
||||||
var autoplay = true {
|
var autoplay = true {
|
||||||
didSet {
|
didSet {
|
||||||
if !autoplay {
|
if !autoplay {
|
||||||
|
@ -78,8 +78,7 @@ public class GifView: ExpoView, AVPlayerViewControllerDelegate {
|
||||||
// See:
|
// See:
|
||||||
// https://github.com/SDWebImage/SDWebImage/blob/master/Docs/HowToUse.md#using-asynchronous-image-caching-independently
|
// https://github.com/SDWebImage/SDWebImage/blob/master/Docs/HowToUse.md#using-asynchronous-image-caching-independently
|
||||||
if !SDImageCache.shared.diskImageDataExists(withKey: source),
|
if !SDImageCache.shared.diskImageDataExists(withKey: source),
|
||||||
let url = URL(string: placeholderSource)
|
let url = URL(string: placeholderSource) {
|
||||||
{
|
|
||||||
self.placeholderOperation = imageManager.loadImage(
|
self.placeholderOperation = imageManager.loadImage(
|
||||||
with: url,
|
with: url,
|
||||||
options: [.retryFailed],
|
options: [.retryFailed],
|
||||||
|
@ -132,8 +131,7 @@ public class GifView: ExpoView, AVPlayerViewControllerDelegate {
|
||||||
if let placeholderSource = self.placeholderSource,
|
if let placeholderSource = self.placeholderSource,
|
||||||
imageUrl?.absoluteString == placeholderSource,
|
imageUrl?.absoluteString == placeholderSource,
|
||||||
self.imageView.image == nil,
|
self.imageView.image == nil,
|
||||||
let image = image
|
let image = image {
|
||||||
{
|
|
||||||
self.setImage(image)
|
self.setImage(image)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -142,8 +140,7 @@ public class GifView: ExpoView, AVPlayerViewControllerDelegate {
|
||||||
imageUrl?.absoluteString == source,
|
imageUrl?.absoluteString == source,
|
||||||
// UIImage perf suckssss if the image is animated
|
// UIImage perf suckssss if the image is animated
|
||||||
let data = data,
|
let data = data,
|
||||||
let animatedImage = SDAnimatedImage(data: data)
|
let animatedImage = SDAnimatedImage(data: data) {
|
||||||
{
|
|
||||||
self.placeholderOperation?.cancel()
|
self.placeholderOperation?.cancel()
|
||||||
self.isPlaying = self.autoplay
|
self.isPlaying = self.autoplay
|
||||||
self.isLoaded = true
|
self.isLoaded = true
|
||||||
|
|
|
@ -4,7 +4,8 @@ import expo.modules.kotlin.modules.Module
|
||||||
import expo.modules.kotlin.modules.ModuleDefinition
|
import expo.modules.kotlin.modules.ModuleDefinition
|
||||||
|
|
||||||
class ExpoBlueskyDevicePrefsModule : Module() {
|
class ExpoBlueskyDevicePrefsModule : Module() {
|
||||||
override fun definition() = ModuleDefinition {
|
override fun definition() =
|
||||||
|
ModuleDefinition {
|
||||||
Name("ExpoBlueskyDevicePrefs")
|
Name("ExpoBlueskyDevicePrefs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,19 @@ package expo.modules.blueskyswissarmy.referrer
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.android.installreferrer.api.InstallReferrerClient
|
import com.android.installreferrer.api.InstallReferrerClient
|
||||||
import com.android.installreferrer.api.InstallReferrerStateListener
|
import com.android.installreferrer.api.InstallReferrerStateListener
|
||||||
|
import expo.modules.kotlin.Promise
|
||||||
import expo.modules.kotlin.modules.Module
|
import expo.modules.kotlin.modules.Module
|
||||||
import expo.modules.kotlin.modules.ModuleDefinition
|
import expo.modules.kotlin.modules.ModuleDefinition
|
||||||
import expo.modules.kotlin.Promise
|
|
||||||
|
|
||||||
class ExpoBlueskyReferrerModule : Module() {
|
class ExpoBlueskyReferrerModule : Module() {
|
||||||
override fun definition() = ModuleDefinition {
|
override fun definition() =
|
||||||
|
ModuleDefinition {
|
||||||
Name("ExpoBlueskyReferrer")
|
Name("ExpoBlueskyReferrer")
|
||||||
|
|
||||||
AsyncFunction("getGooglePlayReferrerInfoAsync") { promise: Promise ->
|
AsyncFunction("getGooglePlayReferrerInfoAsync") { promise: Promise ->
|
||||||
val referrerClient = InstallReferrerClient.newBuilder(appContext.reactContext).build()
|
val referrerClient = InstallReferrerClient.newBuilder(appContext.reactContext).build()
|
||||||
referrerClient.startConnection(object : InstallReferrerStateListener {
|
referrerClient.startConnection(
|
||||||
|
object : InstallReferrerStateListener {
|
||||||
override fun onInstallReferrerSetupFinished(responseCode: Int) {
|
override fun onInstallReferrerSetupFinished(responseCode: Int) {
|
||||||
if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
|
if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
|
||||||
Log.d("ExpoGooglePlayReferrer", "Successfully retrieved referrer info.")
|
Log.d("ExpoGooglePlayReferrer", "Successfully retrieved referrer info.")
|
||||||
|
@ -25,15 +27,15 @@ class ExpoBlueskyReferrerModule : Module() {
|
||||||
mapOf(
|
mapOf(
|
||||||
"installReferrer" to response.installReferrer,
|
"installReferrer" to response.installReferrer,
|
||||||
"clickTimestamp" to response.referrerClickTimestampSeconds,
|
"clickTimestamp" to response.referrerClickTimestampSeconds,
|
||||||
"installTimestamp" to response.installBeginTimestampSeconds
|
"installTimestamp" to response.installBeginTimestampSeconds,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Unknown error.")
|
Log.d("ExpoGooglePlayReferrer", "Failed to get referrer info. Unknown error.")
|
||||||
promise.reject(
|
promise.reject(
|
||||||
"ERR_GOOGLE_PLAY_REFERRER_UNKNOWN",
|
"ERR_GOOGLE_PLAY_REFERRER_UNKNOWN",
|
||||||
"Failed to get referrer info",
|
"Failed to get referrer info",
|
||||||
Exception("Failed to get referrer info")
|
Exception("Failed to get referrer info"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
referrerClient.endConnection()
|
referrerClient.endConnection()
|
||||||
|
@ -45,10 +47,11 @@ class ExpoBlueskyReferrerModule : Module() {
|
||||||
promise.reject(
|
promise.reject(
|
||||||
"ERR_GOOGLE_PLAY_REFERRER_DISCONNECTED",
|
"ERR_GOOGLE_PLAY_REFERRER_DISCONNECTED",
|
||||||
"Failed to get referrer info",
|
"Failed to get referrer info",
|
||||||
Exception("Failed to get referrer info")
|
Exception("Failed to get referrer info"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,8 @@ import java.io.FileOutputStream
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
class ExpoReceiveAndroidIntentsModule : Module() {
|
class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
override fun definition() = ModuleDefinition {
|
override fun definition() =
|
||||||
|
ModuleDefinition {
|
||||||
Name("ExpoReceiveAndroidIntents")
|
Name("ExpoReceiveAndroidIntents")
|
||||||
|
|
||||||
OnNewIntent {
|
OnNewIntent {
|
||||||
|
@ -40,7 +41,7 @@ class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
private fun handleTextIntent(intent: Intent) {
|
private fun handleTextIntent(intent: Intent) {
|
||||||
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
||||||
val encoded = URLEncoder.encode(it, "UTF-8")
|
val encoded = URLEncoder.encode(it, "UTF-8")
|
||||||
"bluesky://intent/compose?text=${encoded}".toUri().let { uri ->
|
"bluesky://intent/compose?text=$encoded".toUri().let { uri ->
|
||||||
val newIntent = Intent(Intent.ACTION_VIEW, uri)
|
val newIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||||
appContext.currentActivity?.startActivity(newIntent)
|
appContext.currentActivity?.startActivity(newIntent)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,8 @@ class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleImageIntent(intent: Intent) {
|
private fun handleImageIntent(intent: Intent) {
|
||||||
val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
val uri =
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
|
intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
|
||||||
} else {
|
} else {
|
||||||
intent.getParcelableExtra(Intent.EXTRA_STREAM)
|
intent.getParcelableExtra(Intent.EXTRA_STREAM)
|
||||||
|
@ -76,16 +78,16 @@ class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
uris.forEachIndexed { index, uri ->
|
uris.forEachIndexed { index, uri ->
|
||||||
val info = getImageInfo(uri)
|
val info = getImageInfo(uri)
|
||||||
val params = buildUriData(info)
|
val params = buildUriData(info)
|
||||||
allParams = "${allParams}${params}"
|
allParams = "${allParams}$params"
|
||||||
|
|
||||||
if (index < uris.count() - 1) {
|
if (index < uris.count() - 1) {
|
||||||
allParams = "${allParams},"
|
allParams = "$allParams,"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val encoded = URLEncoder.encode(allParams, "UTF-8")
|
val encoded = URLEncoder.encode(allParams, "UTF-8")
|
||||||
|
|
||||||
"bluesky://intent/compose?imageUris=${encoded}".toUri().let {
|
"bluesky://intent/compose?imageUris=$encoded".toUri().let {
|
||||||
val newIntent = Intent(Intent.ACTION_VIEW, it)
|
val newIntent = Intent(Intent.ACTION_VIEW, it)
|
||||||
appContext.currentActivity?.startActivity(newIntent)
|
appContext.currentActivity?.startActivity(newIntent)
|
||||||
}
|
}
|
||||||
|
@ -104,7 +106,7 @@ class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
return mapOf(
|
return mapOf(
|
||||||
"width" to bitmap.width,
|
"width" to bitmap.width,
|
||||||
"height" to bitmap.height,
|
"height" to bitmap.height,
|
||||||
"path" to file.path.toString()
|
"path" to file.path.toString(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +116,6 @@ class ExpoReceiveAndroidIntentsModule : Module() {
|
||||||
val path = info.getValue("path")
|
val path = info.getValue("path")
|
||||||
val width = info.getValue("width")
|
val width = info.getValue("width")
|
||||||
val height = info.getValue("height")
|
val height = info.getValue("height")
|
||||||
return "file://${path}|${width}|${height}"
|
return "file://$path|$width|$height"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ class ExpoScrollForwarderView: ExpoView, UIGestureRecognizerDelegate {
|
||||||
self.cancelGestureRecognizers = [lpg, tg]
|
self.cancelGestureRecognizers = [lpg, tg]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// We don't want to recognize the scroll pan gesture and the swipe back gesture together
|
// We don't want to recognize the scroll pan gesture and the swipe back gesture together
|
||||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
if gestureRecognizer is UIPanGestureRecognizer, otherGestureRecognizer is UIPanGestureRecognizer {
|
if gestureRecognizer is UIPanGestureRecognizer, otherGestureRecognizer is UIPanGestureRecognizer {
|
||||||
|
@ -64,11 +63,11 @@ class ExpoScrollForwarderView: ExpoView, UIGestureRecognizerDelegate {
|
||||||
|
|
||||||
// This will be used to cancel the animation whenever we press inside of the scroll view. We don't want to change
|
// This will be used to cancel the animation whenever we press inside of the scroll view. We don't want to change
|
||||||
// the scroll view gesture's delegate, so we add an additional recognizer to detect this.
|
// the scroll view gesture's delegate, so we add an additional recognizer to detect this.
|
||||||
@IBAction func callOnPress(_ sender: UITapGestureRecognizer) -> Void {
|
@IBAction func callOnPress(_ sender: UITapGestureRecognizer) {
|
||||||
self.stopTimer()
|
self.stopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func callOnPan(_ sender: UIPanGestureRecognizer) -> Void {
|
@IBAction func callOnPan(_ sender: UIPanGestureRecognizer) {
|
||||||
guard let rctsv = self.rctScrollView, let sv = rctsv.scrollView else {
|
guard let rctsv = self.rctScrollView, let sv = rctsv.scrollView else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -129,7 +128,7 @@ class ExpoScrollForwarderView: ExpoView, UIGestureRecognizerDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
var animTranslation = -translation
|
var animTranslation = -translation
|
||||||
self.animTimer = Timer.scheduledTimer(withTimeInterval: 1.0 / 120, repeats: true) { timer in
|
self.animTimer = Timer.scheduledTimer(withTimeInterval: 1.0 / 120, repeats: true) { _ in
|
||||||
velocity *= 0.9875
|
velocity *= 0.9875
|
||||||
animTranslation = (-velocity / 120) + animTranslation
|
animTranslation = (-velocity / 120) + animTranslation
|
||||||
|
|
||||||
|
@ -190,7 +189,6 @@ class ExpoScrollForwarderView: ExpoView, UIGestureRecognizerDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func enableCancelGestureRecognizers() {
|
func enableCancelGestureRecognizers() {
|
||||||
self.cancelGestureRecognizers?.forEach { r in
|
self.cancelGestureRecognizers?.forEach { r in
|
||||||
r.isEnabled = true
|
r.isEnabled = true
|
||||||
|
@ -203,11 +201,11 @@ class ExpoScrollForwarderView: ExpoView, UIGestureRecognizerDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollToOffset(_ offset: Int, animated: Bool = true) -> Void {
|
func scrollToOffset(_ offset: Int, animated: Bool = true) {
|
||||||
self.rctScrollView?.scroll(toOffset: CGPoint(x: 0, y: offset), animated: animated)
|
self.rctScrollView?.scroll(toOffset: CGPoint(x: 0, y: offset), animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopTimer() -> Void {
|
func stopTimer() {
|
||||||
self.disableCancelGestureRecognizers()
|
self.disableCancelGestureRecognizers()
|
||||||
self.animTimer?.invalidate()
|
self.animTimer?.invalidate()
|
||||||
self.animTimer = nil
|
self.animTimer = nil
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
"test-ci": "NODE_ENV=test jest --ci --forceExit --reporters=default --reporters=jest-junit",
|
"test-ci": "NODE_ENV=test jest --ci --forceExit --reporters=default --reporters=jest-junit",
|
||||||
"test-coverage": "NODE_ENV=test jest --coverage",
|
"test-coverage": "NODE_ENV=test jest --coverage",
|
||||||
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx src",
|
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx src",
|
||||||
|
"lint-native": "swiftlint ./modules && ktlint ./modules",
|
||||||
|
"lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules",
|
||||||
"typecheck": "tsc --project ./tsconfig.check.json",
|
"typecheck": "tsc --project ./tsconfig.check.json",
|
||||||
"e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts",
|
"e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts",
|
||||||
"e2e:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",
|
"e2e:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",
|
||||||
|
|
Loading…
Reference in New Issue