@viafoura/sdk-react-native 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,68 @@
1
+ package expo.modules.viafourasdk
2
+
3
+ import android.graphics.Color
4
+ import com.viafourasdk.src.Constants
5
+ import com.viafourasdk.src.model.local.VFColors
6
+ import com.viafourasdk.src.model.local.VFDefaultColors
7
+ import com.viafourasdk.src.model.local.VFTheme
8
+
9
+ private const val KEY_COLOR_PRIMARY = "colorPrimary"
10
+ private const val KEY_COLOR_PRIMARY_LIGHT = "colorPrimaryLight"
11
+ private const val KEY_COLOR_AVATARS = "colorAvatars"
12
+ private const val KEY_PRIMARY = "primary"
13
+ private const val KEY_PRIMARY_LIGHT = "primaryLight"
14
+ private const val KEY_AVATARS = "avatars"
15
+
16
+ internal fun resolveVFColors(colors: Map<String, Any?>?, theme: VFTheme?): VFColors {
17
+ val defaults = VFDefaultColors.getInstance()
18
+ val defaultPrimary = defaults.colorPrimaryDefault(null)
19
+ val defaultPrimaryLight = defaults.colorPrimaryLightDefault(null)
20
+
21
+ val primary =
22
+ parseColorOrNull(colors?.get(KEY_COLOR_PRIMARY) ?: colors?.get(KEY_PRIMARY))
23
+ ?: defaultPrimary
24
+ val primaryLight =
25
+ parseColorOrNull(colors?.get(KEY_COLOR_PRIMARY_LIGHT) ?: colors?.get(KEY_PRIMARY_LIGHT))
26
+ ?: defaultPrimaryLight
27
+
28
+ val vfColors = VFColors(primary, primaryLight)
29
+ parseAvatarColors(colors?.get(KEY_COLOR_AVATARS) ?: colors?.get(KEY_AVATARS))
30
+ ?.let { vfColors.setColorAvatars(it) }
31
+ theme?.let { vfColors.setTheme(it) }
32
+
33
+ return vfColors
34
+ }
35
+
36
+ private fun parseColorOrNull(value: Any?): Int? {
37
+ return when (value) {
38
+ is Int -> value
39
+ is Long -> value.toInt()
40
+ is Number -> value.toInt()
41
+ is String -> {
42
+ if (value.isBlank()) return null
43
+ try {
44
+ Color.parseColor(value)
45
+ } catch (_: IllegalArgumentException) {
46
+ null
47
+ }
48
+ }
49
+ else -> null
50
+ }
51
+ }
52
+
53
+ private fun parseAvatarColors(value: Any?): IntArray? {
54
+ val list = when (value) {
55
+ is List<*> -> value
56
+ is Array<*> -> value.asList()
57
+ else -> return null
58
+ }
59
+
60
+ if (list.size != Constants.AVATAR_COLORS.size) return null
61
+
62
+ val parsed = IntArray(list.size)
63
+ for (index in list.indices) {
64
+ val color = parseColorOrNull(list[index]) ?: return null
65
+ parsed[index] = color
66
+ }
67
+ return parsed
68
+ }
@@ -18,10 +18,11 @@ class NewCommentModule : Module() {
18
18
  Prop("articleUrl") { view: NewCommentView, v: String -> view.articleUrl = v }
19
19
  Prop("articleThumbnailUrl") { view: NewCommentView, v: String -> view.articleThumbnailUrl = v }
20
20
  Prop("darkMode") { view: NewCommentView, v: Boolean? -> view.darkMode = v ?: false }
21
+ Prop("theme") { view: NewCommentView, v: String? -> view.theme = v }
22
+ Prop("colors") { view: NewCommentView, v: Map<String, Any?>? -> view.colors = v }
21
23
 
22
24
  // Events
23
- Events("onAuthNeeded", "onCloseNewComment", "onHeightChanged")
25
+ Events("onAuthNeeded", "onCloseNewComment", "onHeightChanged", "onAction")
24
26
  }
25
27
  }
26
28
  }
27
-
@@ -20,8 +20,6 @@ import com.viafourasdk.src.interfaces.VFLayoutInterface
20
20
  import com.viafourasdk.src.model.local.VFActionData
21
21
  import com.viafourasdk.src.model.local.VFActionType
22
22
  import com.viafourasdk.src.model.local.VFArticleMetadata
23
- import com.viafourasdk.src.model.local.VFColors
24
- import com.viafourasdk.src.model.local.VFDefaultColors
25
23
  import com.viafourasdk.src.model.local.VFSettings
26
24
  import com.viafourasdk.src.model.local.VFTheme
27
25
  import java.net.URL
@@ -40,11 +38,22 @@ class NewCommentView(context: Context, appContext: AppContext) :
40
38
  var articleUrl: String? = null
41
39
  var articleThumbnailUrl: String? = null
42
40
  var darkMode: Boolean = false
41
+ set(value) {
42
+ field = value
43
+ applyThemeIfReady()
44
+ }
45
+ var theme: String? = null
46
+ set(value) {
47
+ field = value
48
+ applyThemeIfReady()
49
+ }
50
+ var colors: Map<String, Any?>? = null
43
51
 
44
52
  // Events
45
53
  private val onAuthNeeded by EventDispatcher()
46
54
  private val onCloseNewComment by EventDispatcher()
47
55
  private val onHeightChanged by EventDispatcher()
56
+ private val onAction by EventDispatcher()
48
57
 
49
58
  // Internals
