FastComments.com

FastComments Android Library


์ด๊ฒƒ์€ FastComments์˜ ๊ณต์‹ Android ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

Android์šฉ FastComments ๋Œ“๊ธ€ ์œ„์ ฏ

์ €์žฅ์†Œ

GitHub์—์„œ ๋ณด๊ธฐ


๊ธฐ๋Šฅ Internal Link


  • ๐Ÿ”„ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•œ ๋ผ์ด๋ธŒ ๋Œ“๊ธ€
  • ๐Ÿ“ฑ ๋„ค์ดํ‹ฐ๋ธŒ Android UI ๊ตฌ์„ฑ ์š”์†Œ
  • ๐Ÿงต ๋‹ต๊ธ€์„ ํฌํ•จํ•œ ์Šค๋ ˆ๋“œํ˜• ํ† ๋ก 
  • ๐Ÿ‘ค ๋ณด์•ˆ SSO ์ธ์ฆ
  • ๐Ÿ‘ ์‚ฌ์šฉ์ž ์ง€์ • ๊ฐ€๋Šฅํ•œ ์Šคํƒ€์ผ์˜ ํˆฌํ‘œ ์‹œ์Šคํ…œ
  • ๐Ÿ”” ์‚ฌ์šฉ์ž ์•Œ๋ฆผ ๋ฐ ์ ‘์† ์ƒํƒœ
  • ๐Ÿ” ๋Œ“๊ธ€ ์ค‘์žฌ ๊ธฐ๋Šฅ
  • ๐Ÿ“ฑ ์†Œ์…œ ํ”ผ๋“œ ํ†ตํ•ฉ
  • โ™พ๏ธ ๋ฌดํ•œ ์Šคํฌ๋กค ํŽ˜์ด์ง€ ๋งค๊น€
  • ๐ŸŽจ ํฌ๊ด„์ ์ธ ํ…Œ๋งˆ

์š”๊ตฌ ์‚ฌํ•ญ Internal Link

  • Android SDK 26+ (Android 8.0 Oreo ์ด์ƒ)
  • Java 8+

์„ค์น˜ Internal Link

์•ฑ์˜ build.gradle.kts ํŒŒ์ผ์— FastComments SDK๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

dependencies {
    implementation("com.fastcomments:sdk:0.0.1")
}

ํ”„๋กœ์ ํŠธ์˜ settings.gradle.kts ํŒŒ์ผ์— Repsy ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”:

dependencyResolutionManagement {
    repositories {
        maven {
            url = uri("https://repo.repsy.io/mvn/winrid/fastcomments")
        }
        // ๋‹ค๋ฅธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ...
    }
}

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• Internal Link


1. ๋ ˆ์ด์•„์›ƒ์— FastCommentsView ์ถ”๊ฐ€

<com.fastcomments.sdk.FastCommentsView
    android:id="@+id/commentsView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

2. SDK ์ดˆ๊ธฐํ™” ๋ฐ ๊ตฌ์„ฑ

// SDK ๊ตฌ์„ฑ
val config = CommentWidgetConfig(
    "your-tenant-id", 
    "page-url-id", 
    "Page Title", 
    "yourdomain.com", 
    "Site Name"
)

// ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์˜ต์…˜
config.voteStyle = VoteStyle.UpDown // ๋˜๋Š” VoteStyle.Heart
config.enableInfiniteScrolling = true
config.hasDarkBackground = true // ๋‹คํฌ ๋ชจ๋“œ ์ง€์›์šฉ

// SDK ์ดˆ๊ธฐํ™”
val sdk = FastCommentsSDK(config)

// ๋ ˆ์ด์•„์›ƒ์—์„œ ๋Œ“๊ธ€ ๋ทฐ ์ฐพ๊ธฐ
val commentsView = findViewById<FastCommentsView>(R.id.commentsView)

// ๋ทฐ์— SDK ์ธ์Šคํ„ด์Šค ์„ค์ •
commentsView.setSDK(sdk)

// ๋Œ“๊ธ€ ๋กœ๋“œ
commentsView.load()

๋ณด์•ˆ SSO ์ธ์ฆ Internal Link


์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๋ณด์•ˆ ์ธ์ฆ์„ ๊ตฌํ˜„ํ•˜์„ธ์š”:

// ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ์ƒ์„ฑ(๊ถŒ์žฅ: ์„œ๋ฒ„ ์ธก์—์„œ)
val userData = SecureSSOUserData(
    "user-id",
    "user@example.com",
    "User Name",
    "https://path-to-avatar.jpg"
)

