Add a conversation to your app

The Viafoura SDK ships Fragments for classic View-based screens and Composables for Jetpack Compose screens. Follow the section that matches how your screen is built.

Using Fragments

Add a conversation container

  1. Create your VFArticleMetadata object.
VFArticleMetadata articleMetadata = new VFArticleMetadata("STORY_LINK", "STORY TITLE", "STORY_DESC", "STORY_PICTURE_URL");
val articleMetadata = VFArticleMetadata("STORY_LINK", "STORY TITLE", "STORY_DESC", "STORY_PICTURE_URL")
  1. Create your VFSettings object.
VFColors colors = new VFColors(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryLight));
VFSettings vfSettings = new VFSettings(colors);
val colors = VFColors(ContextCompat.getColor(applicationContext, R.color.colorPrimary), ContextCompat.getColor(applicationContext, R.color.colorPrimaryLight))
val vfSettings = VFSettings(colors)
  1. Add the VFPreviewCommentsFragment into your content.
VFPreviewCommentsFragment previewCommentsFragment = new VFPreviewCommentsFragmentBuilder(
        articleViewModel.getStory().getContainerId(),
        articleMetadata,
        vfSettings
)
.paginationSize(10)
.sortType(VFSortType.newest)
.build();
previewCommentsFragment.setActionCallback(this);

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.article_comments_container, previewCommentsFragment);
ft.commitAllowingStateLoss();
val previewCommentsFragment = VFPreviewCommentsFragmentBuilder(
        articleViewModel.story.containerId,
        articleMetadata,
        vfSettings
)
.paginationSize(10)
.sortType(VFSortType.newest)
.build()
previewCommentsFragment.setActionCallback(this)

val ft = supportFragmentManager.beginTransaction()
ft.replace(R.id.article_comments_container, previewCommentsFragment)
ft.commitAllowingStateLoss()
  1. Listen to the VFPreviewCommentsFragment action callback. Implement VFActionsInterface on your Activity.
@Override
public void onNewAction(VFActionType actionType, VFActionData action) {
    if (actionType == VFActionType.writeNewCommentPressed) {
        Intent intent = new Intent(getApplicationContext(), NewCommentActivity.class);
        intent.putExtra(IntentKeys.INTENT_CONTAINER_ID, articleViewModel.getStory().getContainerId());
        intent.putExtra(IntentKeys.INTENT_STORY_LINK, articleViewModel.getStory().getLink());
        intent.putExtra(IntentKeys.INTENT_STORY_TITLE, articleViewModel.getStory().getTitle());
        intent.putExtra(IntentKeys.INTENT_STORY_DESC, articleViewModel.getStory().getDescription());
        intent.putExtra(IntentKeys.INTENT_STORY_PICTUREURL, articleViewModel.getStory().getPictureUrl());
        intent.putExtra(IntentKeys.INTENT_NEW_COMMENT_ACTION, action.getNewCommentAction().type.toString());
        if (action.getNewCommentAction().content != null) {
            intent.putExtra(IntentKeys.INTENT_NEW_COMMENT_CONTENT, action.getNewCommentAction().content.toString());
        }
        startActivity(intent);
    } else if (actionType == VFActionType.openProfilePressed) {
        Intent intent = new Intent(getApplicationContext(), ProfileActivity.class);
        intent.putExtra(IntentKeys.INTENT_USER_UUID, action.getOpenProfileAction().userUUID.toString());
        if (action.getOpenProfileAction().presentationType != null) {
            intent.putExtra(IntentKeys.INTENT_USER_PRESENTATION_TYPE, action.getOpenProfileAction().presentationType.toString());
        }
        startActivity(intent);
    } else if (actionType == VFActionType.authPressed) {
        Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
        startActivity(intent);
    }
}
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
    when (actionType) {
        VFActionType.writeNewCommentPressed -> {
            val newCommentAction = action.newCommentAction ?: return
            val intent = Intent(applicationContext, NewCommentActivity::class.java)
            intent.putExtra(IntentKeys.INTENT_CONTAINER_ID, articleViewModel.story.containerId)
            intent.putExtra(IntentKeys.INTENT_STORY_LINK, articleViewModel.story.link)
            intent.putExtra(IntentKeys.INTENT_STORY_TITLE, articleViewModel.story.title)
            intent.putExtra(IntentKeys.INTENT_STORY_DESC, articleViewModel.story.description)
            intent.putExtra(IntentKeys.INTENT_STORY_PICTUREURL, articleViewModel.story.pictureUrl)
            intent.putExtra(IntentKeys.INTENT_NEW_COMMENT_ACTION, newCommentAction.type.toString())
            newCommentAction.content?.let { intent.putExtra(IntentKeys.INTENT_NEW_COMMENT_CONTENT, it.toString()) }
            startActivity(intent)
        }
        VFActionType.openProfilePressed -> {
            val openProfileAction = action.openProfileAction ?: return
            val intent = Intent(applicationContext, ProfileActivity::class.java)
            intent.putExtra(IntentKeys.INTENT_USER_UUID, openProfileAction.userUUID.toString())
            openProfileAction.presentationType?.let { intent.putExtra(IntentKeys.INTENT_USER_PRESENTATION_TYPE, it.toString()) }
            startActivity(intent)
        }
        VFActionType.authPressed -> startActivity(Intent(applicationContext, LoginActivity::class.java))
        else -> {}
    }
}

