From baa1be4c23cd15e1e25c49433ecd6f4ba48bb748 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Tue, 1 Aug 2023 14:20:26 +0300 Subject: [PATCH 1/6] fix: issues with android build --- android/build.gradle | 2 +- android/src/main/AndroidManifest.xml | 5 +- .../src/main/AndroidManifestDeprecated.xml | 5 +- .../RTNGiphyGridViewManager.kt | 6 +- .../giphyreactnativesdk/dto/RTNGiphyMedia.kt | 23 ++-- .../events/OnGridMediaSelectEvent.kt | 2 +- .../utils/JsonArguments.kt | 107 ++++++++++++++++++ src/specs/GiphyGridViewNativeComponent.ts | 12 +- src/specs/GiphyVideoViewNativeComponent.ts | 12 +- 9 files changed, 145 insertions(+), 29 deletions(-) create mode 100644 android/src/main/java/com/giphyreactnativesdk/utils/JsonArguments.kt diff --git a/android/build.gradle b/android/build.gradle index 07e8ca06..717a2196 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -23,7 +23,7 @@ import groovy.json.JsonSlurper def registrationCompat = { def reactNativeManifest = file("$projectDir/../node_modules/react-native/package.json").exists() ? file("$projectDir/../node_modules/react-native/package.json") // developer mode, to run example app - : file("$projectDir/../../react-native/package.json") + : file("$projectDir/../../../react-native/package.json") def reactNativeVersion = new JsonSlurper().parseText(reactNativeManifest.text).version as String // Fabric was introduced at react-native@0.68, full CMake support were introduced at react-native@0.70 // Use Android.mk for compatibility with react-native@0.68/0.69 diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 0bfa73ba..c09f50d1 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1 +1,4 @@ - + + + diff --git a/android/src/main/AndroidManifestDeprecated.xml b/android/src/main/AndroidManifestDeprecated.xml index 5b2d93c0..c09f50d1 100644 --- a/android/src/main/AndroidManifestDeprecated.xml +++ b/android/src/main/AndroidManifestDeprecated.xml @@ -1 +1,4 @@ - + + + diff --git a/android/src/main/java/com/giphyreactnativesdk/RTNGiphyGridViewManager.kt b/android/src/main/java/com/giphyreactnativesdk/RTNGiphyGridViewManager.kt index 84a2f7dc..95893b05 100644 --- a/android/src/main/java/com/giphyreactnativesdk/RTNGiphyGridViewManager.kt +++ b/android/src/main/java/com/giphyreactnativesdk/RTNGiphyGridViewManager.kt @@ -1,6 +1,5 @@ package com.giphyreactnativesdk -import com.facebook.react.bridge.JSONArguments import com.facebook.react.bridge.ReactMethod import com.facebook.react.common.MapBuilder import com.facebook.react.module.annotations.ReactModule @@ -16,6 +15,7 @@ import com.giphy.sdk.ui.views.GifView import com.giphyreactnativesdk.events.OnGridContentUpdateEvent import com.giphyreactnativesdk.events.OnGridMediaSelectEvent import com.giphyreactnativesdk.events.OnGridScrollEvent +import com.giphyreactnativesdk.utils.JsonArguments @ReactModule(name = RTNGiphyGridViewManager.NAME) class RTNGiphyGridViewManager : @@ -37,7 +37,7 @@ class RTNGiphyGridViewManager : if (value.isNullOrEmpty()) { view?.setTheme(null) } else { - view?.setTheme(JSONArguments.fromJSONObjectString(value)) + view?.setTheme(JsonArguments.fromJSONObjectString(value)) } } @@ -71,7 +71,7 @@ class RTNGiphyGridViewManager : if (value.isNullOrEmpty()) { view?.setContent(null) } else { - view?.setContent(JSONArguments.fromJSONObjectString(value)) + view?.setContent(JsonArguments.fromJSONObjectString(value)) } } diff --git a/android/src/main/java/com/giphyreactnativesdk/dto/RTNGiphyMedia.kt b/android/src/main/java/com/giphyreactnativesdk/dto/RTNGiphyMedia.kt index 43ef30a4..c75ef2d0 100644 --- a/android/src/main/java/com/giphyreactnativesdk/dto/RTNGiphyMedia.kt +++ b/android/src/main/java/com/giphyreactnativesdk/dto/RTNGiphyMedia.kt @@ -1,6 +1,5 @@ package com.giphyreactnativesdk.dto -import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.WritableMap import com.giphy.sdk.core.models.Media import com.giphy.sdk.core.models.enums.MediaType @@ -9,6 +8,7 @@ import com.giphy.sdk.ui.utils.GifUtils import com.giphy.sdk.ui.utils.aspectRatio import com.giphyreactnativesdk.utils.jsonObjectToRNMap import com.google.gson.Gson +import com.google.gson.JsonElement object RTNGiphyMedia { @@ -18,17 +18,20 @@ object RTNGiphyMedia { } fun toRNValue(media: Media, renditionType: RenditionType?): WritableMap { + return jsonObjectToRNMap(toJson(media, renditionType)) + } + + fun toJson(media: Media, renditionType: RenditionType?): JsonElement { val gson = Gson() - val mediaJson = gson.toJsonTree(media) - val output = Arguments.createMap() + val output = HashMap() - output.putString("id", media.id) - output.putString("url", getGifURL(media, renditionType)) - output.putDouble("aspectRatio", media.aspectRatio.toDouble()) - output.putBoolean("isVideo", media.type == MediaType.video) - output.putBoolean("isDynamic", media.isDynamic) - output.putMap("data", jsonObjectToRNMap(mediaJson)) + output["id"] = media.id + output["url"] = getGifURL(media, renditionType) ?: "" + output["aspectRatio"] = media.aspectRatio.toDouble() + output["isVideo"] = media.type == MediaType.video + output["isDynamic"] = media.isDynamic + output["data"] = media - return output + return gson.toJsonTree(output) } } diff --git a/android/src/main/java/com/giphyreactnativesdk/events/OnGridMediaSelectEvent.kt b/android/src/main/java/com/giphyreactnativesdk/events/OnGridMediaSelectEvent.kt index 3aa477c6..13e25074 100644 --- a/android/src/main/java/com/giphyreactnativesdk/events/OnGridMediaSelectEvent.kt +++ b/android/src/main/java/com/giphyreactnativesdk/events/OnGridMediaSelectEvent.kt @@ -24,7 +24,7 @@ constructor( override fun getEventData(): WritableMap? { val event = Arguments.createMap() - event.putString("media", RTNGiphyMedia.toRNValue(media, renditionType).toString()) + event.putString("media", RTNGiphyMedia.toJson(media, renditionType).toString()) return event } diff --git a/android/src/main/java/com/giphyreactnativesdk/utils/JsonArguments.kt b/android/src/main/java/com/giphyreactnativesdk/utils/JsonArguments.kt new file mode 100644 index 00000000..f8d8a5a5 --- /dev/null +++ b/android/src/main/java/com/giphyreactnativesdk/utils/JsonArguments.kt @@ -0,0 +1,107 @@ +/** + * Source: https://github.com/facebook/react-native/blob/529c9524995e62184777046497f36437c59d7a7d/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSONArguments.java + */ +package com.giphyreactnativesdk.utils + +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject + +object JsonArguments { + /** + * Parse JSONObject to ReadableMap + * + * @param obj The JSONObject to be parsed + * @return readableMap from the JSONObject + */ + @Throws(JSONException::class) + fun fromJSONObject(obj: JSONObject): ReadableMap? { + val result = Arguments.createMap() + val keys = obj.keys() + while (keys.hasNext()) { + val key = keys.next() + val `val` = obj[key] + if (`val` is JSONObject) { + result.putMap(key, fromJSONObject(`val`)) + } else if (`val` is JSONArray) { + result.putArray(key, fromJSONArray(`val`)) + } else if (`val` is String) { + result.putString(key, `val`) + } else if (`val` is Boolean) { + result.putBoolean(key, `val`) + } else if (`val` is Int) { + result.putInt(key, `val`) + } else if (`val` is Double) { + result.putDouble(key, `val`) + } else if (`val` is Long) { + result.putInt(key, `val`.toInt()) + } else if (obj.isNull(key)) { + result.putNull(key) + } else { + // Unknown value type. Will throw + throw JSONException("Unexpected value when parsing JSON object. key: $key") + } + } + return result + } + + /** + * Parse String of JSON object to ReadableMap + * + * @param objStr The String JSON object to be parsed + * @return readableMap from the JSONArray + */ + @Throws(JSONException::class) + fun fromJSONObjectString(objStr: String?): ReadableMap? { + return fromJSONObject(JSONObject(objStr)) + } + + /** + * Parse JSONArray to ReadableArray + * + * @param arr The JSONArray to be parsed + * @return readableArray from the JSONArray + */ + @Throws(JSONException::class) + fun fromJSONArray(arr: JSONArray): ReadableArray? { + val result = Arguments.createArray() + for (i in 0 until arr.length()) { + val `val` = arr[i] + if (`val` is JSONObject) { + result.pushMap(fromJSONObject(`val`)) + } else if (`val` is JSONArray) { + result.pushArray(fromJSONArray(`val`)) + } else if (`val` is String) { + result.pushString(`val`) + } else if (`val` is Boolean) { + result.pushBoolean(`val`) + } else if (`val` is Int) { + result.pushInt(`val`) + } else if (`val` is Double) { + result.pushDouble(`val`) + } else if (`val` is Long) { + result.pushInt(`val`.toInt()) + } else if (arr.isNull(i)) { + result.pushNull() + } else { + // Unknown value type. Will throw + throw JSONException("Unexpected value when parsing JSON array. index: $i") + } + } + return result + } + + /** + * Parse String of JSON array to ReadableArray + * + * @param arrStr The String JSON array to be parsed + * @return readableArray from the JSONArray + */ + @Throws(JSONException::class) + fun fromJSONArrayString(arrStr: String?): ReadableArray? { + return fromJSONArray(JSONArray(arrStr)) + } +} diff --git a/src/specs/GiphyGridViewNativeComponent.ts b/src/specs/GiphyGridViewNativeComponent.ts index cff0d225..867db12c 100644 --- a/src/specs/GiphyGridViewNativeComponent.ts +++ b/src/specs/GiphyGridViewNativeComponent.ts @@ -2,17 +2,17 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati import type { HostComponent, ViewProps } from 'react-native' import type { DirectEventHandler, Double, Int32 } from 'react-native/Libraries/Types/CodegenTypes' -export interface GiphyGridViewContentUpdateEvent { +export type GiphyGridViewContentUpdateEvent = Readonly<{ resultCount: Int32 -} +}> -export interface GiphyGridViewRawMediaSelectEvent { +export type GiphyGridViewRawMediaSelectEvent = Readonly<{ media: string -} +}> -export interface GiphyGridViewMediaScrollEvent { +export type GiphyGridViewMediaScrollEvent = Readonly<{ offset: Double -} +}> export interface NativeProps extends ViewProps { cellPadding: Int32 diff --git a/src/specs/GiphyVideoViewNativeComponent.ts b/src/specs/GiphyVideoViewNativeComponent.ts index 2a9e8358..7a19025e 100644 --- a/src/specs/GiphyVideoViewNativeComponent.ts +++ b/src/specs/GiphyVideoViewNativeComponent.ts @@ -12,17 +12,17 @@ export const GiphyVideoViewPlaybackState = { export type GiphyVideoViewPlaybackState = (typeof GiphyVideoViewPlaybackState)[keyof typeof GiphyVideoViewPlaybackState] -export interface GiphyVideoViewMuteEvent {} +export type GiphyVideoViewMuteEvent = Readonly<{}> -export interface GiphyVideoViewUnmuteEvent {} +export type GiphyVideoViewUnmuteEvent = Readonly<{}> -export interface GiphyVideoViewPlaybackStateChangeEvent { +export type GiphyVideoViewPlaybackStateChangeEvent = Readonly<{ state: Int32 -} +}> -export interface GiphyVideoViewErrorEvent { +export type GiphyVideoViewErrorEvent = Readonly<{ description: string -} +}> export interface NativeProps extends ViewProps { autoPlay: boolean From 8fee20068a1e3ad6d0660b47ecf04c2e7135bd45 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Tue, 1 Aug 2023 15:01:59 +0300 Subject: [PATCH 2/6] chore: replace react-native-dotenv with react-native-config --- example/android/app/build.gradle | 3 ++- example/babel.config.js | 8 -------- example/package.json | 2 +- example/src/giphy.setup.android.ts | 6 +++--- example/src/giphy.setup.ios.ts | 6 +++--- example/src/react-native-config.d.ts | 9 +++++++++ example/src/types/env.d.ts | 4 ---- example/yarn.lock | 15 ++++----------- 8 files changed, 22 insertions(+), 31 deletions(-) create mode 100644 example/src/react-native-config.d.ts delete mode 100644 example/src/types/env.d.ts diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index e320ea37..d4453096 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: "com.android.application" +apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" apply plugin: "com.facebook.react" /** @@ -111,7 +112,7 @@ dependencies { debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group: 'com.squareup.okhttp3', module: 'okhttp' } - + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") if (hermesEnabled.toBoolean()) { diff --git a/example/babel.config.js b/example/babel.config.js index 06e42bf0..15826b0d 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -13,13 +13,5 @@ module.exports = { }, }, ], - [ - 'module:react-native-dotenv', - { - moduleName: 'react-native-dotenv', - safe: true, - whitelist: ['ANDROID_GIPHY_API_KEY', 'IOS_GIPHY_API_KEY'], - }, - ], ], } diff --git a/example/package.json b/example/package.json index 370731f9..49bf1a9b 100644 --- a/example/package.json +++ b/example/package.json @@ -16,7 +16,7 @@ "@react-native-picker/picker": "^2.4.10", "react": "18.2.0", "react-native": "0.72.2", - "react-native-dotenv": "^3.4.8", + "react-native-config": "^1.5.1", "react-native-picker-select": "^8.0.4", "react-native-status-bar-height": "^2.6.0" }, diff --git a/example/src/giphy.setup.android.ts b/example/src/giphy.setup.android.ts index 49fbb95d..3706a934 100644 --- a/example/src/giphy.setup.android.ts +++ b/example/src/giphy.setup.android.ts @@ -1,6 +1,6 @@ +import Config from 'react-native-config' import { GiphySDK } from '@giphy/react-native-sdk' -import { ANDROID_GIPHY_API_KEY } from 'react-native-dotenv' -if (ANDROID_GIPHY_API_KEY) { - GiphySDK.configure({ apiKey: ANDROID_GIPHY_API_KEY }) +if (Config.ANDROID_GIPHY_API_KEY) { + GiphySDK.configure({ apiKey: Config.ANDROID_GIPHY_API_KEY }) } diff --git a/example/src/giphy.setup.ios.ts b/example/src/giphy.setup.ios.ts index 6d27cbe6..b72a3d6f 100644 --- a/example/src/giphy.setup.ios.ts +++ b/example/src/giphy.setup.ios.ts @@ -1,6 +1,6 @@ +import Config from 'react-native-config' import { GiphySDK } from '@giphy/react-native-sdk' -import { IOS_GIPHY_API_KEY } from 'react-native-dotenv' -if (IOS_GIPHY_API_KEY) { - GiphySDK.configure({ apiKey: IOS_GIPHY_API_KEY }) +if (Config.IOS_GIPHY_API_KEY) { + GiphySDK.configure({ apiKey: Config.IOS_GIPHY_API_KEY }) } diff --git a/example/src/react-native-config.d.ts b/example/src/react-native-config.d.ts new file mode 100644 index 00000000..0cf85bcb --- /dev/null +++ b/example/src/react-native-config.d.ts @@ -0,0 +1,9 @@ +declare module 'react-native-config' { + export interface NativeConfig { + ANDROID_GIPHY_API_KEY?: string + IOS_GIPHY_API_KEY?: string + } + + export const Config: NativeConfig + export default Config +} diff --git a/example/src/types/env.d.ts b/example/src/types/env.d.ts deleted file mode 100644 index 93621a44..00000000 --- a/example/src/types/env.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'react-native-dotenv' { - export const IOS_GIPHY_API_KEY: string | undefined - export const ANDROID_GIPHY_API_KEY: string | undefined -} diff --git a/example/yarn.lock b/example/yarn.lock index 07a6275f..c7464c4c 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2160,11 +2160,6 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -dotenv@^16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4065,12 +4060,10 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-native-dotenv@^3.4.8: - version "3.4.9" - resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.9.tgz#621c5b0c1d0c5c7f569bfe5a1d804bec7885c010" - integrity sha512-dbyd+mcy7SUzxEgmt33TRf1FGcNe6swJhXmB0unKkI49F7+pidog9kPtjxMLTAfmKA8gcN2XHQSKltGfGbGCLQ== - dependencies: - dotenv "^16.3.1" +react-native-config@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/react-native-config/-/react-native-config-1.5.1.tgz#73c94f511493e9b7ff9350cdf351d203a1b05acc" + integrity sha512-g1xNgt1tV95FCX+iWz6YJonxXkQX0GdD3fB8xQtR1GUBEqweB9zMROW77gi2TygmYmUkBI7LU4pES+zcTyK4HA== react-native-picker-select@^8.0.4: version "8.0.4" From ad6c79a8efaa927e1c90a1a7de990d0dd1c99a36 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Wed, 2 Aug 2023 15:29:04 +0300 Subject: [PATCH 3/6] fix: example app fails on sticker's preview screen --- example/android/app/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index d4453096..aa566f9a 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -108,6 +108,9 @@ dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") + // Fixes https://github.com/facebook/fresco/issues/2714 + api("com.facebook.fresco:nativeimagetranscoder:2.6.0!!") + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group: 'com.squareup.okhttp3', module: 'okhttp' From 08563c18d1dd0ee131ea650437255076bd6a1d02 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Wed, 2 Aug 2023 16:53:20 +0300 Subject: [PATCH 4/6] docs: update CONTRIBUTING --- CODE_OF_CONDUCT.md | 136 ++++++++++++++++++++ CONTRIBUTING.md | 207 ++++++++++++------------------ example/android/gradle.properties | 2 +- 3 files changed, 220 insertions(+), 125 deletions(-) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d16a881d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,136 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org + +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html + +[Mozilla CoC]: https://github.com/mozilla/diversity + +[FAQ]: https://www.contributor-covenant.org/faq + +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4844c29e..57af07df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,64 +1,88 @@ # Contributing -We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. +We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the +project. ## Development workflow +### Install dependencies + To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: ```sh yarn ``` -> While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. +> While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built +> around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. -While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app. +To edit the Objective-C files, open `example/ios/GiphyReactNativeSdkExample.xcworkspace` in XCode and find the source +files at `Pods > Development Pods > giphy-react-native-sdk`. -To start the packager: +To edit the Kotlin files, open `example/android` in Android studio and find the source files at `giphyreactnativesdk` +under `Android`. -```sh -yarn example start -``` +While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's +JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need +to rebuild the example app. -To run the example app on Android: +### Run the example app -```sh -yarn example android -``` +- To run the example application, you need to configure the API keys. To do this, + you can copy the `.example.env` file and fill in the necessary variables: + ```shell + cp example/.example.env example/.env + ``` -To run the example app on iOS: +- Start the packager: + ```sh + yarn example start + ``` -```sh -yarn example ios -``` +- Run the example app on Android: + ```sh + yarn example android + ``` -Make sure your code passes TypeScript and ESLint. Run the following to verify: +- Run the example app on iOS: + ```sh + yarn example ios + ``` -```sh -yarn typescript -yarn lint -``` +By default, the example is configured to build with the old architecture. To run the example with the new architecture, +you can do the following: -To fix formatting errors, run the following: +1. For Android, run: + ```sh + ORG_GRADLE_PROJECT_newArchEnabled=true yarn example android + ``` + + Or if you are using Android Studio, set the `newArchEnabled` property to true in + the `example/android/gradle.properties` file and run the following command from + the `example/android` folder: + ```sh + ./gradlew generateCodegenArtifactsFromSchema + ``` + +2. For iOS, run: + ```sh + RCT_NEW_ARCH_ENABLED=1 yarn example pods + ``` + +If you are building for a different architecture than your previous build, make sure to remove the build folders first. +You can run the following command to cleanup all build folders: ```sh -yarn lint --fix +yarn clean ``` -Remember to add tests for your changes if possible, and don't forget to run the e2e tests before releasing the changes by: +To confirm that the app is running with the new architecture, you can check the Metro logs for a message like this: ```sh -# Android -yarn detox:build:android -yarn detox:test:android -# iOS -yarn detox:build:ios -yarn detox:test:ios +Running "GiphyReactNativeSdkExample" with {"fabric":true,"initialProps":{"concurrentRoot":true},"rootTag":1} ``` -To edit the Objective-C files, open `example/ios/GiphyReactNativeSdkExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > giphy-react-native-sdk`. - -To edit the Kotlin files, open `example/android` in Android studio and find the source files at `giphyreactnativesdk` under `Android`. +Note the `"fabric":true` and `"concurrentRoot":true` properties. ### Commit message convention @@ -77,9 +101,22 @@ Our pre-commit hooks verify that your commit message matches this format when co [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/), [Detox](https://github.com/wix/Detox) -We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Detox](https://github.com/wix/Detox) with [Jest](https://jestjs.io/) for e2e testing. +We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) +with [Prettier](https://prettier.io/) for linting and formatting the code, and [Detox](https://github.com/wix/Detox) +with [Jest](https://jestjs.io/) for e2e testing. + +Make sure your code passes TypeScript and ESLint. Run the following to verify: + +```sh +yarn typescript +yarn lint +``` -Our pre-commit hooks verify that the linter and type checks pass when committing. +To fix formatting errors, run the following: + +```sh +yarn lint --fix +``` Also before doing release you should run e2e tests locally by: @@ -102,7 +139,8 @@ Prerequisites: - ✅ Java’s runtime - ✅ The Android SDK -If all of the above are ready, you need to load the necessary packages and configure the AVD device for the e2e test. Fortunately, you can do this simply by running the following command: +If all of the above are ready, you need to load the necessary packages and configure the AVD device for the e2e test. +Fortunately, you can do this simply by running the following command: `yarn detox:bootstrap:android` @@ -112,15 +150,18 @@ Prerequisites: - ✅ Detox Command Line Tools. This can be done by running this command: `npm install -g detox-cli` - ✅ MacOS Catalina or newer -- ✅ Xcode v12.x or newer (v13 support - see [here](https://github.com/wix/Detox/issues/2895)), with Xcode command-line tools installed +- ✅ Xcode v12.x or newer (v13 support - see [here](https://github.com/wix/Detox/issues/2895)), with Xcode command-line + tools installed -If all of the above is ready, you need to configure the iOS Simulator to run the e2e test. This can be done by running the following command: +If all of the above is ready, you need to configure the iOS Simulator to run the e2e test. This can be done by running +the following command: `yarn detox:bootstrap:ios` ### Publishing to npm -We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc. +We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles +common tasks like bumping version based on semver, creating tags and releases etc. To publish new versions, run the following: @@ -133,6 +174,7 @@ yarn release The `package.json` file contains various scripts for common tasks: - `yarn bootstrap`: setup project by installing all dependencies and pods. +- `yarn clean`: cleanup all build folders. - `yarn detox:bootstrap:android`: prepare the environment for e2e-tests on the Android platform. - `yarn detox:bootstrap:ios`: prepare the environment for e2e-tests on the iOS platform. - `yarn detox:build:android`: create a build of the example app ready for e2e-testing on the Android platform. @@ -152,7 +194,9 @@ The `package.json` file contains various scripts for common tasks: ### Sending a pull request -> **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). +> **Working on your first pull request?** You can learn how from this _free_ +> +series: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). When you're sending a pull request: @@ -161,88 +205,3 @@ When you're sending a pull request: - Review the documentation to make sure it looks good. - Follow the pull request template when opening a pull request. - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. - -## Code of Conduct - -### Our Pledge - -We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. - -### Our Standards - -Examples of behavior that contributes to a positive environment for our community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or - advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email - address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -### Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. - -### Scope - -This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. - -### Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the reporter of any incident. - -### Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: - -#### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. - -#### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. - -#### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. - -#### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the community. - -### Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, -available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 2b74a6fe..c7645fab 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -29,7 +29,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 # your application. You should enable this flag either if you want # to write custom TurboModules/Fabric components OR use libraries that # are providing them. -newArchEnabled=true +newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true From 9341d83f6e8b2c1b9fd8aab6111e331a1dfd6bd7 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Wed, 2 Aug 2023 17:05:14 +0300 Subject: [PATCH 5/6] chore(example): remove react-native-status-bar-height --- example/ios/Podfile.lock | 8 +++++ .../Settings.bundle/Acknowledgements.plist | 31 +++++++++++++++++++ example/package.json | 3 +- example/src/App.tsx | 8 ++--- example/src/Dialog.tsx | 8 ++--- example/yarn.lock | 5 --- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 7c6db114..cb5490ab 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -960,6 +960,10 @@ PODS: - React-jsinspector (0.72.2) - React-logger (0.72.2): - glog + - react-native-config (1.5.1): + - react-native-config/App (= 1.5.1) + - react-native-config/App (1.5.1): + - React-Core - React-NativeModulesApple (0.72.2): - hermes-engine - React-callinvoker @@ -1143,6 +1147,7 @@ DEPENDENCIES: - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) + - react-native-config (from `../node_modules/react-native-config`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -1233,6 +1238,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/jsinspector" React-logger: :path: "../node_modules/react-native/ReactCommon/logger" + react-native-config: + :path: "../node_modules/react-native-config" React-NativeModulesApple: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" React-perflogger: @@ -1313,6 +1320,7 @@ SPEC CHECKSUMS: React-jsiexecutor: 2c53849838b096599bd04cbbf11a6b67a1781e7b React-jsinspector: 36bb3067723df92b7ea564a28ee61a2282a696bc React-logger: 48a3629a61899735cbfa9f0b8c5cd44cb1561952 + react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8 React-NativeModulesApple: 5dfdf09b36ffad0c08f401e86569b8f170a0035d React-perflogger: e7006abd30efeebef143702550063ca3415e267a React-RCTActionSheet: 017232a203ef82e42e54b15673e26489c2797745 diff --git a/example/ios/Resources/Settings.bundle/Acknowledgements.plist b/example/ios/Resources/Settings.bundle/Acknowledgements.plist index 0a002827..42065ea2 100644 --- a/example/ios/Resources/Settings.bundle/Acknowledgements.plist +++ b/example/ios/Resources/Settings.bundle/Acknowledgements.plist @@ -1591,6 +1591,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Type PSGroupSpecifier + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Lugg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + react-native-config + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/example/package.json b/example/package.json index 49bf1a9b..903235f5 100644 --- a/example/package.json +++ b/example/package.json @@ -17,8 +17,7 @@ "react": "18.2.0", "react-native": "0.72.2", "react-native-config": "^1.5.1", - "react-native-picker-select": "^8.0.4", - "react-native-status-bar-height": "^2.6.0" + "react-native-picker-select": "^8.0.4" }, "devDependencies": { "@babel/core": "^7.22.5", diff --git a/example/src/App.tsx b/example/src/App.tsx index 7b1ea84c..8808e6ca 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useRef, useState } from 'react' -import { getStatusBarHeight } from 'react-native-status-bar-height' -import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native' +import { SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native' import { GiphyDialog, type GiphyDialogConfig, type GiphyMedia, GiphyVideoManager } from '@giphy/react-native-sdk' import './giphy.setup' @@ -13,7 +12,6 @@ import { MediaViewSample } from './MediaViewSample' const styles = StyleSheet.create({ container: { flex: 1, - paddingTop: getStatusBarHeight() ?? 0, backgroundColor: '#eee', }, header: { @@ -86,7 +84,7 @@ export default function App() { }, [addMediaRef]) return ( - + {/* Displaying Giphy Dialog & settings for it */} - + ) } diff --git a/example/src/Dialog.tsx b/example/src/Dialog.tsx index 1f0632f7..9aa2ab33 100644 --- a/example/src/Dialog.tsx +++ b/example/src/Dialog.tsx @@ -1,13 +1,11 @@ import React from 'react' -import { getStatusBarHeight } from 'react-native-status-bar-height' -import { Modal, ModalProps, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native' +import { Modal, ModalProps, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity } from 'react-native' const styles = StyleSheet.create({ container: { backgroundColor: '#eee', flex: 1, flexDirection: 'column', - paddingTop: getStatusBarHeight() ?? 0, }, content: { flex: 1, @@ -33,7 +31,7 @@ export const Dialog: React.FC = (props) => { return ( - + {children} @@ -42,7 +40,7 @@ export const Dialog: React.FC = (props) => { Close - + ) } diff --git a/example/yarn.lock b/example/yarn.lock index c7464c4c..0ec91042 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -4073,11 +4073,6 @@ react-native-picker-select@^8.0.4: "@react-native-picker/picker" "^1.8.3" lodash.isequal "^4.5.0" -react-native-status-bar-height@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/react-native-status-bar-height/-/react-native-status-bar-height-2.6.0.tgz#b6afd25b6e3d533c43d0fcdcfd5cafd775592cea" - integrity sha512-z3SGLF0mHT+OlJDq7B7h/jXPjWcdBT3V14Le5L2PjntjjWM3+EJzq2BcXDwV+v67KFNJic5pgA26cCmseYek6w== - react-native@0.72.2: version "0.72.2" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.2.tgz#e2acf4be0238b0e5d2e2501ca53994488f13712a" From 9cbad3679bac4e02b1907080f08db88eea797a00 Mon Sep 17 00:00:00 2001 From: Valentyn Pshoniuk Date: Wed, 2 Aug 2023 17:06:46 +0300 Subject: [PATCH 6/6] docs: fix typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57af07df..2e1d5d9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ to rebuild the example app. ### Run the example app -- To run the example application, you need to configure the API keys. To do this, +- To run the example application, you need to configure the GIPHY API keys. To do this, you can copy the `.example.env` file and fill in the necessary variables: ```shell cp example/.example.env example/.env