// SSO ํ† ํฐ ์ƒ์„ฑ(์„œ๋ฒ„์—์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!)
val sso = FastCommentsSSO.createSecure("YOUR_API_KEY", userData)
val token = sso.prepareToSend()

// ๊ตฌ์„ฑ์— ์ถ”๊ฐ€
config.sso = token

ํ”ผ๋“œ ์—ฐ๋™ Internal Link

๋Œ“๊ธ€์ด ํฌํ•จ๋œ ์†Œ์…œ ๋ฏธ๋””์–ด ์Šคํƒ€์ผ ํ”ผ๋“œ ํ‘œ์‹œ:

// SDK ๊ตฌ์„ฑ
CommentWidgetConfig config = new CommentWidgetConfig();
config.tenantId = "your-tenant-id";
config.urlId = "page-url-id";

// ํ”ผ๋“œ SDK ์ดˆ๊ธฐํ™”
FastCommentsFeedSDK feedSDK = new FastCommentsFeedSDK(config);

// ํ”ผ๋“œ ๋ทฐ ์„ค์ •
FastCommentsFeedView feedView = findViewById(R.id.feedView);
feedView.setSDK(feedSDK);

// ์ƒํ˜ธ์ž‘์šฉ ๋ฆฌ์Šค๋„ˆ ์„ค์ •
feedView.setFeedViewInteractionListener(new FastCommentsFeedView.OnFeedViewInteractionListener() {
    @Override
    public void onFeedLoaded(List<FeedPost> posts) {
        // ํ”ผ๋“œ ๋กœ๋“œ ์„ฑ๊ณต
    }

    @Override
    public void onFeedError(String errorMessage) {
        // ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
    }

    @Override
    public void onPostSelected(FeedPost post) {
        // ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒŒ์‹œ๋ฌผ์„ ์„ ํƒํ•จ
    }

    @Override
    public void onCommentsRequested(FeedPost post) {
        // ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ“๊ธ€ ํ‘œ์‹œ
        CommentsDialog dialog = new CommentsDialog(context, post, feedSDK);
        dialog.show();
    }
});

// Load the feed
feedView.load();

๋ผ์ด๋ธŒ ์ฑ„ํŒ… ์—ฐ๋™ Internal Link

์•ฑ์— ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

// ๋ ˆ์ด์•„์›ƒ XML์— LiveChatView ์ถ”๊ฐ€
// <com.fastcomments.sdk.LiveChatView
//     android:id="@+id/liveChatView"
//     android:layout_width="match_parent"
//     android:layout_height="match_parent" />

// Create a configuration for the SDK
val config = CommentWidgetConfig().apply {
    tenantId = "your-tenant-id"
    urlId = "chat-room-identifier" 
    pageTitle = "Chat Room Name"
}
LiveChatView.setupLiveChatConfig(config)

// ์„ ํƒ ์‚ฌํ•ญ: ์‚ฌ์šฉ์ž ์ธ์ฆ ์ถ”๊ฐ€
val userData = SimpleSSOUserData(
    "User Name",
    "user@example.com",
    "https://path-to-avatar.jpg"
)
val sso = FastCommentsSSO(userData)
config.sso = sso.prepareToSend()

// SDK ์ดˆ๊ธฐํ™”
val sdk = FastCommentsSDK().configure(config)

// ๋ผ์ด๋ธŒ ์ฑ„ํŒ… ๋ทฐ ์„ค์ •
val liveChatView = findViewById<LiveChatView>(R.id.liveChatView)
liveChatView.setSDK(sdk)
liveChatView.load()

// ๋ผ์ดํ”„์‚ฌ์ดํด ์ฒ˜๋ฆฌ๋ฅผ ์žŠ์ง€ ๋งˆ์„ธ์š”
override fun onResume() {
    super.onResume()
    sdk.refreshLiveEvents()
}

override fun onDestroy() {
    super.onDestroy()
    sdk.cleanup()
}

์˜ˆ์ œ ํ”„๋กœ์ ํŠธ Internal Link


๋‹ค์Œ ๋ฐ๋ชจ ๊ตฌํ˜„์„ ํ™•์ธํ•ด๋ณด์„ธ์š”:


๊ตฌ์„ฑ ์˜ต์…˜ Internal Link

์ด SDK๋Š” CommentWidgetConfig ํด๋ž˜์Šค์—์„œ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