Type a new comment

  1. Create your VFArticleMetadata object.
VFArticleMetadata articleMetadata = new VFArticleMetadata(
        getIntent().getStringExtra(IntentKeys.INTENT_STORY_LINK),
        getIntent().getStringExtra(IntentKeys.INTENT_STORY_TITLE),
        getIntent().getStringExtra(IntentKeys.INTENT_STORY_DESC),
        getIntent().getStringExtra(IntentKeys.INTENT_STORY_PICTUREURL)
);
val articleMetadata = VFArticleMetadata(
        intent.getStringExtra(IntentKeys.INTENT_STORY_LINK)!!,
        intent.getStringExtra(IntentKeys.INTENT_STORY_TITLE)!!,
        intent.getStringExtra(IntentKeys.INTENT_STORY_DESC)!!,
        intent.getStringExtra(IntentKeys.INTENT_STORY_PICTUREURL)!!
)
  1. Create your VFSettings object.
VFColors colors = new VFColors(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryLight));
VFSettings vfSettings = new VFSettings(colors);
val colors = VFColors(ContextCompat.getColor(applicationContext, R.color.colorPrimary), ContextCompat.getColor(applicationContext, R.color.colorPrimaryLight))
val vfSettings = VFSettings(colors)
  1. Create the VFNewCommentAction object.
VFNewCommentAction.VFNewCommentActionType newCommentActionType = VFNewCommentAction.VFNewCommentActionType.valueOf(getIntent().getStringExtra(IntentKeys.INTENT_NEW_COMMENT_ACTION));
VFNewCommentAction newCommentAction = new VFNewCommentAction(newCommentActionType);

if (getIntent().getStringExtra(IntentKeys.INTENT_NEW_COMMENT_CONTENT) != null) {
    newCommentAction.content = UUID.fromString(getIntent().getStringExtra(IntentKeys.INTENT_NEW_COMMENT_CONTENT));
}
val newCommentActionType = VFNewCommentAction.VFNewCommentActionType.valueOf(intent.getStringExtra(IntentKeys.INTENT_NEW_COMMENT_ACTION)!!)
val newCommentAction = VFNewCommentAction(newCommentActionType)

intent.getStringExtra(IntentKeys.INTENT_NEW_COMMENT_CONTENT)?.let {
    newCommentAction.content = UUID.fromString(it)
}
  1. Add the VFNewCommentFragment into your content.
VFNewCommentFragment newCommentFragment = new VFNewCommentFragmentBuilder(
        newCommentAction,
        getIntent().getStringExtra(IntentKeys.INTENT_CONTAINER_ID),
        articleMetadata,
        vfSettings
).build();
newCommentFragment.setActionCallback(this);

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.new_comment_container, newCommentFragment);
ft.commit();
val newCommentFragment = VFNewCommentFragmentBuilder(
        newCommentAction,
        intent.getStringExtra(IntentKeys.INTENT_CONTAINER_ID)!!,
        articleMetadata,
        vfSettings
).build()
newCommentFragment.setActionCallback(this)

val ft = supportFragmentManager.beginTransaction()
ft.replace(R.id.new_comment_container, newCommentFragment)
ft.commit()
  1. Listen to the VFNewCommentFragment action callback.
