VideoFeed.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <script>
  2. import { defineComponent } from 'vue'
  3. import Player from '@/components/Player.vue'
  4. import { config } from '@/main.js'
  5. import { animate, createSpring } from 'animejs'
  6. import Cookies from 'js-cookie'
  7. export default defineComponent({
  8. name: 'VideoFeed',
  9. data() {
  10. return {
  11. player1: null,
  12. player2: null,
  13. config,
  14. animating: false,
  15. feedIndex: 0,
  16. currentPlayer: "player1",
  17. stiffness: 550,
  18. damping: 15,
  19. touchInfo: []
  20. }
  21. },
  22. props: {
  23. feed: {
  24. type: Object,
  25. required: true
  26. }
  27. },
  28. methods: {
  29. scrollDown() {
  30. if(this.animating) return;
  31. if (this.feedIndex >= this.feed.length - 1) {
  32. if(!this.signedIn()) {
  33. alert("SIGN IN to see more EPIC content!!!");
  34. this.animating = false;
  35. return;
  36. }
  37. console.log("Reached end of feed");
  38. this.animating = false;
  39. return;
  40. }
  41. this.animating = true;
  42. const screenHeight = window.innerHeight;
  43. const inactivePlayer = this.currentPlayer === "player1" ? ".player2" : ".player1";
  44. const activePlayer = this.currentPlayer === "player1" ? ".player1" : ".player2";
  45. const nextIndex = this.feedIndex + 1; // calculate this early!
  46. // Move the inactive player down
  47. animate(inactivePlayer, {
  48. translateY: screenHeight,
  49. duration: 0
  50. });
  51. if (this.currentPlayer === "player1") {
  52. this.player2 = this.feed[nextIndex];
  53. } else {
  54. this.player1 = this.feed[nextIndex];
  55. }
  56. // animate players
  57. animate(activePlayer, {
  58. translateY: [0, -screenHeight],
  59. duration: 500,
  60. ease: createSpring({stiffness: this.stiffness, damping: this.damping})
  61. });
  62. animate(inactivePlayer, {
  63. translateY: [screenHeight, 0],
  64. duration: 500,
  65. ease: createSpring({stiffness: this.stiffness, damping: this.damping})
  66. }).then(() => {
  67. const nextPlayer = this.currentPlayer === "player1" ? "player2" : "player1";
  68. this.feedIndex = nextIndex;
  69. this.currentPlayer = nextPlayer;
  70. document.querySelector(activePlayer).querySelector(".video-container").querySelector("video").pause();
  71. document.querySelector(inactivePlayer).querySelector(".video-container").querySelector("video").play();
  72. this.animating = false;
  73. });
  74. },
  75. scrollUp() {
  76. if(this.animating) return;
  77. if (this.feedIndex <= 0) {
  78. console.log("Reached beginning of feed");
  79. this.animating = false;
  80. return;
  81. }
  82. this.animating = true;
  83. const screenHeight = window.innerHeight;
  84. const inactivePlayer = this.currentPlayer === "player1" ? ".player2" : ".player1";
  85. const activePlayer = this.currentPlayer === "player1" ? ".player1" : ".player2";
  86. const nextIndex = this.feedIndex - 1; // calculate this early!
  87. // Move the inactive player up
  88. animate(inactivePlayer, {
  89. translateY: -screenHeight,
  90. duration: 0
  91. });
  92. if (this.currentPlayer === "player1") {
  93. this.player2 = this.feed[nextIndex];
  94. } else {
  95. this.player1 = this.feed[nextIndex];
  96. }
  97. // animate players
  98. animate(activePlayer, {
  99. translateY: [0, screenHeight],
  100. duration: 500,
  101. ease: createSpring({stiffness: this.stiffness, damping: this.damping})
  102. });
  103. animate(inactivePlayer, {
  104. translateY: [-screenHeight, 0],
  105. duration: 500,
  106. ease: createSpring({stiffness: this.stiffness, damping: this.damping})
  107. }).then(() => {
  108. const nextPlayer = this.currentPlayer === "player1" ? "player2" : "player1";
  109. this.feedIndex = nextIndex;
  110. this.currentPlayer = nextPlayer;
  111. document.querySelector(activePlayer).querySelector(".video-container").querySelector("video").pause();
  112. document.querySelector(inactivePlayer).querySelector(".video-container").querySelector("video").play();
  113. this.animating = false;
  114. });
  115. },
  116. handleScroll(event) {
  117. if(this.animating) return;
  118. if(event.deltaY > 0) {
  119. this.scrollDown();
  120. } else {
  121. this.scrollUp();
  122. }
  123. },
  124. signedIn() {
  125. return Cookies.get('token') && Cookies.get('token').startsWith('HajeebToken')
  126. },
  127. handleTouch(event) {
  128. if(this.animating) return;
  129. this.touchInfo.push(event.touches[0].clientY);
  130. if ((this.touchInfo[this.touchInfo.length - 1] - this.touchInfo[0]) > 300) this.scrollUp();
  131. if ((this.touchInfo[0] - this.touchInfo[this.touchInfo.length - 1]) > 300) this.scrollDown();
  132. }
  133. },
  134. created () {
  135. // initial setup for players
  136. this.player1 = this.feed[this.feedIndex];
  137. this.player2 = this.feed[this.feedIndex + 1];
  138. document.addEventListener("wheel", this.handleScroll);
  139. document.addEventListener("touchmove", this.handleTouch);
  140. document.addEventListener("touchstart", (event) => {
  141. this.touchInfo = [];
  142. this.touchInfo.push(event.touches[0].clientY);
  143. });
  144. document.addEventListener("touchend", (event) => {
  145. this.touchInfo = [];
  146. });
  147. },
  148. mounted () {
  149. console.log("peepee")
  150. animate(".player2", {
  151. translateY: -window.innerHeight,
  152. duration: 0
  153. })
  154. },
  155. components: { Player },
  156. })
  157. </script>
  158. <template>
  159. <div id="player-container">
  160. <Player
  161. class-name="player1"
  162. :video="player1?.id ?? 1"
  163. :key="player1?.id ?? 1"
  164. :information="{
  165. title: player1?.title ?? '',
  166. description: player1?.description ?? '',
  167. likes: player1?.likes ?? 13242,
  168. dislikes: player1?.dislikes ?? 13242,
  169. comments: player1?.comments ?? 13242,
  170. shares: player1?.shares ?? 13242,
  171. author: {
  172. username: player1?.author?.username ?? 'johnclapper',
  173. verified: player1?.author?.verified ?? false,
  174. id: player1?.author?.id ?? 1,
  175. }
  176. }"
  177. />
  178. <Player
  179. class-name="player2"
  180. :video="player2?.id ?? 1"
  181. :key="player2?.id ?? 1"
  182. :information="{
  183. title: player2?.title ?? '',
  184. description: player2?.description ?? '',
  185. likes: player2?.likes ?? 13242,
  186. dislikes: player2?.dislikes ?? 13242,
  187. comments: player2?.comments ?? 13242,
  188. shares: player2?.shares ?? 13242,
  189. author: {
  190. username: player2?.author?.username ?? 'johnclapper',
  191. verified: player2?.author?.verified ?? false,
  192. id: player2?.author?.id ?? 1,
  193. }
  194. }"
  195. />
  196. </div>
  197. </template>
  198. <style scoped>
  199. #player-container
  200. {
  201. flex-grow: 1;
  202. display: flex;
  203. justify-content: center;
  204. }
  205. .player1 {
  206. position: absolute;
  207. }
  208. .player2 {
  209. position: absolute;
  210. }
  211. </style>