Option Description
tenantId FastComments ๊ณ„์ • ID
urlId ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ID
sso ์ธ์ฆ์„ ์œ„ํ•œ SSO ํ† ํฐ
allowAnon ์ต๋ช… ๋Œ“๊ธ€ ํ—ˆ์šฉ
voteStyle UpDown ๋˜๋Š” Heart ํˆฌํ‘œ ์Šคํƒ€์ผ
hideAvatars ์‚ฌ์šฉ์ž ์•„๋ฐ”ํƒ€ ์ˆจ๊ธฐ๊ธฐ
hasDarkBackground ๋‹คํฌ ๋ชจ๋“œ ์—ฌ๋ถ€
customCSS ์‚ฌ์šฉ์ž ์ •์˜ CSS ์Šคํƒ€์ผ
enableInfiniteScrolling ๋ฌดํ•œ ์Šคํฌ๋กค ํŽ˜์ด์ง• ํ™œ์„ฑํ™”
readonly ๋Œ“๊ธ€ ์ž‘์„ฑ ๋น„ํ™œ์„ฑํ™”(๋Œ“๊ธ€ ํ‘œ์‹œ)
disableVoting ํˆฌํ‘œ ๊ธฐ๋Šฅ ๋น„ํ™œ์„ฑํ™”
disableLiveCommenting ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ๋น„ํ™œ์„ฑํ™”

ํฌ๊ด„์ ์ธ ํ…Œ๋งˆ ๋งž์ถคํ™” Internal Link

FastComments SDK์˜ ๋ชจ๋“  ๋ฒ„ํŠผ ๋ฐ UI ์š”์†Œ๋Š” ํ…Œ๋งˆ ์„ค์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์•ฑ ๋ธŒ๋žœ๋”ฉ์„ ์™„์ „ํžˆ ์ œ์–ดํ•˜๋ ค๋ฉด FastCommentsTheme.Builder๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ํ…Œ๋งˆ ์ ์šฉ (๊ถŒ์žฅ)

val theme = FastCommentsTheme.Builder()
    // ์ž‘์—… ๋ฒ„ํŠผ: ์ „์†ก, ํˆฌํ‘œ, ๋ฉ”๋‰ด, ์ข‹์•„์š”/๊ณต์œ  ๋ฒ„ํŠผ
    .setActionButtonColor(Color.parseColor("#FF1976D2"))

    // ๋‹ต๊ธ€ ๋ฒ„ํŠผ: ๋Œ“๊ธ€ ๋‹ต๊ธ€ ๋ฒ„ํŠผ  
    .setReplyButtonColor(Color.parseColor("#FF4CAF50"))

    // ํ† ๊ธ€ ๋ฒ„ํŠผ: ๋‹ต๊ธ€ ํ‘œ์‹œ/์ˆจ๊ธฐ๊ธฐ ๋ฒ„ํŠผ
    .setToggleRepliesButtonColor(Color.parseColor("#FFFF5722"))

    // ๋” ๋ณด๊ธฐ ๋ฒ„ํŠผ: ํŽ˜์ด์ง€ ๋งค๊น€ ๋ฒ„ํŠผ
    .setLoadMoreButtonTextColor(Color.parseColor("#FF9C27B0"))

    .setPrimaryColor(Color.parseColor("#FF6200EE"))
    .setLinkColor(Color.parseColor("#FF1976D2"))
    .setDialogHeaderBackgroundColor(Color.parseColor("#FF333333"))
    .build()

// ํ…Œ๋งˆ ์ ์šฉ
sdk.setTheme(theme)

๋น ๋ฅธ ์ƒ‰์ƒ ์žฌ์ •์˜

๊ฐ„๋‹จํ•œ ๋ธŒ๋žœ๋”ฉ์„ ์œ„ํ•ด colors.xml์˜ ์ƒ‰์ƒ ๋ฆฌ์†Œ์Šค๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์„ธ์š”:

<!-- ์•ฑ์˜ res/values/colors.xml์—์„œ -->
<resources>
    <!-- ๋ชจ๋“  ์ฃผ์š” UI ์š”์†Œ ๋ณ€๊ฒฝ -->
    <color name="primary">#FF1976D2</color>

    <!-- ๋˜๋Š” ํŠน์ • ๋ฒ„ํŠผ ์œ ํ˜•์„ ์‚ฌ์šฉ์žํ™” -->
    <color name="fastcomments_action_button_color">#FF1976D2</color>
    <color name="fastcomments_reply_button_color">#FF4CAF50</color>
    <color name="fastcomments_toggle_replies_button_color">#FFFF5722</color>
    <color name="fastcomments_load_more_button_text_color">#FF9C27B0</color>
