@viafoura/sdk-react-native 0.1.2 → 0.1.3

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)
@@ -39,10 +50,13 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
39
50
  }
40
51
 
41
52
  private func initializeSettings() {
42
- 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)
53
+ let resolvedTheme = resolveTheme()
54
+ var colors = VFColors(
55
+ colorPrimary: resolveColor(key: "colorPrimary", fallbackKey: "primary", fallback: UIColor(red: 0.00, green: 0.45, blue: 0.91, alpha: 1.00)),
56
+ colorPrimaryLight: resolveColor(key: "colorPrimaryLight", fallbackKey: "primaryLight", fallback: UIColor(red: 0.90, green: 0.95, blue: 1.00, alpha: 1.00)),
57
+ colorAvatars: resolveAvatarColors() ?? Constants.AvatarColors.colors
45
58
  )
59
+ colors.setTheme(theme: resolvedTheme)
46
60
  let fonts = VFFonts(fontBold: fontBold)
47
61
  settings = VFSettings(colors: colors, fonts: fonts)
48
62
 
@@ -68,13 +82,19 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
68
82
  guard let self else { return }
69
83
  switch type {
70
84
  case .writeNewCommentPressed(let actionType):
85
+ self.emitAction(type: "writeNewCommentPressed", payload: ["actionType": self.stringForActionType(actionType)])
71
86
  self.presentNewCommentViewController(actionType: actionType)
72
87
  case .trendingArticlePressed(let metadata, let containerId):
88
+ self.emitAction(type: "trendingArticlePressed", payload: ["containerId": containerId, "articleUrl": metadata.url.absoluteString])
73
89
  self.onArticlePressed(["containerId": containerId, "articleUrl": metadata.url.absoluteString])
74
90
  case .openProfilePressed(let userUUID, let presentationType):
75
91
  // Emit event and present profile for parity with Android
76
- self.onOpenProfile(["userUUID": userUUID.uuidString, "presentationType": String(describing: presentationType)])
92
+ let presentation = self.stringForPresentationType(presentationType)
93
+ self.emitAction(type: "openProfilePressed", payload: ["userUUID": userUUID.uuidString, "presentationType": presentation])
94
+ self.onOpenProfile(["userUUID": userUUID.uuidString, "presentationType": presentation])
77
95
  self.presentProfileViewController(userUUID: userUUID, presentationType: presentationType)
96
+ case .seeMoreCommentsPressed:
97
+ self.emitAction(type: "seeMoreCommentsPressed")
78
98
  default:
79
99
  break
80
100
  }
@@ -107,7 +127,22 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
107
127
  switch type {
108
128
  case .trendingArticlePressed(let metadata, let containerId):
109
129
  profileVC.dismiss(animated: true)
130
+ self.emitAction(type: "trendingArticlePressed", payload: ["containerId": containerId, "articleUrl": metadata.url.absoluteString])
110
131
  self.onArticlePressed(["containerId": containerId, "articleUrl": metadata.url.absoluteString])
132
+ case .notificationPressed(let presentation):
133
+ var payload: [String: Any] = [:]
134
+ switch presentation {
135
+ case .profile(let userUUID):
136
+ payload["presentationType"] = "profile"
137
+ payload["userUUID"] = userUUID.uuidString
138
+ case .content(let containerUUID, let contentUUID, let containerId, let articleMetadata):
139
+ payload["presentationType"] = "content"
140
+ payload["containerUUID"] = containerUUID.uuidString
141
+ payload["contentUUID"] = contentUUID.uuidString
142
+ payload["containerId"] = containerId
143
+ payload["articleUrl"] = articleMetadata.url.absoluteString
144
+ }
145
+ self.emitAction(type: "notificationPressed", payload: payload)
111
146
  default: break
112
147
  }
113
148
  }
@@ -129,8 +164,11 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
129
164
  let callbacks: VFActionsCallbacks = { [weak self] type in
130
165
  guard let self else { return }
131
166
  switch type {
132
- case .commentPosted:
133
- self.onNewComment([:])
167
+ case .commentPosted(let contentUUID):
168
+ self.emitAction(type: "commentPosted", payload: ["content": contentUUID.uuidString])
169
+ self.onNewComment(["content": contentUUID.uuidString])
170
+ case .replyPosted(let contentUUID):
171
+ self.emitAction(type: "replyPosted", payload: ["content": contentUUID.uuidString])
134
172
  default: break
135
173
  }
136
174
  }
@@ -139,6 +177,74 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
139
177
  parentVC.present(newCommentVC, animated: true)
140
178
  }
141
179
 
