Channel/request.js

import { addEvent, getElement, removeEvent } from '../util'
import { applyAttributes, emptyCleanups, getAppKey, KakaoError, processRules, URL, windowOpen } from '../common'

import { createAnchorImage, makeChannelParams, POPUP_FEATURES } from './common';
import rules from './rules'

const API_VER = '1.1';
const ADD_CHANNEL_POPUP_NAME = 'channel_add_social_plugin';
const CHAT_POPUP_NAME = 'channel_chat_social_plugin';

/**
 * 카카오톡 채널 추가 버튼을 생성합니다.
 * @function createAddChannelButton
 * @param {Object} settings 카카오톡 채널 추가 버튼 생성과 관련된 설정을 key/value로 전달합니다.
 * @param {String|HTMLElement} settings.container DOM Element 또는 Element의 ID Selector
 * @param {String} settings.channelPublicId 대상 카카오톡 채널 홈 URL에 포함된 카카오톡 채널 ID
 * @param {String} [settings.size="small"] 채널추가 버튼의 사이즈, "small"|"large"
 * @param {Boolean} [settings.supportMultipleDensities=false] 화면 배율에 따라 2x 3x 이미지를 사용, IE 미지원
 * @see {@link Kakao.Channel.addChannel} 직접 버튼을 제작하여 사용할 때 이용하세요.
 * @see {@link https://developers.kakao.com/tool/demo/channel/add?method=button|데모 보러가기}
 * @memberof Kakao.Channel
 */
export function createAddChannelButton(settings) {
  const container$ = getElement(settings.container);
  if (!container$) {
    throw new KakaoError('container is required for Channel.createAddChannelButton: pass in element or id');
  } else {
    applyAttributes(settings, container$, {
      channelPublicId: 'data-channel-public-id',
      size: 'data-size',
      supportMultipleDensities: 'data-support-multiple-densities',
    });
  }

  settings = processRules(settings, rules.createAddChannelButton, 'Channel.createAddChannelButton');

  const imgSrc = getAddChannelImgSrc(settings);
  const anchor$ = createAnchorImage(settings, imgSrc, '카카오톡 채널 추가 버튼');
  container$.appendChild(anchor$);

  const clickHandler = e => {
    e.preventDefault();
    openAddChannelPopup(settings);
  };

  addEvent(anchor$, 'click', clickHandler);
  cleanups.push(() => {
    removeEvent(anchor$, 'click', clickHandler);
    container$.removeChild(anchor$);
  });
}

/**
 * 카카오톡 채널 추가 팝업창을 띄웁니다. 사용자의 클릭 이벤트 이후에 호출되어야 브라우저에 의해 팝업이 차단되지 않습니다.
 * @function addChannel
 * @param {Object} settings 카카오톡 채널 추가와 관련된 설정을 key/value로 전달합니다.
 * @param {String} settings.channelPublicId 대상 카카오톡 채널 홈 URL에 포함된 카카오톡 채널 공개 ID
 * @see {@link Kakao.Channel.createAddChannelButton} 직접 버튼을 제작하여 사용할 필요가 없는 경우 유용합니다.
 * @see {@link https://developers.kakao.com/tool/demo/channel/add|데모 보러가기}
 * @memberof Kakao.Channel
 */
export function addChannel(settings) {
  settings = processRules(settings, rules.addChannel, 'Channel.addChannel');
  openAddChannelPopup(settings);
}

function getAddChannelImgSrc(settings) {
  const filename = `friendadd_${settings.size}_yellow_rect.png`;
  return `${URL.channelIcon}/channel/${filename}`;
}

function openAddChannelPopup(settings) {
  let addChannelUrl = `${URL.channel}/${settings.channelPublicId}/friend`;
  if (getAppKey() !== null) {
    addChannelUrl += `?${makeChannelParams(API_VER)}`;
  }

  windowOpen(addChannelUrl, ADD_CHANNEL_POPUP_NAME, POPUP_FEATURES);
}

