channel.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * 핸들 표시/URL canonical form 정규화 — 앞에 붙은 '@' 모두 제거.
  3. * YouTube API 의 customUrl 이 '@foo' 형태로 내려오기 때문에 legacy 데이터가 '@foo' 로 저장돼 있을 수 있어
  4. * 프론트 표시/URL 조합 시점에 한 번 더 방어적 정규화를 수행한다.
  5. */
  6. function stripAtPrefix(value: string): string {
  7. let i = 0;
  8. while (i < value.length && value[i] === '@') {
  9. i++;
  10. }
  11. return value.slice(i);
  12. }
  13. /**
  14. * 채널 URL 생성 헬퍼.
  15. * - handle 이 있으면 `/channel/@handle` 형식 (짧고 친숙한 URL)
  16. * - 없으면 기존 `/channel/{channelSID}` 형식 (YouTube Channel ID 폴백)
  17. *
  18. * handle 은 의도적으로 URL 인코딩하지 않는다.
  19. * Watch 페이지의 canonical 리다이렉트 로직이 decoded URL 기준이라
  20. * 여기서 인코딩하면 `current !== canonical` 무한 리다이렉트 루프가 발생.
  21. * 브라우저가 navigation 시 필요한 문자만 자동 인코딩하므로 안전하다.
  22. */
  23. export function buildChannelUrl(channel: { handle?: string|null; channelSID: string }): string {
  24. if (channel.handle) {
  25. return `/channel/@${stripAtPrefix(channel.handle)}`;
  26. }
  27. return `/channel/${channel.channelSID}`;
  28. }
  29. /**
  30. * 라이브 시청 URL 생성 헬퍼. (/watch 프리픽스)
  31. */
  32. export function buildWatchUrl(channel: { handle?: string|null; channelSID: string }): string {
  33. if (channel.handle) {
  34. return `/watch/@${stripAtPrefix(channel.handle)}`;
  35. }
  36. return `/watch/${channel.channelSID}`;
  37. }
  38. /**
  39. * 핸들 표시 문자열 생성 — `@foo` 형식으로 반환. 이중 `@` 방지.
  40. */
  41. export function formatHandle(handle: string): string {
  42. return `@${stripAtPrefix(handle)}`;
  43. }
  44. /**
  45. * URL 파라미터(identifier)가 @handle 인지 SID 인지 판별.
  46. */
  47. export function isHandleIdentifier(identifier: string): boolean {
  48. return identifier.length > 0 && identifier[0] === '@';
  49. }
  50. /**
  51. * URL 파라미터에서 실제 핸들 값만 추출 (`@` 제거).
  52. */
  53. export function normalizeHandle(identifier: string): string {
  54. return stripAtPrefix(identifier);
  55. }
  56. /**
  57. * 큰 수를 축약 표기 (10000 이상 → 'N.N만', 1000 이상 → 'N.NK').
  58. */
  59. export function formatCount(n: number): string {
  60. if (n >= 10000) {
  61. return `${(n / 10000).toFixed(1)}만`;
  62. }
  63. if (n >= 1000) {
  64. return `${(n / 1000).toFixed(1)}K`;
  65. }
  66. return n.toString();
  67. }