180
+ private func emitAction(type: String, payload: [String: Any] = [:]) {
181
+ var event = payload
182
+ event["type"] = type
183
+ onAction(event)
184
+ }
185
+
186
+ private func resolveTheme() -> VFTheme {
187
+ switch theme?.lowercased() {
188
+ case "dark":
189
+ return .dark
190
+ case "light":
191
+ return .light
192
+ default:
193
+ return darkMode ? .dark : .light
194
+ }
195
+ }
196
+
197
+ private func applyThemeIfReady() {
198
+ previewCommentsViewController?.setTheme(theme: resolveTheme())
199
+ }
200
+
201
+ private func resolveColor(key: String, fallbackKey: String, fallback: UIColor) -> UIColor {
202
+ let hex = (colors[key] as? String) ?? (colors[fallbackKey] as? String)
203
+ if let hex, let parsed = UIColor.vfColor(fromHex: hex) {
204
+ return parsed
205
+ }
206
+ return fallback
207
+ }
208
+
209
+ private func resolveAvatarColors() -> [UIColor]? {
210
+ let raw = colors["colorAvatars"] ?? colors["avatars"]
211
+ let list: [String]? = (raw as? [String]) ?? (raw as? [Any])?.compactMap { $0 as? String }
212
+ guard let list, list.count == Constants.AvatarColors.colors.count else {
213
+ return nil
214
+ }
215
+ var parsed: [UIColor] = []
216
+ parsed.reserveCapacity(list.count)
217
+ for hex in list {
218
+ guard let color = UIColor.vfColor(fromHex: hex) else { return nil }
219
+ parsed.append(color)
220
+ }
221
+ return parsed
222
+ }
223
+
224
+ private func stringForActionType(_ actionType: VFNewCommentActionType) -> String {
225
+ switch actionType {
226
+ case .create:
227
+ return "create"
228
+ case .edit:
229
+ return "edit"
230
+ case .reply:
231
+ return "reply"
232
+ @unknown default:
233
+ return "create"
234
+ }
235
+ }
236
+
237
+ private func stringForPresentationType(_ presentationType: VFProfilePresentationType) -> String {
238
+ switch presentationType {
239
+ case .profile:
240
+ return "profile"
241
+ case .feed:
242
+ return "feed"
243
+ @unknown default:
244
+ return "profile"
245
+ }
246
+ }
247
+
142
248
  // MARK: VFLayoutDelegate
143
249
  func containerHeightUpdated(viewController: VFUIViewController, height: CGFloat) {
144
250
  onHeightChanged(["newHeight": height, "containerId": containerId])
@@ -146,6 +252,7 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
146
252
 
147
253
  // MARK: VFLoginDelegate
148
254
  func startLogin() {
255
+ emitAction(type: "authPressed", payload: ["requireLogin": true])
149
256
  onAuthNeeded(["requireLogin": true])
150
257
  }
151
258
 
@@ -154,6 +261,26 @@ class RNPreviewComments: ExpoView, VFLoginDelegate, VFLayoutDelegate, VFAdDelega
154
261
  func generateAd(viewController: VFUIViewController, adPosition: Int) -> VFAdView? { VFAdView() }
155
262
  }
156
263
 
264
+ extension UIColor {
265
+ static func vfColor(fromHex hex: String) -> UIColor? {
266
+ var value = hex.trimmingCharacters(in: .whitespacesAndNewlines)
267
+ if value.hasPrefix("#") {
268
+ value.removeFirst()
269
+ }
270
+ if value.count == 6 {
271
+ value = "FF" + value
272
+ }
273
+ guard value.count == 8, let hexNumber = UInt64(value, radix: 16) else {
274
+ return nil
275
+ }
276
+ let alpha = CGFloat((hexNumber & 0xFF000000) >> 24) / 255.0
277
+ let red = CGFloat((hexNumber & 0x00FF0000) >> 16) / 255.0
278
+ let green = CGFloat((hexNumber & 0x0000FF00) >> 8) / 255.0
279
+ let blue = CGFloat(hexNumber & 0x000000FF) / 255.0
280
+ return UIColor(red: red, green: green, blue: blue, alpha: alpha)
281
+ }
282
+ }
283
+
157
284
  extension UIView {
158
285
  var parentViewController: UIViewController? {
159
286
  var parentResponder: UIResponder? = self
@@ -187,9 +314,11 @@ public class PreviewCommentsModule: Module {
187
314
  Prop("articleThumbnailUrl") { (view: RNPreviewComments, v: String) in view.articleThumbnailUrl = v }
188
315
  Prop("syndicationKey") { (view: RNPreviewComments, v: String?) in view.syndicationKey = v ?? "" }
189
316
  Prop("darkMode") { (view: RNPreviewComments, v: Bool?) in view.darkMode = v ?? false }
317
+ Prop("theme") { (view: RNPreviewComments, v: String?) in view.theme = v }
318
+ Prop("colors") { (view: RNPreviewComments, v: [String: Any]?) in view.colors = v ?? [:] }
190
319
 
191
320
  // Events
192
- Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed")
321
+ Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed", "onAction")
193
322
  }
194
323
  }
195
324
  }
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.3",
4
4
  "description": "Viafoura React Native SDK",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",