/**
 * 카카오톡 채널 1:1 채팅 버튼을 생성합니다.
 * @function createChatButton
 * @param {Object} settings 카카오톡 채널 1:1 채팅 버튼 생성과 관련된 설정을 key/value로 전달합니다.
 * @param {String|HTMLElement} settings.container DOM Element 또는 Element의 ID Selector
 * @param {String} settings.channelPublicId 대상 카카오톡 채널 홈 URL에 포함된 카카오톡 채널 ID
 * @param {String} [settings.title="consult"] 1:1 채팅 버튼에 들어갈 제목, "consult"|"question"
 * @param {String} [settings.size="small"] 1:1 채팅 버튼의 사이즈, "small"|"large"
 * @param {String} [settings.color="yellow"] 1:1 채팅 버튼의 배경색, "yellow"|"black"
 * @param {String} [settings.shape="pc"] 1:1 채팅 버튼의 모양, "pc"|"mobile"
 * @param {Boolean} [settings.supportMultipleDensities=false] 화면 배율에 따라 2x 3x 이미지를 사용, IE 미지원
 * @see {@link Kakao.Channel.chat} 직접 버튼을 제작하여 사용할 때 이용하세요.
 * @see {@link https://developers.kakao.com/tool/demo/channel/chat?method=button|데모 보러가기}
 * @memberof Kakao.Channel
 */
export function createChatButton(settings) {
  const container$ = getElement(settings.container);
  if (!container$) {
    throw new KakaoError('container is required for Channel.createChatButton: pass in element or id');
  } else {
    applyAttributes(settings, container$, {
      channelPublicId: 'data-channel-public-id',
      size: 'data-size',
      color: 'data-color',
      shape: 'data-shape',
      title: 'data-title',
      supportMultipleDensities: 'data-support-multiple-densities',
    });
  }

  settings = processRules(settings, rules.createChatButton, 'Channel.createChatButton');

  const imgSrc = getChatImgSrc(settings);
  const anchor$ = createAnchorImage(settings, imgSrc, '카카오톡 채널 1:1 채팅 버튼');
  container$.appendChild(anchor$);

  const clickHandler = e => {
    e.preventDefault();
    openChatPopup(settings);
  };

  addEvent(anchor$, 'click', clickHandler);
  cleanups.push(() => {
    removeEvent(anchor$, 'click', clickHandler);
    container$.removeChild(anchor$);
  });
}

/**
 * 카카오톡 채널 1:1 채팅을 시작합니다. 사용자의 클릭 이벤트 이후에 호출되어야 브라우저에 의해 팝업이 차단되지 않습니다.
 * @function chat
 * @param {Object} settings 카카오톡 채널 추가와 관련된 설정을 key/value로 전달합니다.
 * @param {String} settings.channelPublicId 대상 카카오톡 채널 홈 URL에 포함된 카카오톡 채널 공개 ID
 * @see {@link Kakao.Channel.createChatButton} 직접 버튼을 제작하여 사용할 필요가 없는 경우 유용합니다.
 * @see {@link https://developers.kakao.com/tool/demo/channel/chat|데모 보러가기}
 * @memberof Kakao.Channel
 */
export function chat(settings) {
  settings = processRules(settings, rules.chat, 'Channel.chat');
  openChatPopup(settings);
}

function getChatImgSrc(settings) {
  const filename = `${settings.title}_${settings.size}_${settings.color}_${settings.shape}.png`;
  return `${URL.channelIcon}/channel/${filename}`;
}

function openChatPopup(settings) {
  let chatUrl = `${URL.channel}/${settings.channelPublicId}/chat`;
  if (getAppKey() !== null) {
    chatUrl += `?${makeChannelParams(API_VER)}`;
  }

  windowOpen(chatUrl, CHAT_POPUP_NAME, POPUP_FEATURES);
}

const cleanups = []
export function cleanup() {
  emptyCleanups(cleanups)
}