@viafoura/sdk-react-native 0.1.0
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.
- package/README.md +40 -0
- package/android/build.gradle +48 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/viafourasdk/NewCommentModule.kt +27 -0
- package/android/src/main/java/expo/modules/viafourasdk/NewCommentView.kt +153 -0
- package/android/src/main/java/expo/modules/viafourasdk/PreviewCommentsModule.kt +26 -0
- package/android/src/main/java/expo/modules/viafourasdk/PreviewCommentsView.kt +157 -0
- package/android/src/main/java/expo/modules/viafourasdk/ProfileModule.kt +21 -0
- package/android/src/main/java/expo/modules/viafourasdk/ProfileView.kt +134 -0
- package/android/src/main/java/expo/modules/viafourasdk/ViafouraModule.kt +123 -0
- package/build/NewCommentView.d.ts +4 -0
- package/build/NewCommentView.d.ts.map +1 -0
- package/build/NewCommentView.js +13 -0
- package/build/NewCommentView.js.map +1 -0
- package/build/PreviewCommentsView.d.ts +4 -0
- package/build/PreviewCommentsView.d.ts.map +1 -0
- package/build/PreviewCommentsView.js +7 -0
- package/build/PreviewCommentsView.js.map +1 -0
- package/build/ProfileView.d.ts +4 -0
- package/build/ProfileView.d.ts.map +1 -0
- package/build/ProfileView.js +13 -0
- package/build/ProfileView.js.map +1 -0
- package/build/Viafoura.types.d.ts +92 -0
- package/build/Viafoura.types.d.ts.map +1 -0
- package/build/Viafoura.types.js +2 -0
- package/build/Viafoura.types.js.map +1 -0
- package/build/ViafouraModule.d.ts +15 -0
- package/build/ViafouraModule.d.ts.map +1 -0
- package/build/ViafouraModule.js +3 -0
- package/build/ViafouraModule.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +6 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +14 -0
- package/ios/PreviewCommentsModule.swift +195 -0
- package/ios/Viafoura.podspec +30 -0
- package/ios/ViafouraModule.swift +281 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @viafoura/sdk-react-native
|
|
2
|
+
|
|
3
|
+
Basic install and usage.
|
|
4
|
+
|
|
5
|
+
# Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @viafoura/sdk-react-native
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
iOS:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npx pod-install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# Usage
|
|
18
|
+
|
|
19
|
+
Initialize the SDK once at app startup (e.g., in `App.tsx` or a bootstrap module):
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import Viafoura from '@viafoura/sdk-react-native';
|
|
23
|
+
|
|
24
|
+
await Viafoura.initialize('SITE_UUID', 'your.domain.com', true);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then render the views you need:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { PreviewCommentsView } from '@viafoura/sdk-react-native';
|
|
31
|
+
|
|
32
|
+
<PreviewCommentsView
|
|
33
|
+
containerId="YOUR_CONTAINER_ID"
|
|
34
|
+
articleUrl="https://example.com/article"
|
|
35
|
+
articleTitle="Title"
|
|
36
|
+
articleThumbnailUrl="https://example.com/thumb.jpg"
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`ProfileView` and `NewCommentView` are Android-only. On iOS they render as empty views.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
group = 'expo.modules.viafourasdk'
|
|
4
|
+
version = '0.1.0'
|
|
5
|
+
|
|
6
|
+
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
|
+
apply from: expoModulesCorePlugin
|
|
8
|
+
applyKotlinExpoModulesCorePlugin()
|
|
9
|
+
useCoreDependencies()
|
|
10
|
+
useExpoPublishing()
|
|
11
|
+
|
|
12
|
+
// If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
|
|
13
|
+
// The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
|
|
14
|
+
// Most of the time, you may like to manage the Android SDK versions yourself.
|
|
15
|
+
def useManagedAndroidSdkVersions = false
|
|
16
|
+
if (useManagedAndroidSdkVersions) {
|
|
17
|
+
useDefaultAndroidSdkVersions()
|
|
18
|
+
} else {
|
|
19
|
+
buildscript {
|
|
20
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
21
|
+
ext.safeExtGet = { prop, fallback ->
|
|
22
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
project.android {
|
|
26
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 36)
|
|
27
|
+
defaultConfig {
|
|
28
|
+
minSdkVersion safeExtGet("minSdkVersion", 24)
|
|
29
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 36)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
android {
|
|
35
|
+
namespace "expo.modules.viafourasdk"
|
|
36
|
+
defaultConfig {
|
|
37
|
+
versionCode 1
|
|
38
|
+
versionName "0.1.0"
|
|
39
|
+
}
|
|
40
|
+
lintOptions {
|
|
41
|
+
abortOnError false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
dependencies {
|
|
46
|
+
// Viafoura Android SDK (published artifact)
|
|
47
|
+
implementation 'com.viafoura:android:2.0.52'
|
|
48
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.modules.Module
|
|
4
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
+
|
|
6
|
+
class NewCommentModule : Module() {
|
|
7
|
+
override fun definition() = ModuleDefinition {
|
|
8
|
+
Name("NewComment")
|
|
9
|
+
|
|
10
|
+
View(NewCommentView::class) {
|
|
11
|
+
// Props
|
|
12
|
+
Prop("newCommentActionType") { view: NewCommentView, v: String -> view.newCommentActionType = v }
|
|
13
|
+
Prop("content") { view: NewCommentView, v: String? -> view.content = v }
|
|
14
|
+
Prop("containerId") { view: NewCommentView, v: String -> view.containerId = v }
|
|
15
|
+
Prop("syndicationKey") { view: NewCommentView, v: String? -> view.syndicationKey = v }
|
|
16
|
+
Prop("articleTitle") { view: NewCommentView, v: String -> view.articleTitle = v }
|
|
17
|
+
Prop("articleSubtitle") { view: NewCommentView, v: String? -> view.articleSubtitle = v }
|
|
18
|
+
Prop("articleUrl") { view: NewCommentView, v: String -> view.articleUrl = v }
|
|
19
|
+
Prop("articleThumbnailUrl") { view: NewCommentView, v: String -> view.articleThumbnailUrl = v }
|
|
20
|
+
Prop("darkMode") { view: NewCommentView, v: Boolean? -> view.darkMode = v ?: false }
|
|
21
|
+
|
|
22
|
+
// Events
|
|
23
|
+
Events("onAuthNeeded", "onCloseNewComment", "onHeightChanged")
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.widget.FrameLayout
|
|
5
|
+
import androidx.core.view.ViewCompat
|
|
6
|
+
import androidx.fragment.app.Fragment
|
|
7
|
+
import androidx.fragment.app.FragmentActivity
|
|
8
|
+
import expo.modules.kotlin.AppContext
|
|
9
|
+
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
10
|
+
import expo.modules.kotlin.views.ExpoView
|
|
11
|
+
|
|
12
|
+
// Viafoura SDK imports
|
|
13
|
+
import com.viafourasdk.src.fragments.base.VFFragment
|
|
14
|
+
import com.viafourasdk.src.fragments.newcomment.VFNewCommentFragment
|
|
15
|
+
import com.viafourasdk.src.fragments.newcomment.VFNewCommentFragmentBuilder
|
|
16
|
+
import com.viafourasdk.src.model.local.VFNewCommentAction
|
|
17
|
+
import com.viafourasdk.src.interfaces.VFActionsInterface
|
|
18
|
+
import com.viafourasdk.src.interfaces.VFCustomUIInterface
|
|
19
|
+
import com.viafourasdk.src.interfaces.VFLayoutInterface
|
|
20
|
+
import com.viafourasdk.src.model.local.VFActionData
|
|
21
|
+
import com.viafourasdk.src.model.local.VFActionType
|
|
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
|
+
import com.viafourasdk.src.model.local.VFSettings
|
|
26
|
+
import com.viafourasdk.src.model.local.VFTheme
|
|
27
|
+
import java.net.URL
|
|
28
|
+
import java.util.UUID
|
|
29
|
+
|
|
30
|
+
class NewCommentView(context: Context, private val appContext: AppContext) :
|
|
31
|
+
ExpoView(context, appContext), VFCustomUIInterface, VFActionsInterface, VFLayoutInterface {
|
|
32
|
+
|
|
33
|
+
// Props
|
|
34
|
+
var newCommentActionType: String = "create" // create | edit | reply
|
|
35
|
+
var content: String? = null
|
|
36
|
+
var containerId: String? = null
|
|
37
|
+
var syndicationKey: String? = null
|
|
38
|
+
var articleTitle: String? = null
|
|
39
|
+
var articleSubtitle: String? = null
|
|
40
|
+
var articleUrl: String? = null
|
|
41
|
+
var articleThumbnailUrl: String? = null
|
|
42
|
+
var darkMode: Boolean = false
|
|
43
|
+
|
|
44
|
+
// Events
|
|
45
|
+
private val onAuthNeeded by EventDispatcher()
|
|
46
|
+
private val onCloseNewComment by EventDispatcher()
|
|
47
|
+
private val onHeightChanged by EventDispatcher()
|
|
48
|
+
|
|
49
|
+
// Internals
|
|
50
|
+
private val container = FrameLayout(context).also {
|
|
51
|
+
it.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
52
|
+
it.id = ViewCompat.generateViewId()
|
|
53
|
+
addView(it)
|
|
54
|
+
}
|
|
55
|
+
private var fragment: VFNewCommentFragment? = null
|
|
56
|
+
|
|
57
|
+
override fun onAttachedToWindow() {
|
|
58
|
+
super.onAttachedToWindow()
|
|
59
|
+
ensureFragment()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun onDetachedFromWindow() {
|
|
63
|
+
super.onDetachedFromWindow()
|
|
64
|
+
destroyFragment()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private fun currentActivity(): FragmentActivity? =
|
|
68
|
+
appContext.currentActivity as? FragmentActivity
|
|
69
|
+
|
|
70
|
+
private fun ensureFragment() {
|
|
71
|
+
if (fragment != null) return
|
|
72
|
+
val activity = currentActivity() ?: return
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
val metadata = VFArticleMetadata(
|
|
76
|
+
URL(requireNotNull(articleUrl)),
|
|
77
|
+
requireNotNull(articleTitle),
|
|
78
|
+
articleSubtitle ?: "",
|
|
79
|
+
URL(requireNotNull(articleThumbnailUrl))
|
|
80
|
+
)
|
|
81
|
+
val colors = VFColors(
|
|
82
|
+
VFDefaultColors.getInstance().colorPrimaryDefault(null),
|
|
83
|
+
VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
|
|
84
|
+
)
|
|
85
|
+
val settings = VFSettings(colors)
|
|
86
|
+
|
|
87
|
+
val type = when (newCommentActionType) {
|
|
88
|
+
"edit" -> VFNewCommentAction.VFNewCommentActionType.edit
|
|
89
|
+
"reply" -> VFNewCommentAction.VFNewCommentActionType.reply
|
|
90
|
+
else -> VFNewCommentAction.VFNewCommentActionType.create
|
|
91
|
+
}
|
|
92
|
+
val action = VFNewCommentAction(type)
|
|
93
|
+
content?.let { c ->
|
|
94
|
+
if (c.isNotEmpty()) action.content = UUID.fromString(c)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
val builder = VFNewCommentFragmentBuilder(action, requireNotNull(containerId), metadata, settings)
|
|
98
|
+
syndicationKey?.let { builder.syndicationKey(it) }
|
|
99
|
+
val frag = builder.build()
|
|
100
|
+
frag.setActionCallback(this)
|
|
101
|
+
frag.setCustomUICallback(this)
|
|
102
|
+
frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
|
|
103
|
+
|
|
104
|
+
activity.supportFragmentManager
|
|
105
|
+
.beginTransaction()
|
|
106
|
+
.replace(container.id, frag, container.id.toString())
|
|
107
|
+
.commit()
|
|
108
|
+
|
|
109
|
+
fragment = frag
|
|
110
|
+
} catch (_: Exception) {
|
|
111
|
+
// Swallow; invalid input
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private fun destroyFragment() {
|
|
116
|
+
val activity = currentActivity() ?: return
|
|
117
|
+
val tag = container.id.toString()
|
|
118
|
+
val frag: Fragment? = activity.supportFragmentManager.findFragmentByTag(tag)
|
|
119
|
+
if (frag != null) {
|
|
120
|
+
activity.supportFragmentManager
|
|
121
|
+
.beginTransaction()
|
|
122
|
+
.remove(frag)
|
|
123
|
+
.commit()
|
|
124
|
+
}
|
|
125
|
+
fragment = null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// VFActionsInterface
|
|
129
|
+
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
|
|
130
|
+
when (actionType) {
|
|
131
|
+
VFActionType.closeNewCommentPressed -> {
|
|
132
|
+
onCloseNewComment(emptyMap<String, Any>())
|
|
133
|
+
}
|
|
134
|
+
VFActionType.authPressed -> {
|
|
135
|
+
onAuthNeeded(mapOf("requireLogin" to true))
|
|
136
|
+
}
|
|
137
|
+
else -> {}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// VFCustomUIInterface
|
|
142
|
+
override fun customizeView(
|
|
143
|
+
theme: com.viafourasdk.src.model.local.VFTheme?,
|
|
144
|
+
customViewType: com.viafourasdk.src.model.local.VFCustomViewType?,
|
|
145
|
+
view: android.view.View?
|
|
146
|
+
) { /* no-op */ }
|
|
147
|
+
|
|
148
|
+
// VFLayoutInterface
|
|
149
|
+
override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {
|
|
150
|
+
onHeightChanged(mapOf("newHeight" to height, "containerId" to containerId))
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.modules.Module
|
|
4
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
+
|
|
6
|
+
class PreviewCommentsModule : Module() {
|
|
7
|
+
override fun definition() = ModuleDefinition {
|
|
8
|
+
Name("PreviewComments")
|
|
9
|
+
|
|
10
|
+
View(PreviewCommentsView::class) {
|
|
11
|
+
// Props
|
|
12
|
+
Prop("containerId") { view: PreviewCommentsView, v: String -> view.containerId = v }
|
|
13
|
+
Prop("authorId") { view: PreviewCommentsView, v: String? -> view.authorId = v }
|
|
14
|
+
Prop("articleUrl") { view: PreviewCommentsView, v: String -> view.articleUrl = v }
|
|
15
|
+
Prop("articleTitle") { view: PreviewCommentsView, v: String -> view.articleTitle = v }
|
|
16
|
+
Prop("articleSubtitle") { view: PreviewCommentsView, v: String? -> view.articleSubtitle = v }
|
|
17
|
+
Prop("articleThumbnailUrl") { view: PreviewCommentsView, v: String -> view.articleThumbnailUrl = v }
|
|
18
|
+
Prop("syndicationKey") { view: PreviewCommentsView, v: String? -> view.syndicationKey = v }
|
|
19
|
+
Prop("darkMode") { view: PreviewCommentsView, v: Boolean? -> view.darkMode = v ?: false }
|
|
20
|
+
|
|
21
|
+
// Events
|
|
22
|
+
Events("onHeightChanged", "onAuthNeeded", "onOpenProfile", "onNewComment", "onArticlePressed")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import android.widget.FrameLayout
|
|
6
|
+
import androidx.core.view.ViewCompat
|
|
7
|
+
import androidx.fragment.app.Fragment
|
|
8
|
+
import androidx.fragment.app.FragmentActivity
|
|
9
|
+
import expo.modules.kotlin.AppContext
|
|
10
|
+
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
11
|
+
import expo.modules.kotlin.views.ExpoView
|
|
12
|
+
|
|
13
|
+
// Viafoura SDK imports
|
|
14
|
+
import com.viafourasdk.src.fragments.base.VFFragment
|
|
15
|
+
import com.viafourasdk.src.fragments.previewcomments.VFPreviewCommentsFragment
|
|
16
|
+
import com.viafourasdk.src.fragments.previewcomments.VFPreviewCommentsFragmentBuilder
|
|
17
|
+
import com.viafourasdk.src.interfaces.VFActionsInterface
|
|
18
|
+
import com.viafourasdk.src.interfaces.VFCustomUIInterface
|
|
19
|
+
import com.viafourasdk.src.interfaces.VFLayoutInterface
|
|
20
|
+
import com.viafourasdk.src.model.local.VFActionData
|
|
21
|
+
import com.viafourasdk.src.model.local.VFActionType
|
|
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
|
+
import com.viafourasdk.src.model.local.VFSettings
|
|
26
|
+
import com.viafourasdk.src.model.local.VFTheme
|
|
27
|
+
import java.net.URL
|
|
28
|
+
|
|
29
|
+
class PreviewCommentsView(context: Context, private val appContext: AppContext) :
|
|
30
|
+
ExpoView(context, appContext), VFCustomUIInterface, VFActionsInterface, VFLayoutInterface {
|
|
31
|
+
|
|
32
|
+
// Props
|
|
33
|
+
var containerId: String? = null
|
|
34
|
+
var authorId: String? = null
|
|
35
|
+
var articleUrl: String? = null
|
|
36
|
+
var articleTitle: String? = null
|
|
37
|
+
var articleSubtitle: String? = null
|
|
38
|
+
var articleThumbnailUrl: String? = null
|
|
39
|
+
var syndicationKey: String? = null
|
|
40
|
+
var darkMode: Boolean = false
|
|
41
|
+
|
|
42
|
+
// Events
|
|
43
|
+
private val onHeightChanged by EventDispatcher()
|
|
44
|
+
private val onAuthNeeded by EventDispatcher()
|
|
45
|
+
private val onOpenProfile by EventDispatcher()
|
|
46
|
+
private val onNewComment by EventDispatcher()
|
|
47
|
+
private val onArticlePressed by EventDispatcher()
|
|
48
|
+
|
|
49
|
+
// Internals
|
|
50
|
+
private val container = FrameLayout(context).also {
|
|
51
|
+
it.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
52
|
+
it.id = ViewCompat.generateViewId()
|
|
53
|
+
addView(it)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private var fragment: VFPreviewCommentsFragment? = null
|
|
57
|
+
|
|
58
|
+
override fun onAttachedToWindow() {
|
|
59
|
+
super.onAttachedToWindow()
|
|
60
|
+
ensureFragment()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun onDetachedFromWindow() {
|
|
64
|
+
super.onDetachedFromWindow()
|
|
65
|
+
destroyFragment()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private fun currentActivity(): FragmentActivity? =
|
|
69
|
+
appContext.currentActivity as? FragmentActivity
|
|
70
|
+
|
|
71
|
+
private fun ensureFragment() {
|
|
72
|
+
if (fragment != null) return
|
|
73
|
+
val activity = currentActivity() ?: return
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
val meta = VFArticleMetadata(
|
|
77
|
+
URL(requireNotNull(articleUrl)),
|
|
78
|
+
requireNotNull(articleTitle),
|
|
79
|
+
articleSubtitle ?: "",
|
|
80
|
+
URL(requireNotNull(articleThumbnailUrl))
|
|
81
|
+
)
|
|
82
|
+
val colors = VFColors(
|
|
83
|
+
VFDefaultColors.getInstance().colorPrimaryDefault(null),
|
|
84
|
+
VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
|
|
85
|
+
)
|
|
86
|
+
val settings = VFSettings(colors)
|
|
87
|
+
|
|
88
|
+
val builder = VFPreviewCommentsFragmentBuilder(requireNotNull(containerId), meta, settings)
|
|
89
|
+
syndicationKey?.let { builder.syndicationKey(it) }
|
|
90
|
+
val frag = builder.build()
|
|
91
|
+
frag.setActionCallback(this)
|
|
92
|
+
frag.setLayoutCallback(this)
|
|
93
|
+
frag.setCustomUICallback(this)
|
|
94
|
+
frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
|
|
95
|
+
authorId?.let { if (it.isNotEmpty()) frag.setAuthorIds(listOf(it)) }
|
|
96
|
+
|
|
97
|
+
activity.supportFragmentManager
|
|
98
|
+
.beginTransaction()
|
|
99
|
+
.replace(container.id, frag, container.id.toString())
|
|
100
|
+
.commit()
|
|
101
|
+
|
|
102
|
+
fragment = frag
|
|
103
|
+
} catch (_: Exception) {
|
|
104
|
+
// Swallow; invalid input
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private fun destroyFragment() {
|
|
109
|
+
val activity = currentActivity() ?: return
|
|
110
|
+
val tag = container.id.toString()
|
|
111
|
+
val frag = activity.supportFragmentManager.findFragmentByTag(tag)
|
|
112
|
+
if (frag != null) {
|
|
113
|
+
activity.supportFragmentManager
|
|
114
|
+
.beginTransaction()
|
|
115
|
+
.remove(frag)
|
|
116
|
+
.commit()
|
|
117
|
+
}
|
|
118
|
+
fragment = null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// VFCustomUIInterface
|
|
122
|
+
override fun customizeView(
|
|
123
|
+
theme: com.viafourasdk.src.model.local.VFTheme?,
|
|
124
|
+
customViewType: com.viafourasdk.src.model.local.VFCustomViewType?,
|
|
125
|
+
view: android.view.View?
|
|
126
|
+
) { /* no-op */ }
|
|
127
|
+
|
|
128
|
+
// VFActionsInterface
|
|
129
|
+
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
|
|
130
|
+
when (actionType) {
|
|
131
|
+
VFActionType.writeNewCommentPressed -> {
|
|
132
|
+
val content = action.newCommentAction?.content?.toString()
|
|
133
|
+
val type = action.newCommentAction?.type?.toString()
|
|
134
|
+
onNewComment(mapOf("content" to content, "actionType" to type).filterValues { it != null })
|
|
135
|
+
}
|
|
136
|
+
VFActionType.openProfilePressed -> {
|
|
137
|
+
val pres = action.openProfileAction?.presentationType?.toString()
|
|
138
|
+
val user = action.openProfileAction?.userUUID?.toString()
|
|
139
|
+
onOpenProfile(mapOf("presentationType" to pres, "userUUID" to user).filterValues { it != null })
|
|
140
|
+
}
|
|
141
|
+
VFActionType.trendingArticlePressed -> {
|
|
142
|
+
val url = action.trendingPressedAction?.articleMetadata?.url?.toString() ?: return
|
|
143
|
+
val containerId = action.trendingPressedAction?.containerId ?: ""
|
|
144
|
+
onArticlePressed(mapOf("articleUrl" to url, "containerId" to containerId))
|
|
145
|
+
}
|
|
146
|
+
VFActionType.authPressed -> {
|
|
147
|
+
onAuthNeeded(mapOf("requireLogin" to true))
|
|
148
|
+
}
|
|
149
|
+
else -> {}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// VFLayoutInterface
|
|
154
|
+
override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {
|
|
155
|
+
onHeightChanged(mapOf("newHeight" to height, "containerId" to containerId))
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.modules.Module
|
|
4
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
+
|
|
6
|
+
class ProfileModule : Module() {
|
|
7
|
+
override fun definition() = ModuleDefinition {
|
|
8
|
+
Name("Profile")
|
|
9
|
+
|
|
10
|
+
View(ProfileView::class) {
|
|
11
|
+
// Props
|
|
12
|
+
Prop("userUUID") { view: ProfileView, v: String -> view.userUUID = v }
|
|
13
|
+
Prop("presentationType") { view: ProfileView, v: String? -> view.presentationType = v }
|
|
14
|
+
Prop("darkMode") { view: ProfileView, v: Boolean? -> view.darkMode = v ?: false }
|
|
15
|
+
|
|
16
|
+
// Events
|
|
17
|
+
Events("onAuthNeeded", "onCloseProfile")
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
package expo.modules.viafourasdk
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.widget.FrameLayout
|
|
5
|
+
import androidx.core.view.ViewCompat
|
|
6
|
+
import androidx.fragment.app.Fragment
|
|
7
|
+
import androidx.fragment.app.FragmentActivity
|
|
8
|
+
import expo.modules.kotlin.AppContext
|
|
9
|
+
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
10
|
+
import expo.modules.kotlin.views.ExpoView
|
|
11
|
+
|
|
12
|
+
// Viafoura SDK imports
|
|
13
|
+
import com.viafourasdk.src.fragments.profile.VFProfileFragment
|
|
14
|
+
import com.viafourasdk.src.fragments.profile.VFProfileFragmentBuilder
|
|
15
|
+
import com.viafourasdk.src.interfaces.VFActionsInterface
|
|
16
|
+
import com.viafourasdk.src.interfaces.VFCustomUIInterface
|
|
17
|
+
import com.viafourasdk.src.interfaces.VFLayoutInterface
|
|
18
|
+
import com.viafourasdk.src.model.local.VFActionData
|
|
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
|
+
import com.viafourasdk.src.model.local.VFSettings
|
|
23
|
+
import com.viafourasdk.src.model.local.VFProfilePresentationType
|
|
24
|
+
import com.viafourasdk.src.model.local.VFTheme
|
|
25
|
+
import java.util.UUID
|
|
26
|
+
|
|
27
|
+
class ProfileView(context: Context, private val appContext: AppContext) :
|
|
28
|
+
ExpoView(context, appContext), VFCustomUIInterface, VFActionsInterface, VFLayoutInterface {
|
|
29
|
+
|
|
30
|
+
// Props
|
|
31
|
+
var userUUID: String? = null
|
|
32
|
+
var presentationType: String? = null // "profile" | "feed"
|
|
33
|
+
var darkMode: Boolean = false
|
|
34
|
+
|
|
35
|
+
// Events
|
|
36
|
+
private val onAuthNeeded by EventDispatcher()
|
|
37
|
+
private val onCloseProfile by EventDispatcher()
|
|
38
|
+
|
|
39
|
+
// Internals
|
|
40
|
+
private val container = FrameLayout(context).also {
|
|
41
|
+
it.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
42
|
+
it.id = ViewCompat.generateViewId()
|
|
43
|
+
addView(it)
|
|
44
|
+
}
|
|
45
|
+
private var fragment: VFProfileFragment? = null
|
|
46
|
+
|
|
47
|
+
override fun onAttachedToWindow() {
|
|
48
|
+
super.onAttachedToWindow()
|
|
49
|
+
ensureFragment()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun onDetachedFromWindow() {
|
|
53
|
+
super.onDetachedFromWindow()
|
|
54
|
+
destroyFragment()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private fun currentActivity(): FragmentActivity? =
|
|
58
|
+
appContext.currentActivity as? FragmentActivity
|
|
59
|
+
|
|
60
|
+
private fun ensureFragment() {
|
|
61
|
+
if (fragment != null) return
|
|
62
|
+
val activity = currentActivity() ?: return
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
val colors = VFColors(
|
|
66
|
+
VFDefaultColors.getInstance().colorPrimaryDefault(null),
|
|
67
|
+
VFDefaultColors.getInstance().colorPrimaryLightDefault(null)
|
|
68
|
+
)
|
|
69
|
+
val settings = VFSettings(colors)
|
|
70
|
+
|
|
71
|
+
val pres = when (presentationType) {
|
|
72
|
+
"feed" -> VFProfilePresentationType.feed
|
|
73
|
+
"profile" -> VFProfilePresentationType.profile
|
|
74
|
+
else -> null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
val uuid = UUID.fromString(requireNotNull(userUUID))
|
|
78
|
+
val frag = VFProfileFragmentBuilder(uuid, pres, settings).build()
|
|
79
|
+
frag.setActionCallback(this)
|
|
80
|
+
frag.setCustomUICallback(this)
|
|
81
|
+
frag.setTheme(if (darkMode) VFTheme.dark else VFTheme.light)
|
|
82
|
+
|
|
83
|
+
activity.supportFragmentManager
|
|
84
|
+
.beginTransaction()
|
|
85
|
+
.replace(container.id, frag, container.id.toString())
|
|
86
|
+
.commit()
|
|
87
|
+
|
|
88
|
+
fragment = frag
|
|
89
|
+
} catch (_: Exception) {
|
|
90
|
+
// Swallow; invalid input
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private fun destroyFragment() {
|
|
95
|
+
val activity = currentActivity() ?: return
|
|
96
|
+
val tag = container.id.toString()
|
|
97
|
+
val frag: Fragment? = activity.supportFragmentManager.findFragmentByTag(tag)
|
|
98
|
+
if (frag != null) {
|
|
99
|
+
activity.supportFragmentManager
|
|
100
|
+
.beginTransaction()
|
|
101
|
+
.remove(frag)
|
|
102
|
+
.commit()
|
|
103
|
+
}
|
|
104
|
+
fragment = null
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// VFActionsInterface
|
|
108
|
+
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
|
|
109
|
+
when (actionType) {
|
|
110
|
+
VFActionType.closeProfilePressed -> {
|
|
111
|
+
onCloseProfile(emptyMap<String, Any>())
|
|
112
|
+
}
|
|
113
|
+
VFActionType.authPressed -> {
|
|
114
|
+
onAuthNeeded(mapOf("requireLogin" to true))
|
|
115
|
+
}
|
|
116
|
+
else -> {}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// VFCustomUIInterface
|
|
121
|
+
override fun customizeView(
|
|
122
|
+
theme: com.viafourasdk.src.model.local.VFTheme?,
|
|
123
|
+
customViewType: com.viafourasdk.src.model.local.VFCustomViewType?,
|
|
124
|
+
view: android.view.View?
|
|
125
|
+
) { /* no-op */ }
|
|
126
|
+
|
|
127
|
+
// VFLayoutInterface
|
|
128
|
+
override fun containerHeightUpdated(
|
|
129
|
+
fragment: com.viafourasdk.src.fragments.base.VFFragment,
|
|
130
|
+
containerId: String,
|
|
131
|
+
height: Int
|
|
132
|
+
) { /* no-op for profile */ }
|
|
133
|
+
}
|
|
134
|
+
|