</resources>

ํ…Œ๋งˆ ์ ์šฉ ๋ฒ„ํŠผ ๋ฒ”์œ„

SDK์˜ ๋ชจ๋“  ๋ฒ„ํŠผ์€ ํ…Œ๋งˆ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

  • ์ „์†ก ๋ฒ„ํŠผ, ํˆฌํ‘œ ๋ฒ„ํŠผ, ๋ฉ”๋‰ด ๋ฒ„ํŠผ, ๋‹ต๊ธ€ ๋ฒ„ํŠผ
  • ๋‹ต๊ธ€ ํ‘œ์‹œ/์ˆจ๊ธฐ๊ธฐ ๋ฒ„ํŠผ, ๋” ๋ณด๊ธฐ ๋ฒ„ํŠผ
  • ํ”ผ๋“œ ์•ก์…˜ ๋ฒ„ํŠผ(์ข‹์•„์š”, ๋Œ“๊ธ€, ๊ณต์œ )
  • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ฒ„ํŠผ(์ œ์ถœ, ์ทจ์†Œ, ์ €์žฅ)
  • ํ”ผ๋“œ ๊ฒŒ์‹œ๋ฌผ์˜ ๋™์  ์ž‘์—… ๋ฒ„ํŠผ

์ž์„ธํ•œ ํ…Œ๋งˆ ๋ฌธ์„œ๋Š” THEMING.md๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ Internal Link

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€

Activity ๋˜๋Š” Fragment์—์„œ FastComments ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด, ๋” ์ด์ƒ ๋ทฐ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ ํ•ญ์ƒ cleanup()์„ ํ˜ธ์ถœํ•˜์„ธ์š”:

์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ:

@Override
protected void onDestroy() {
    super.onDestroy();
    // ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด FastComments ๋ทฐ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค
    if (feedView != null) {
        feedView.cleanup();
    }
    if (commentsView != null) {
        commentsView.cleanup();
    }
}

ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ:

@Override
public void onDestroyView() {
    super.onDestroyView();
    // ํ”„๋ž˜๊ทธ๋จผํŠธ ๋ทฐ๊ฐ€ ํŒŒ๊ดด๋  ๋•Œ FastComments ๋ทฐ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค
    if (feedView != null) {
        feedView.cleanup();
        feedView = null;
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    // ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ€ ํŒŒ๊ดด๋  ๋•Œ ์ถ”๊ฐ€ ์ •๋ฆฌ ์ˆ˜ํ–‰
    if (feedSDK != null) {
        feedSDK.cleanup();
        feedSDK = null;
    }
}

ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์ „ํ™˜ํ•  ๋•Œ:

// FastComments ๋ทฐ๋ฅผ ํฌํ•จํ•œ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ๊ต์ฒด ๋˜๋Š” ์ œ๊ฑฐํ•˜๊ธฐ ์ „์—
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
if (currentFragment instanceof YourFragmentWithFeedView) {
    ((YourFragmentWithFeedView) currentFragment).cleanupFeedView();
}

// Then proceed with fragment transaction
getSupportFragmentManager().beginTransaction()
    .replace(R.id.container, newFragment)
    .commit();

์ค‘์š”: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ํ•ญ์ƒ cleanup() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. ํŠนํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ:

  • ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ
  • ํ”„๋ž˜๊ทธ๋จผํŠธ ๋ทฐ๊ฐ€ ํŒŒ๊ดด๋  ๋•Œ
  • ํ”„๋ž˜๊ทธ๋จผํŠธ ๊ฐ„ ์ „ํ™˜ ์‹œ
  • FastComments ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•œ ํ™”๋ฉด์—์„œ ์ด๋™ํ•  ๋•Œ

๋„์›€์„ ์›ํ•˜์‹œ๋‚˜์š”?

Android ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ด€๋ จํ•˜์—ฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์งˆ๋ฌธ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, ๋‹ค์Œ์„ ์ด์šฉํ•˜์„ธ์š”:

๊ธฐ์—ฌ

๊ธฐ์—ฌ๋Š” ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ๊ธฐ์—ฌ ์ง€์นจ์€ GitHub ์ €์žฅ์†Œ์—์„œ ํ™•์ธํ•˜์„ธ์š”.