@Override
public void onNewAction(VFActionType actionType, VFActionData action) {
    if (actionType == VFActionType.closeNewCommentPressed) {
        getOnBackPressedDispatcher().onBackPressed();
    } else if (actionType == VFActionType.authPressed) {
        Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
        startActivity(intent);
    }
}
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
    when (actionType) {
        VFActionType.closeNewCommentPressed -> onBackPressedDispatcher.onBackPressed()
        VFActionType.authPressed -> startActivity(Intent(applicationContext, LoginActivity::class.java))
        else -> {}
    }
}

Open a profile

  1. Create your VFSettings object.
VFColors colors = new VFColors(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryLight));
VFSettings vfSettings = new VFSettings(colors);
val colors = VFColors(ContextCompat.getColor(applicationContext, R.color.colorPrimary), ContextCompat.getColor(applicationContext, R.color.colorPrimaryLight))
val vfSettings = VFSettings(colors)
  1. Create the VFProfilePresentationType object.
VFProfilePresentationType presentationType = VFProfilePresentationType.profile;
if (getIntent().getStringExtra(IntentKeys.INTENT_USER_PRESENTATION_TYPE) != null) {
    presentationType = VFProfilePresentationType.valueOf(getIntent().getStringExtra(IntentKeys.INTENT_USER_PRESENTATION_TYPE));
}
val presentationType = intent.getStringExtra(IntentKeys.INTENT_USER_PRESENTATION_TYPE)
    ?.let { VFProfilePresentationType.valueOf(it) }
    ?: VFProfilePresentationType.profile
  1. Add the VFProfileFragment into your content.
VFProfileFragment profileFragment = new VFProfileFragmentBuilder(
        UUID.fromString(getIntent().getStringExtra(IntentKeys.INTENT_USER_UUID)),
        presentationType,
        vfSettings
).build();
profileFragment.setActionCallback(this);

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.profile_container, profileFragment);
ft.commit();
val profileFragment = VFProfileFragmentBuilder(
        UUID.fromString(intent.getStringExtra(IntentKeys.INTENT_USER_UUID)),
        presentationType,
        vfSettings
).build()
profileFragment.setActionCallback(this)

val ft = supportFragmentManager.beginTransaction()
ft.replace(R.id.profile_container, profileFragment)
ft.commit()
  1. Listen to the VFProfileFragment action callback.
@Override
public void onNewAction(VFActionType actionType, VFActionData action) {
    if (actionType == VFActionType.closeProfilePressed) {
        getOnBackPressedDispatcher().onBackPressed();
    } else if (actionType == VFActionType.authPressed) {
        Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
        startActivity(intent);
    }
}
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
    when (actionType) {
        VFActionType.closeProfilePressed -> onBackPressedDispatcher.onBackPressed()
        VFActionType.authPressed -> startActivity(Intent(applicationContext, LoginActivity::class.java))
        else -> {}
    }
}

Implement the VFLayoutInterface (Optional)

The fragment content height will change depending on the amount of content present on the container. Listen to height changes by implementing the VFLayoutInterface, registering it with setLayoutCallback, and update the container view height accordingly.

previewCommentsFragment.setLayoutCallback(this);
previewCommentsFragment.setLayoutCallback(this)
@Override
public void containerHeightUpdated(VFFragment fragment, String containerId, int height) {

}
override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {

}

Using Jetpack Compose

The android-compose artifact provides VFPreviewComments, VFNewComment and VFProfile as Composables. They host the Fragments above inside your composition, so they take the same VFSettings, VFArticleMetadata and callback interfaces, and the content sizes itself. No FragmentTransaction or container view is needed.

Add the Compose dependency

Add the com.viafoura:android-compose artifact as described in Add the Viafoura Android SDK to your app. The hosting Activity must be a FragmentActivity or AppCompatActivity.

Add a conversation container

  1. Create your VFArticleMetadata and VFSettings objects. These are the same objects used with Fragments.
val articleMetadata = VFArticleMetadata(story.link, story.title, story.description, story.pictureUrl)

val colors = VFColors(ContextCompat.getColor(applicationContext, R.color.colorPrimary), ContextCompat.getColor(applicationContext, R.color.colorPrimaryLight))
val vfSettings = VFSettings(colors)
  1. Add VFPreviewComments into your composition. Place it anywhere in a LazyColumn or Column. The content reports its own height, so you don't need a container view.
