useYoutubeVideo.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { ref, reactive } from "vue";
  2. import Toast from "toasters";
  3. import { useWebsocketsStore } from "@/stores/websockets";
  4. type YoutubeVideo = {
  5. _id: string;
  6. youtubeId: string;
  7. title: string;
  8. author: string;
  9. duration: number;
  10. documentVersion: number;
  11. createdAt: Date;
  12. rawData: {
  13. kind: "youtube#video";
  14. etag: string;
  15. id: string;
  16. snippet: {
  17. publishedAt: string;
  18. channelId: string;
  19. title: string;
  20. description: string;
  21. thumbnails: {
  22. default: {
  23. url: string;
  24. width: number;
  25. height: number;
  26. };
  27. medium: {
  28. url: string;
  29. width: number;
  30. height: number;
  31. };
  32. high: {
  33. url: string;
  34. width: number;
  35. height: number;
  36. };
  37. standard: {
  38. url: string;
  39. width: number;
  40. height: number;
  41. };
  42. maxres: {
  43. url: string;
  44. width: number;
  45. height: number;
  46. };
  47. };
  48. channelTitle: string;
  49. tags: string[];
  50. categoryId: string;
  51. liveBroadcastContent: string;
  52. localized: {
  53. title: string;
  54. description: string;
  55. };
  56. };
  57. contentDetails: {
  58. duration: string;
  59. dimension: string;
  60. definition: string;
  61. caption: string;
  62. licensedContent: boolean;
  63. regionRestriction: {
  64. allowed: string[];
  65. };
  66. contentRating: object;
  67. projection: string;
  68. };
  69. status: {
  70. uploadStatus: string;
  71. privacyStatus: string;
  72. license: string;
  73. embeddable: true;
  74. publicStatsViewable: true;
  75. madeForKids: false;
  76. };
  77. statistics: {
  78. viewCount: string;
  79. likeCount: string;
  80. favoriteCount: string;
  81. commentCount: string;
  82. };
  83. };
  84. updatedAt: Date;
  85. uploadedAt: Date;
  86. };
  87. const youtubeVideoIDRegex = /^([\w-]{11})$/;
  88. export const useYoutubeVideo = () => {
  89. const youtubeVideoURLOrID = ref("");
  90. const youtubeVideos = reactive<YoutubeVideo[]>([]);
  91. const { socket } = useWebsocketsStore();
  92. const selectYoutubeVideo = () => {
  93. const youtubeVideoURLOrIDTrimmed = youtubeVideoURLOrID.value.trim();
  94. if (youtubeVideoURLOrIDTrimmed.length === 0)
  95. return new Toast(
  96. "No YouTube video ID found in the supplied value."
  97. );
  98. const youtubeVideoIDRegexResult = youtubeVideoIDRegex.exec(
  99. youtubeVideoURLOrIDTrimmed
  100. );
  101. if (!youtubeVideoIDRegexResult)
  102. return new Toast(
  103. "No YouTube video ID found in the supplied value."
  104. );
  105. return socket.dispatch(
  106. "youtube.getVideo",
  107. youtubeVideoIDRegexResult.groups.youtubeVideoID,
  108. res => {
  109. if (res.status === "success") {
  110. const { data } = res;
  111. if (
  112. !youtubeVideos.find(
  113. youtubeVideo =>
  114. youtubeVideo.youtubeId === data.youtubeId
  115. )
  116. )
  117. youtubeVideos.push(data);
  118. youtubeVideoURLOrID.value = "";
  119. } else if (res.status === "error") new Toast(res.message);
  120. }
  121. );
  122. };
  123. return {
  124. youtubeVideoURLOrID,
  125. youtubeVideos,
  126. selectYoutubeVideo
  127. };
  128. };