50
59
  private val container = FrameLayout(context).also {
@@ -72,17 +81,16 @@ class NewCommentView(context: Context, appContext: AppContext) :
72
81
  val activity = currentActivity() ?: return
73
82
 
74
83
  try {
84
+ val resolvedTheme = resolveTheme()
75
85
  val metadata = VFArticleMetadata(
76
86
  URL(requireNotNull(articleUrl)),
77
87
  requireNotNull(articleTitle),
78
88
  articleSubtitle ?: "",
79
89
  URL(requireNotNull(articleThumbnailUrl))
80
90
  )
81
- val colors = VFColors(
82
- VFDefaultColors.getInstance().colorPrimaryDefault(null),
83
- VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
91
+ val settings = VFSettings(
92
+ resolveVFColors(colors, resolvedTheme)
84
93
  )
85
- val settings = VFSettings(colors)
86
94
 
87
95
  val type = when (newCommentActionType) {
88
96
  "edit" -> VFNewCommentAction.VFNewCommentActionType.edit
@@ -99,7 +107,7 @@ class NewCommentView(context: Context, appContext: AppContext) :
99
107
  val frag = builder.build()
100
108
  frag.setActionCallback(this)
101
109
  frag.setCustomUICallback(this)
102
- frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
110
+ frag.setTheme(resolvedTheme)
103
111
 
104
112
  activity.supportFragmentManager
105
113
  .beginTransaction()
@@ -127,15 +135,18 @@ class NewCommentView(context: Context, appContext: AppContext) :
127
135
 
128
136
  // VFActionsInterface
129
137
  override fun onNewAction(actionType: VFActionType, action: VFActionData) {
138
+ val actionPayload = mutableMapOf<String, Any>("type" to actionType.toString())
130
139
  when (actionType) {
131
140
  VFActionType.closeNewCommentPressed -> {
132
141
  onCloseNewComment(emptyMap<String, Any>())
133
142
  }
134
143
  VFActionType.authPressed -> {
144
+ actionPayload["requireLogin"] = true
135
145
  onAuthNeeded(mapOf("requireLogin" to true))
136
146
  }
137
147
  else -> {}
138
148
  }
149
+ onAction(actionPayload)
139
150
  }
140
151
 
141
152
  // VFCustomUIInterface
@@ -149,4 +160,16 @@ class NewCommentView(context: Context, appContext: AppContext) :
149
160
  override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {
150
161
  onHeightChanged(mapOf("newHeight" to height, "containerId" to containerId))
151
162
  }
163
+
164
+ private fun resolveTheme(): VFTheme {
165
+ return when (theme?.lowercase()) {
166
+ "dark" -> VFTheme.dark
167
+ "light" -> VFTheme.light
168
+ else -> if (darkMode) VFTheme.dark else VFTheme.light
169
+ }
170
+ }
171
+
172
+ private fun applyThemeIfReady() {
173
+ fragment?.setTheme(resolveTheme())
174
+ }
152
175
  }
@@ -17,10 +17,11 @@ class PreviewCommentsModule : Module() {
17
17
  Prop("articleThumbnailUrl") { view: PreviewCommentsView, v: String -> view.articleThumbnailUrl = v }
18
18
  Prop("syndicationKey") { view: PreviewCommentsView, v: String? -> view.syndicationKey = v }
19
19
  Prop("darkMode") { view: PreviewCommentsView, v: Boolean? -> view.darkMode = v ?: false }
20
+ Prop("theme") { view: PreviewCommentsView, v: String? -> view.theme = v }
21
+ Prop("colors") { view: PreviewCommentsView, v: Map<String, Any?>? -> view.colors = v }
20
22
 
21
23
  // Events
22
- Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed")
24
+ Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed", "onAction")
23
25
  }
24
26
  }
25
27
  }
26
-
@@ -20,8 +20,6 @@ import com.viafourasdk.src.interfaces.VFLayoutInterface
20
20
  import com.viafourasdk.src.model.local.VFActionData
21
21
  import com.viafourasdk.src.model.local.VFActionType
22
22
  import com.viafourasdk.src.model.local.VFArticleMetadata
23
- import com.viafourasdk.src.model.local.VFColors
24
- import com.viafourasdk.src.model.local.VFDefaultColors
25
23
  import com.viafourasdk.src.model.local.VFSettings
26
24
  import com.viafourasdk.src.model.local.VFTheme
27
25
  import java.net.URL
@@ -38,6 +36,16 @@ class PreviewCommentsView(context: Context, appContext: AppContext) :
38
36
  var articleThumbnailUrl: String? = null
39
37
  var syndicationKey: String? = null
40
38
  var darkMode: Boolean = false
39
+ set(value) {
40
+ field = value
41
+ applyThemeIfReady()
42
+ }
43
+ var theme: String? = null
44
+ set(value) {
45
+ field = value
46
+ applyThemeIfReady()
47
+ }
48
+ var colors: Map<String, Any?>? = null
41
49
 
42
50
  // Events
43
51
  private val onHeightChanged by EventDispatcher()
@@ -45,6 +53,7 @@ class PreviewCommentsView(context: Context, appContext: AppContext) :
45
53
  private val onOpenProfile by EventDispatcher()
46
54
  private val onNewComment by EventDispatcher()
47
55
  private val onArticlePressed by EventDispatcher()
56
+ private val onAction by EventDispatcher()
48
57
 
49
58
  // Internals
50
59
  private val container = FrameLayout(context).also {
@@ -73,17 +82,16 @@ class PreviewCommentsView(context: Context, appContext: AppContext) :
73
82
  val activity = currentActivity() ?: return
74
83
 
75
84
  try {
85
+ val resolvedTheme = resolveTheme()
76
86
  val meta = VFArticleMetadata(
77
87
  URL(requireNotNull(articleUrl)),
78
88
  requireNotNull(articleTitle),
79
89
  articleSubtitle ?: "",
80
90
  URL(requireNotNull(articleThumbnailUrl))
81
91
  )
82
- val colors = VFColors(
83
- VFDefaultColors.getInstance().colorPrimaryDefault(null),
84
- VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
92
+ val settings = VFSettings(
93
+ resolveVFColors(colors, resolvedTheme)
85
94
  )
86
- val settings = VFSettings(colors)
87
95
 
88
96
  val builder = VFPreviewCommentsFragmentBuilder(requireNotNull(containerId), meta, settings)
89
97
  syndicationKey?.let { builder.syndicationKey(it) }
@@ -91,7 +99,7 @@ class PreviewCommentsView(context: Context, appContext: AppContext) :
91
99
  frag.setActionCallback(this)
92
100
  frag.setLayoutCallback(this)
93
101
  frag.setCustomUICallback(this)
94
- frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
102
+ frag.setTheme(resolvedTheme)
95
103
  authorId?.let { if (it.isNotEmpty()) frag.setAuthorIds(listOf(it)) }
96
104
 
97
105
  activity.supportFragmentManager
@@ -127,33 +135,54 @@ class PreviewCommentsView(context: Context, appContext: AppContext) :
127
135
 
128
136
  // VFActionsInterface
129
137
  override fun onNewAction(actionType: VFActionType, action: VFActionData) {
138
+ val actionPayload = mutableMapOf<String, Any>("type" to actionType.toString())
130
139
  when (actionType) {
131
140
  VFActionType.writeNewCommentPressed -> {
132
141
  val payload = mutableMapOf<String, Any>()
133
142
  action.newCommentAction?.content?.toString()?.let { payload["content"] = it }
134
143
  action.newCommentAction?.type?.toString()?.let { payload["actionType"] = it }
144
+ actionPayload.putAll(payload)
135
145
  onNewComment(payload)
136
146
  }
137
147
  VFActionType.openProfilePressed -> {
138
148
  val payload = mutableMapOf<String, Any>()
139
149
  action.openProfileAction?.presentationType?.toString()?.let { payload["presentationType"] = it }
140
150
  action.openProfileAction?.userUUID?.toString()?.let { payload["userUUID"] = it }
151
+ actionPayload.putAll(payload)
141
152
  onOpenProfile(payload)
142
153
  }
143
154
  VFActionType.trendingArticlePressed -> {
144
- val url = action.trendingPressedAction?.articleMetadata?.url?.toString() ?: return
155
+ val url = action.trendingPressedAction?.articleMetadata?.url?.toString()
145
156
  val containerId = action.trendingPressedAction?.containerId ?: ""
146
- onArticlePressed(mapOf("articleUrl" to url, "containerId" to containerId))
157
+ url?.let { actionPayload["articleUrl"] = it }
158
+ actionPayload["containerId"] = containerId
159
+ if (url != null) {
160
+ onArticlePressed(mapOf("articleUrl" to url, "containerId" to containerId))
161
+ }
147
162
  }
148
163
  VFActionType.authPressed -> {
164
+ actionPayload["requireLogin"] = true
149
165
  onAuthNeeded(mapOf("requireLogin" to true))
150
166
  }
151
167
  else -> {}
152
168
  }
169
+ onAction(actionPayload)
153
170
  }
154
171
 
155
172
  // VFLayoutInterface
156
173
  override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {
157
174
  onHeightChanged(mapOf("newHeight" to height, "containerId" to containerId))
158
175
  }
176
+
177
+ private fun resolveTheme(): VFTheme {
178
+ return when (theme?.lowercase()) {
179
+ "dark" -> VFTheme.dark
180
+ "light" -> VFTheme.light
181
+ else -> if (darkMode) VFTheme.dark else VFTheme.light
182
+ }
183
+ }
184
+
185
+ private fun applyThemeIfReady() {
186
+ fragment?.setTheme(resolveTheme())
187
+ }
159
188
  }
@@ -12,10 +12,11 @@ class ProfileModule : Module() {
12
12
  Prop("userUUID") { view: ProfileView, v: String -> view.userUUID = v }
13
13
  Prop("presentationType") { view: ProfileView, v: String? -> view.presentationType = v }
14
14
  Prop("darkMode") { view: ProfileView, v: Boolean? -> view.darkMode = v ?: false }
15
+ Prop("theme") { view: ProfileView, v: String? -> view.theme = v }
16
+ Prop("colors") { view: ProfileView, v: Map<String, Any?>? -> view.colors = v }
15
17
 
16
18
  // Events
17
- Events("onAuthNeeded", "onCloseProfile")
19
+ Events("onAuthNeeded", "onCloseProfile", "onAction")
18
20
  }
19
21
  }
20
22
  }
21
-
@@ -17,8 +17,6 @@ import com.viafourasdk.src.interfaces.VFCustomUIInterface
17
17
  import com.viafourasdk.src.interfaces.VFLayoutInterface
18
18
  import com.viafourasdk.src.model.local.VFActionData
19
19
  import com.viafourasdk.src.model.local.VFActionType
20
- import com.viafourasdk.src.model.local.VFDefaultColors
21
- import com.viafourasdk.src.model.local.VFColors
22
20
  import com.viafourasdk.src.model.local.VFSettings
23
21
  import com.viafourasdk.src.model.local.VFProfilePresentationType
24
22
  import com.viafourasdk.src.model.local.VFTheme
@@ -31,10 +29,21 @@ class ProfileView(context: Context, appContext: AppContext) :
31
29
  var userUUID: String? = null
32
30
  var presentationType: String? = null // "profile" | "feed"
33
31
  var darkMode: Boolean = false
32
+ set(value) {
33
+ field = value
34
+ applyThemeIfReady()
35
+ }
36
+ var theme: String? = null
37
+ set(value) {
38
+ field = value
39
+ applyThemeIfReady()
40
+ }
41
+ var colors: Map<String, Any?>? = null
34
42
 
35
43
  // Events
36
44
  private val onAuthNeeded by EventDispatcher()
37
45
  private val onCloseProfile by EventDispatcher()
46
+ private val onAction by EventDispatcher()
38
47
 
39
48
  // Internals
40
49
  private val container = FrameLayout(context).also {
@@ -62,11 +71,10 @@ class ProfileView(context: Context, appContext: AppContext) :
62
71
  val activity = currentActivity() ?: return
63
72
 
64
73
  try {
65
- val colors = VFColors(
66
- VFDefaultColors.getInstance().colorPrimaryDefault(null),
67
- VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
74
+ val resolvedTheme = resolveTheme()
75
+ val settings = VFSettings(
76
+ resolveVFColors(colors, resolvedTheme)
68
77
  )
69
- val settings = VFSettings(colors)
70
78
 
71
79
  val pres = when (presentationType) {
72
80
  "feed" -> VFProfilePresentationType.feed
@@ -77,7 +85,7 @@ class ProfileView(context: Context, appContext: AppContext) :
77
85
  val frag = VFProfileFragmentBuilder(uuid, pres, settings).build()
78
86
  frag.setActionCallback(this)
79
87
  frag.setCustomUICallback(this)
80
- frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
88
+ frag.setTheme(resolvedTheme)
81
89
 
82
90
  activity.supportFragmentManager
83
91
  .beginTransaction()
@@ -105,15 +113,18 @@ class ProfileView(context: Context, appContext: AppContext) :
105
113
 
106
114
  // VFActionsInterface
107
115
  override fun onNewAction(actionType: VFActionType, action: VFActionData) {
116
+ val actionPayload = mutableMapOf<String, Any>("type" to actionType.toString())
108
117
  when (actionType) {
109
118
  VFActionType.closeProfilePressed -> {
110
119
  onCloseProfile(emptyMap<String, Any>())
111
120
  }
112
121
  VFActionType.authPressed -> {
122
+ actionPayload["requireLogin"] = true
113
123
  onAuthNeeded(mapOf("requireLogin" to true))
114
124
  }
115
125
  else -> {}
116
126
  }
127
+ onAction(actionPayload)
117
128
  }
118
129
 
119
130
  // VFCustomUIInterface
@@ -129,4 +140,16 @@ class ProfileView(context: Context, appContext: AppContext) :
129
140
  containerId: String,
130
141
  height: Int
131
142
  ) { /* no-op for profile */ }
143
+
144
+ private fun resolveTheme(): VFTheme {
145
+ return when (theme?.lowercase()) {
146
+ "dark" -> VFTheme.dark
147
+ "light" -> VFTheme.light
148
+ else -> if (darkMode) VFTheme.dark else VFTheme.light
149
+ }
150
+ }
151
+
152
+ private fun applyThemeIfReady() {
153
+ fragment?.setTheme(resolveTheme())
154
+ }
132
155
  }
@@ -5,7 +5,49 @@ export type ViafouraModuleEvents = {
5
5
  export type ChangeEventPayload = {
6
6
  value: string;
7
7
  };
8
- export type PreviewCommentsEvents = 'onHeightChanged' | 'onAuthNeeded' | 'onOpenProfile' | 'onNewComment' | 'onArticlePressed';
8
+ export type PreviewCommentsEvents = 'onHeightChanged' | 'onAuthNeeded' | 'onOpenProfile' | 'onNewComment' | 'onArticlePressed' | 'onAction';
9
+ export type ViafouraColors = {
10
+ colorPrimary?: string;
11
+ colorPrimaryLight?: string;
12
+ colorAvatars?: string[];
13
+ };
14
+ export type ActionCallbackType = 'writeNewCommentPressed' | 'trendingArticlePressed' | 'openProfilePressed' | 'seeMoreCommentsPressed' | 'notificationPressed' | 'commentPosted' | 'replyPosted' | 'authPressed' | 'closeNewCommentPressed' | 'closeProfilePressed';
15
+ export type ActionCallbackPayload = {
16
+ type: 'writeNewCommentPressed';
17
+ actionType?: 'create' | 'edit' | 'reply';
18
+ content?: string;
19
+ } | {
20
+ type: 'trendingArticlePressed';
21
+ containerId?: string;
22
+ articleUrl?: string;
23
+ } | {
24
+ type: 'openProfilePressed';
25
+ userUUID?: string;
26
+ presentationType?: 'profile' | 'feed';
27
+ } | {
28
+ type: 'seeMoreCommentsPressed';
29
+ } | {
30
+ type: 'notificationPressed';
31
+ presentationType?: 'profile' | 'content';
32
+ userUUID?: string;
33
+ containerUUID?: string;
34
+ contentUUID?: string;
35
+ containerId?: string;
36
+ articleUrl?: string;
37
+ } | {
38
+ type: 'commentPosted';
39
+ content?: string;
40
+ } | {
41
+ type: 'replyPosted';
42
+ content?: string;
43
+ } | {
44
+ type: 'authPressed';
45
+ requireLogin?: boolean;
46
+ } | {
47
+ type: 'closeNewCommentPressed';
48
+ } | {
49
+ type: 'closeProfilePressed';
50
+ };
9
51
  export type PreviewCommentsHeightChangedPayload = {
10
52
  newHeight: number;
11
53
  containerId: string;
@@ -34,6 +76,8 @@ export type PreviewCommentsViewProps = {
34
76
  articleThumbnailUrl: string;
35
77
  syndicationKey?: string;
36
78
  darkMode?: boolean;
79
+ theme?: 'light' | 'dark';
80
+ colors?: ViafouraColors;
37
81
  onHeightChanged?: (event: {
38
82
  nativeEvent: PreviewCommentsHeightChangedPayload;
39
83
  }) => void;
@@ -49,6 +93,9 @@ export type PreviewCommentsViewProps = {
49
93
  onArticlePressed?: (event: {
50
94
  nativeEvent: PreviewCommentsArticlePressedPayload;
51
95
  }) => void;
96
+ onAction?: (event: {
97
+ nativeEvent: ActionCallbackPayload;
98
+ }) => void;
52
99
  style?: StyleProp<ViewStyle>;
53
100
  };
54
101
  export type ProfileAuthNeededPayload = {
@@ -58,12 +105,17 @@ export type ProfileViewProps = {
58
105
  userUUID: string;
59
106
  presentationType?: 'profile' | 'feed';
60
107
  darkMode?: boolean;
108
+ theme?: 'light' | 'dark';
109
+ colors?: ViafouraColors;
61
110
  onAuthNeeded?: (event: {
62
111
  nativeEvent: ProfileAuthNeededPayload;
63
112
  }) => void;
64
113
  onCloseProfile?: (event: {
65
114
  nativeEvent: Record<string, never>;
66
115
  }) => void;
116
+ onAction?: (event: {
117
+ nativeEvent: ActionCallbackPayload;
118
+ }) => void;
67
119
  style?: StyleProp<ViewStyle>;
68
120
  };
69
121
  export type NewCommentHeightChangedPayload = PreviewCommentsHeightChangedPayload;
@@ -78,6 +130,8 @@ export type NewCommentViewProps = {
78
130
  articleUrl: string;
79
131
  articleThumbnailUrl: string;
80
132
  darkMode?: boolean;
133
+ theme?: 'light' | 'dark';
134
+ colors?: ViafouraColors;
81
135
  onHeightChanged?: (event: {
82
136
  nativeEvent: NewCommentHeightChangedPayload;
83
137
  }) => void;
@@ -87,6 +141,9 @@ export type NewCommentViewProps = {
87
141
  onCloseNewComment?: (event: {
88
142
  nativeEvent: Record<string, never>;
89
143
  }) => void;
144
+ onAction?: (event: {
145
+ nativeEvent: ActionCallbackPayload;
146
+ }) => void;
90
147
  style?: StyleProp<ViewStyle>;
91
148
  };
92
149
  //# sourceMappingURL=Viafoura.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Viafoura.types.d.ts","sourceRoot":"","sources":["../src/Viafoura.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Viafoura.types.d.ts","sourceRoot":"","sources":["../src/Viafoura.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Viafoura.types.js","sourceRoot":"","sources":["../src/Viafoura.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { StyleProp, ViewStyle } from 'react-native';\n\nexport type ViafouraModuleEvents = {\n onChange: (params: ChangeEventPayload) => void;\n};\n\nexport type ChangeEventPayload = {\n value: string;\n};\n\n\nexport type PreviewCommentsEvents =\n | 'onHeightChanged'\n | 'onAuthNeeded'\n | 'onOpenProfile'\n | 'onNewComment'\n | 'onArticlePressed';\n\nexport type PreviewCommentsHeightChangedPayload = {\n newHeight: number;\n containerId: string;\n};\n\nexport type PreviewCommentsAuthNeededPayload = {\n requireLogin?: boolean;\n};\n\nexport type PreviewCommentsOpenProfilePayload = {\n userUUID: string;\n presentationType?: string;\n};\n\nexport type PreviewCommentsNewCommentPayload = {\n content?: string;\n actionType?: string;\n};\n\nexport type PreviewCommentsArticlePressedPayload = {\n articleUrl: string;\n containerId: string;\n};\n\nexport type PreviewCommentsViewProps = {\n containerId: string;\n authorId?: string;\n articleUrl: string;\n articleTitle: string;\n articleSubtitle?: string;\n articleThumbnailUrl: string;\n syndicationKey?: string;\n darkMode?: boolean;\n onHeightChanged?: (event: { nativeEvent: PreviewCommentsHeightChangedPayload }) => void;\n onAuthNeeded?: (event: { nativeEvent: PreviewCommentsAuthNeededPayload }) => void;\n onOpenProfile?: (event: { nativeEvent: PreviewCommentsOpenProfilePayload }) => void;\n onNewComment?: (event: { nativeEvent: PreviewCommentsNewCommentPayload }) => void;\n onArticlePressed?: (event: { nativeEvent: PreviewCommentsArticlePressedPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type ProfileAuthNeededPayload = {\n requireLogin?: boolean;\n};\n\nexport type ProfileViewProps = {\n userUUID: string;\n presentationType?: 'profile' | 'feed';\n darkMode?: boolean;\n onAuthNeeded?: (event: { nativeEvent: ProfileAuthNeededPayload }) => void;\n onCloseProfile?: (event: { nativeEvent: Record<string, never> }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type NewCommentHeightChangedPayload = PreviewCommentsHeightChangedPayload;\nexport type NewCommentAuthNeededPayload = PreviewCommentsAuthNeededPayload;\n\nexport type NewCommentViewProps = {\n newCommentActionType: 'create' | 'edit' | 'reply';\n content?: string; // UUID as string\n containerId: string;\n syndicationKey?: string;\n articleTitle: string;\n articleSubtitle?: string;\n articleUrl: string;\n articleThumbnailUrl: string;\n darkMode?: boolean;\n onHeightChanged?: (event: { nativeEvent: NewCommentHeightChangedPayload }) => void;\n onAuthNeeded?: (event: { nativeEvent: NewCommentAuthNeededPayload }) => void;\n onCloseNewComment?: (event: { nativeEvent: Record<string, never> }) => void;\n style?: StyleProp<ViewStyle>;\n};\n"]}
1
+ {"version":3,"file":"Viafoura.types.js","sourceRoot":"","sources":["../src/Viafoura.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { StyleProp, ViewStyle } from 'react-native';\n\nexport type ViafouraModuleEvents = {\n onChange: (params: ChangeEventPayload) => void;\n};\n\nexport type ChangeEventPayload = {\n value: string;\n};\n\n\nexport type PreviewCommentsEvents =\n | 'onHeightChanged'\n | 'onAuthNeeded'\n | 'onOpenProfile'\n | 'onNewComment'\n | 'onArticlePressed'\n | 'onAction';\n\nexport type ViafouraColors = {\n colorPrimary?: string;\n colorPrimaryLight?: string;\n colorAvatars?: string[];\n};\n\nexport type ActionCallbackType =\n | 'writeNewCommentPressed'\n | 'trendingArticlePressed'\n | 'openProfilePressed'\n | 'seeMoreCommentsPressed'\n | 'notificationPressed'\n | 'commentPosted'\n | 'replyPosted'\n | 'authPressed'\n | 'closeNewCommentPressed'\n | 'closeProfilePressed';\n\nexport type ActionCallbackPayload =\n | {\n type: 'writeNewCommentPressed';\n actionType?: 'create' | 'edit' | 'reply';\n content?: string;\n }\n | {\n type: 'trendingArticlePressed';\n containerId?: string;\n articleUrl?: string;\n }\n | {\n type: 'openProfilePressed';\n userUUID?: string;\n presentationType?: 'profile' | 'feed';\n }\n | {\n type: 'seeMoreCommentsPressed';\n }\n | {\n type: 'notificationPressed';\n presentationType?: 'profile' | 'content';\n userUUID?: string;\n containerUUID?: string;\n contentUUID?: string;\n containerId?: string;\n articleUrl?: string;\n }\n | {\n type: 'commentPosted';\n content?: string;\n }\n | {\n type: 'replyPosted';\n content?: string;\n }\n | {\n type: 'authPressed';\n requireLogin?: boolean;\n }\n | {\n type: 'closeNewCommentPressed';\n }\n | {\n type: 'closeProfilePressed';\n };\n\nexport type PreviewCommentsHeightChangedPayload = {\n newHeight: number;\n containerId: string;\n};\n\nexport type PreviewCommentsAuthNeededPayload = {\n requireLogin?: boolean;\n};\n\nexport type PreviewCommentsOpenProfilePayload = {\n userUUID: string;\n presentationType?: string;\n};\n\nexport type PreviewCommentsNewCommentPayload = {\n content?: string;\n actionType?: string;\n};\n\nexport type PreviewCommentsArticlePressedPayload = {\n articleUrl: string;\n containerId: string;\n};\n\nexport type PreviewCommentsViewProps = {\n containerId: string;\n authorId?: string;\n articleUrl: string;\n articleTitle: string;\n articleSubtitle?: string;\n articleThumbnailUrl: string;\n syndicationKey?: string;\n darkMode?: boolean;\n theme?: 'light' | 'dark';\n colors?: ViafouraColors;\n onHeightChanged?: (event: { nativeEvent: PreviewCommentsHeightChangedPayload }) => void;\n onAuthNeeded?: (event: { nativeEvent: PreviewCommentsAuthNeededPayload }) => void;\n onOpenProfile?: (event: { nativeEvent: PreviewCommentsOpenProfilePayload }) => void;\n onNewComment?: (event: { nativeEvent: PreviewCommentsNewCommentPayload }) => void;\n onArticlePressed?: (event: { nativeEvent: PreviewCommentsArticlePressedPayload }) => void;\n onAction?: (event: { nativeEvent: ActionCallbackPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type ProfileAuthNeededPayload = {\n requireLogin?: boolean;\n};\n\nexport type ProfileViewProps = {\n userUUID: string;\n presentationType?: 'profile' | 'feed';\n darkMode?: boolean;\n theme?: 'light' | 'dark';\n colors?: ViafouraColors;\n onAuthNeeded?: (event: { nativeEvent: ProfileAuthNeededPayload }) => void;\n onCloseProfile?: (event: { nativeEvent: Record<string, never> }) => void;\n onAction?: (event: { nativeEvent: ActionCallbackPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type NewCommentHeightChangedPayload = PreviewCommentsHeightChangedPayload;\nexport type NewCommentAuthNeededPayload = PreviewCommentsAuthNeededPayload;\n\nexport type NewCommentViewProps = {\n newCommentActionType: 'create' | 'edit' | 'reply';\n content?: string; // UUID as string\n containerId: string;\n syndicationKey?: string;\n articleTitle: string;\n articleSubtitle?: string;\n articleUrl: string;\n articleThumbnailUrl: string;\n darkMode?: boolean;\n theme?: 'light' | 'dark';\n colors?: ViafouraColors;\n onHeightChanged?: (event: { nativeEvent: NewCommentHeightChangedPayload }) => void;\n onAuthNeeded?: (event: { nativeEvent: NewCommentAuthNeededPayload }) => void;\n onCloseNewComment?: (event: { nativeEvent: Record<string, never> }) => void;\n onAction?: (event: { nativeEvent: ActionCallbackPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n"]}
@@ -13,7 +13,17 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
13
13
  var syndicationKey: String = ""
14
14
  var articleSubtitle: String = ""
15
15
  var articleThumbnailUrl: String = ""
16
- var darkMode: Bool = false
16
+ var darkMode: Bool = false {
17
+ didSet {
18
+ applyThemeIfReady()
19
+ }
20
+ }
21
+ var theme: String? = nil {
22
+ didSet {
23
+ applyThemeIfReady()
24
+ }
25
+ }
26
+ var colors: [String: Any] = [:]
17
27
 
18
28
  // Events
19
29
  let onHeightChanged = EventDispatcher()
@@ -21,6 +31,7 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
21
31
  let onOpenProfile = EventDispatcher()
22
32
  let onNewComment = EventDispatcher()
23
33
  let onArticlePressed = EventDispatcher()
34
+ let onAction = EventDispatcher()
24
35
 
25
36
  // Internals
26
37
  let fontBold = UIFont.boldSystemFont(ofSize: 17)
@@ -40,8 +51,9 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
40
51
 
41
52
  private func initializeSettings() {
42
53
  let colors = VFColors(
43
- colorPrimary: UIColor(red: 0.00, green: 0.45, blue: 0.91, alpha: 1.00),
44
- colorPrimaryLight: UIColor(red: 0.90, green: 0.95, blue: 1.00, alpha: 1.00)
54
+ colorPrimary: resolveColor(key: "colorPrimary", fallbackKey: "primary", fallback: UIColor(red: 0.00, green: 0.45, blue: 0.91, alpha: 1.00)),
55
+ colorPrimaryLight: resolveColor(key: "colorPrimaryLight", fallbackKey: "primaryLight", fallback: UIColor(red: 0.90, green: 0.95, blue: 1.00, alpha: 1.00)),
56
+ colorAvatars: resolveAvatarColors() ?? Constants.AvatarColors.colors
45
57
  )
46
58
  let fonts = VFFonts(fontBold: fontBold)
47
59
  settings = VFSettings(colors: colors, fonts: fonts)
@@ -68,13 +80,19 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
68
80
  guard let self else { return }
69
81
  switch type {
70
82
  case .writeNewCommentPressed(let actionType):
83
+ self.emitAction(type: "writeNewCommentPressed", payload: ["actionType": self.stringForActionType(actionType)])
71
84
  self.presentNewCommentViewController(actionType: actionType)
72
85
  case .trendingArticlePressed(let metadata, let containerId):
86
+ self.emitAction(type: "trendingArticlePressed", payload: ["containerId": containerId, "articleUrl": metadata.url.absoluteString])
73
87
  self.onArticlePressed(["containerId": containerId, "articleUrl": metadata.url.absoluteString])
74
88
  case .openProfilePressed(let userUUID, let presentationType):
75
89
  // Emit event and present profile for parity with Android
76
- self.onOpenProfile(["userUUID": userUUID.uuidString, "presentationType": String(describing: presentationType)])
90
+ let presentation = self.stringForPresentationType(presentationType)
91
+ self.emitAction(type: "openProfilePressed", payload: ["userUUID": userUUID.uuidString, "presentationType": presentation])
92
+ self.onOpenProfile(["userUUID": userUUID.uuidString, "presentationType": presentation])
77
93
  self.presentProfileViewController(userUUID: userUUID, presentationType: presentationType)
94
+ case .seeMoreCommentsPressed:
95
+ self.emitAction(type: "seeMoreCommentsPressed")
78
96
  default:
79
97
  break
80
98
  }
@@ -89,7 +107,7 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
89
107
  addSubview(vc.view)
90
108
  vc.view.frame = bounds
91
109
  vc.didMove(toParent: parentVC)
92
- vc.setTheme(theme: darkMode ? .dark : .light)
110
+ vc.setTheme(theme: resolveTheme())
93
111
  self.previewCommentsViewController = vc
94
112
  }
95
113
 
@@ -107,12 +125,27 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
107
125
  switch type {
108
126
  case .trendingArticlePressed(let metadata, let containerId):
109
127
  profileVC.dismiss(animated: true)
128
+ self.emitAction(type: "trendingArticlePressed", payload: ["containerId": containerId, "articleUrl": metadata.url.absoluteString])
110
129
  self.onArticlePressed(["containerId": containerId, "articleUrl": metadata.url.absoluteString])
130
+ case .notificationPressed(let presentation):
131
+ var payload: [String: Any] = [:]
132
+ switch presentation {
133
+ case .profile(let userUUID):
134
+ payload["presentationType"] = "profile"
135
+ payload["userUUID"] = userUUID.uuidString
136
+ case .content(let containerUUID, let contentUUID, let containerId, let articleMetadata):
137
+ payload["presentationType"] = "content"
138
+ payload["containerUUID"] = containerUUID.uuidString
139
+ payload["contentUUID"] = contentUUID.uuidString
140
+ payload["containerId"] = containerId
141
+ payload["articleUrl"] = articleMetadata.url.absoluteString
142
+ }
143
+ self.emitAction(type: "notificationPressed", payload: payload)
111
144
  default: break
112
145
  }
113
146
  }
114
147
  profileVC.setActionCallbacks(callbacks: callbacks)
115
- profileVC.setTheme(theme: darkMode ? .dark : .light)
148
+ profileVC.setTheme(theme: resolveTheme())
116
149
  parentVC.present(profileVC, animated: true)
117
150
  }
118
151
 
@@ -129,16 +162,87 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
129
162
  let callbacks: VFActionsCallbacks = { [weak self] type in
130
163
  guard let self else { return }
131
164
  switch type {
132
- case .commentPosted:
133
- self.onNewComment([:])
165
+ case .commentPosted(let contentUUID):
166
+ self.emitAction(type: "commentPosted", payload: ["content": contentUUID.uuidString])
167
+ self.onNewComment(["content": contentUUID.uuidString])
168
+ case .replyPosted(let contentUUID):
169
+ self.emitAction(type: "replyPosted", payload: ["content": contentUUID.uuidString])
134
170
  default: break
135
171
  }
136
172
  }
137
173
  newCommentVC.setActionCallbacks(callbacks: callbacks)
138
- newCommentVC.setTheme(theme: darkMode ? .dark : .light)
174
+ newCommentVC.setTheme(theme: resolveTheme())
139
175
  parentVC.present(newCommentVC, animated: true)
140
176
  }
141
177
 
178
+ private func emitAction(type: String, payload: [String: Any] = [:]) {
179
+ var event = payload
180
+ event["type"] = type
181
+ onAction(event)
182
+ }
183
+
184
+ private func resolveTheme() -> VFTheme {
185
+ switch theme?.lowercased() {
186
+ case "dark":
187
+ return .dark
188
+ case "light":
189
+ return .light
190
+ default:
191
+ return darkMode ? .dark : .light
192
+ }
193
+ }
194
+
195
+ private func applyThemeIfReady() {
196
+ previewCommentsViewController?.setTheme(theme: resolveTheme())
197
+ }
198
+
199
+ private func resolveColor(key: String, fallbackKey: String, fallback: UIColor) -> UIColor {
200
+ let hex = (colors[key] as? String) ?? (colors[fallbackKey] as? String)
201
+ if let hex, let parsed = UIColor.vfColor(fromHex: hex) {
202
+ return parsed
203
+ }
204
+ return fallback
205
+ }
206
+
207
+ private func resolveAvatarColors() -> [UIColor]? {
208
+ let raw = colors["colorAvatars"] ?? colors["avatars"]
209
+ let list: [String]? = (raw as? [String]) ?? (raw as? [Any])?.compactMap { $0 as? String }
210
+ guard let list, list.count == Constants.AvatarColors.colors.count else {
211
+ return nil
212
+ }
213
+ var parsed: [UIColor] = []
214
+ parsed.reserveCapacity(list.count)
215
+ for hex in list {
216
+ guard let color = UIColor.vfColor(fromHex: hex) else { return nil }
217
+ parsed.append(color)
218
+ }
219
+ return parsed
220
+ }
221
+
222
+ private func stringForActionType(_ actionType: VFNewCommentActionType) -> String {
223
+ switch actionType {
224
+ case .create:
225
+ return "create"
226
+ case .edit:
227
+ return "edit"
228
+ case .reply:
229
+ return "reply"
230
+ @unknown default:
231
+ return "create"
232
+ }
233
+ }
234
+
235
+ private func stringForPresentationType(_ presentationType: VFProfilePresentationType) -> String {
236
+ switch presentationType {
237
+ case .profile:
238
+ return "profile"
239
+ case .feed:
240
+ return "feed"
241
+ @unknown default:
242
+ return "profile"
243
+ }
244
+ }
245
+
142
246
  // MARK: VFLayoutDelegate
143
247
  func containerHeightUpdated(viewController: VFUIViewController, height: CGFloat) {
144
248
  onHeightChanged(["newHeight": height, "containerId": containerId])
@@ -146,6 +250,7 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
146
250
 
147
251
  // MARK: VFLoginDelegate
148
252
  func startLogin() {
253
+ emitAction(type: "authPressed", payload: ["requireLogin": true])
149
254
  onAuthNeeded(["requireLogin": true])
150
255
  }
151
256
 
@@ -154,6 +259,26 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
154
259
  func generateAd(viewController: VFUIViewController, adPosition: Int) -> VFAdView? { VFAdView() }
155
260
  }
156
261
 
262
+ extension UIColor {
263
+ static func vfColor(fromHex hex: String) -> UIColor? {
264
+ var value = hex.trimmingCharacters(in: .whitespacesAndNewlines)
265
+ if value.hasPrefix("#") {
266
+ value.removeFirst()
267
+ }
268
+ if value.count == 6 {
269
+ value = "FF" + value
270
+ }
271
+ guard value.count == 8, let hexNumber = UInt64(value, radix: 16) else {
272
+ return nil
273
+ }
274
+ let alpha = CGFloat((hexNumber & 0xFF000000) >> 24) / 255.0
275
+ let red = CGFloat((hexNumber & 0x00FF0000) >> 16) / 255.0
276
+ let green = CGFloat((hexNumber & 0x0000FF00) >> 8) / 255.0
277
+ let blue = CGFloat(hexNumber & 0x000000FF) / 255.0
278
+ return UIColor(red: red, green: green, blue: blue, alpha: alpha)
279
+ }
280
+ }
281
+
157
282
  extension UIView {
158
283
  var parentViewController: UIViewController? {
159
284
  var parentResponder: UIResponder? = self
@@ -187,9 +312,11 @@ public class PreviewCommentsModule: Module {
187
312
  Prop("articleThumbnailUrl") { (view: RNPreviewComments, v: String) in view.articleThumbnailUrl = v }
188
313
  Prop("syndicationKey") { (view: RNPreviewComments, v: String?) in view.syndicationKey = v ?? "" }
189
314
  Prop("darkMode") { (view: RNPreviewComments, v: Bool?) in view.darkMode = v ?? false }
315
+ Prop("theme") { (view: RNPreviewComments, v: String?) in view.theme = v }
316
+ Prop("colors") { (view: RNPreviewComments, v: [String: Any]?) in view.colors = v ?? [:] }
190
317
 
191
318
  // Events
192
- Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed")
319
+ Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed", "onAction")
193
320
  }
194
321
  }
195
322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viafoura/sdk-react-native",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Viafoura React Native SDK",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",