setContent {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        item {
            // Your article content
        }
        item {
            VFPreviewComments(
                containerId = story.containerId,
                articleMetadata = articleMetadata,
                settings = vfSettings,
                modifier = Modifier.fillMaxWidth(),
                paginationSize = 10,
                sortType = VFSortType.newest,
                actionCallback = this@ArticleActivity
            )
        }
    }
}
ParameterTypeDescription
containerIdStringContainer ID of the content
articleMetadataVFArticleMetadataArticle metadata object
settingsVFSettingsSettings object
modifierModifierOptional. Compose modifier applied to the host view
paginationSizeIntOptional, defaults to 10
sortTypeVFSortType?Optional. Initial sort order
themeVFTheme?Optional. VFTheme.light or VFTheme.dark
actionCallbackVFActionsInterface?Optional. Receives user actions, same interface as setActionCallback on the Fragment
customUICallbackVFCustomUIInterface?Optional. Same interface as setCustomUICallback on the Fragment
layoutCallbackVFLayoutInterface?Optional. Receives height updates. Not required, the Composable sizes itself
  1. Listen to the VFPreviewComments action callback. Implement VFActionsInterface on your Activity and pass it as actionCallback. The actions are the same as with Fragments, see step 4 of the Fragments section above.

Type a new comment

  1. Create your VFArticleMetadata, VFSettings and VFNewCommentAction objects. Build them from the Intent extras exactly as in the Fragments section above.

  2. Add VFNewComment into your composition.

setContent {
    VFNewComment(
        action = newCommentAction,
        containerId = intent.getStringExtra(IntentKeys.INTENT_CONTAINER_ID)!!,
        articleMetadata = articleMetadata,
        settings = vfSettings,
        modifier = Modifier.fillMaxSize(),
        actionCallback = this@NewCommentActivity
    )
}
  1. Listen to the VFNewComment action callback.
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
    when (actionType) {
        VFActionType.closeNewCommentPressed -> onBackPressedDispatcher.onBackPressed()
        VFActionType.authPressed -> startActivity(Intent(applicationContext, LoginActivity::class.java))
        else -> {}
    }
}

Open a profile

  1. Create your VFSettings and VFProfilePresentationType objects. Build them from the Intent extras exactly as in the Fragments section above.

  2. Add VFProfile into your composition.

setContent {
    VFProfile(
        userUUID = UUID.fromString(intent.getStringExtra(IntentKeys.INTENT_USER_UUID)),
        presentationType = presentationType,
        settings = vfSettings,
        modifier = Modifier.fillMaxSize(),
        actionCallback = this@ProfileActivity
    )
}
  1. Listen to the VFProfile action callback.
override fun onNewAction(actionType: VFActionType, action: VFActionData) {
    when (actionType) {
        VFActionType.closeProfilePressed -> onBackPressedDispatcher.onBackPressed()
        VFActionType.authPressed -> startActivity(Intent(applicationContext, LoginActivity::class.java))
        else -> {}
    }
}

Listen to height changes (Optional)

The Composables already size themselves to their content, so a layout callback is only needed if you want to react to height changes yourself. Pass a VFLayoutInterface as layoutCallback.

VFPreviewComments(
    containerId = story.containerId,
    articleMetadata = articleMetadata,
    settings = vfSettings,
    layoutCallback = object : VFLayoutInterface {
        override fun containerHeightUpdated(fragment: VFFragment, containerId: String, height: Int) {

        }
    }
)

Fetch the comment count for a container (Optional)

Call getCommentCount passing the container ID. This works the same way for Fragments and Compose.

VFLiveCommentsService liveCommentsService = ViafouraSDK.liveComments();
liveCommentsService.getCommentCount("12312312", new VFLiveCommentsService.CommentCountCallback() {
    @Override
    public void onSuccess(Integer commentCount) {

    }

    @Override
    public void onError(NetworkError err) {

    }
});
val liveCommentsService = ViafouraSDK.liveComments()
liveCommentsService.getCommentCount("12312312", object : VFLiveCommentsService.CommentCountCallback {
    override fun onSuccess(commentCount: Int) {

    }

    override fun onError(err: NetworkError) {

    }
})

Did this page help you?