diff --git a/Gemfile b/Gemfile index fd0e2e8c2..1af9ee447 100644 --- a/Gemfile +++ b/Gemfile @@ -108,7 +108,6 @@ gem "store_attribute", "~> 0.8.1" # ActiveRecord extension which adds typecastin gem "storext", "~> 3.3" # Add type-casting and other features on top of ActiveRecord::Store.store_accessor gem "stripe", "~> 5.30" # Ruby library for the Stripe API gem "strong_migrations", "~> 0.7" # Catch unsafe migrations -gem "twilio-ruby", "~> 5.48" # The official library for communicating with the Twilio REST API gem "twitter", "~> 7.0" # A Ruby interface to the Twitter API gem "uglifier", "~> 4.2" # Uglifier minifies JavaScript files gem "ulid", "~> 1.3" # Universally Unique Lexicographically Sortable Identifier implementation for Ruby diff --git a/Gemfile.lock b/Gemfile.lock index 2251eab6f..94e875db9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -808,10 +808,6 @@ GEM thread_safe (0.3.6) tilt (2.0.10) timecop (0.9.4) - twilio-ruby (5.48.0) - faraday (>= 0.9, < 2.0) - jwt (>= 1.5, <= 2.5) - nokogiri (>= 1.6, < 2.0) twitter (7.0.0) addressable (~> 2.3) buftok (~> 0.2.0) @@ -1028,7 +1024,6 @@ DEPENDENCIES strong_migrations (~> 0.7) test-prof (~> 1.0) timecop (~> 0.9) - twilio-ruby (~> 5.48) twitter (~> 7.0) uglifier (~> 4.2) ulid (~> 1.3) diff --git a/app/controllers/twilio_tokens_controller.rb b/app/controllers/twilio_tokens_controller.rb deleted file mode 100644 index ae6be1e2a..000000000 --- a/app/controllers/twilio_tokens_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -class TwilioTokensController < ApplicationController - after_action :verify_authorized - - def show - video_channel = params[:id].split("private-video-channel-")[1] if params[:id].start_with?("private-video-channel-") - unless video_channel - skip_authorization - render json: { status: "failure", token: @twilio_token }, status: :not_found - return - end - @chat_channel = ChatChannel.find(video_channel.to_i) - authorize @chat_channel # show pundit method for chat_channel_policy works here, should always check though - @twilio_token = Twilio::GetJwtToken.call(current_user, params[:id]) - render json: { status: "success", token: @twilio_token }, status: :ok - end -end diff --git a/app/controllers/video_chats_controller.rb b/app/controllers/video_chats_controller.rb deleted file mode 100644 index fbc5eac27..000000000 --- a/app/controllers/video_chats_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -class VideoChatsController < ApplicationController - before_action :authenticate_user! - after_action :verify_authorized - - def show - @chat_channel = ChatChannel.find(params[:id]) || not_found - authorize @chat_channel - - account_sid = ApplicationConfig["TWILIO_ACCOUNT_SID"] - api_key = ApplicationConfig["TWILIO_VIDEO_API_KEY"] - api_secret = ApplicationConfig["TWILIO_VIDEO_API_SECRET"] - @username = display_username - @video_type = video_type - token = Twilio::JWT::AccessToken.new( - account_sid, - api_key, - api_secret, - [], - identity: @username, - ) - - grant = Twilio::JWT::AccessToken::VideoGrant.new - grant.room = params[:id] - token.add_grant(grant) - - @token = token.to_jwt - end - - private - - def display_username - return "@#{params[:username]}" if params[:username] && Rails.env.development? # simpler solo testing in dev - - "@#{current_user.username}" - end - - def video_type - if @chat_channel.channel_type == "direct" || @chat_channel.chat_channel_memberships.size < 5 - "peer-to-peer" - else - "group" - end - end -end diff --git a/app/javascript/chat/__tests__/VideoContent.test.jsx b/app/javascript/chat/__tests__/VideoContent.test.jsx deleted file mode 100644 index 852499038..000000000 --- a/app/javascript/chat/__tests__/VideoContent.test.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import { h } from 'preact'; -import { axe } from 'jest-axe'; -import { render } from '@testing-library/preact'; -import { VideoContent } from '../videoContent'; - -describe('', () => { - it('should have no a11y violations', async () => { - const { container } = render( - , - ); - const results = await axe(container); - - expect(results).toHaveNoViolations(); - }); - - it('should render in fullscreen', () => { - const { queryByLabelText } = render( - , - ); - - expect(queryByLabelText('Leave fullscreen')).toBeNull(); - expect(queryByLabelText('Fullscreen')).toBeDefined(); - }); - - it('should not render in fullscreen', () => { - const { queryByLabelText } = render( - , - ); - - expect(queryByLabelText('Fullscreen')).toBeNull(); - expect(queryByLabelText('Leave fullscreen')).toBeDefined(); - }); - - it('should trigger video content when clicked', () => { - const onTriggerVideoContent = jest.fn(); - - const { getByTestId } = render( - , - ); - - getByTestId('connect-video').click(); - - expect(onTriggerVideoContent).toHaveBeenCalledTimes(1); - }); - - it('should load the given video', () => { - const onTriggerVideoContent = jest.fn(); - - const { getByTitle } = render( - , - ); - - const videoFrame = getByTitle('Video display'); - - expect(videoFrame.getAttribute('src')).toEqual('/some-video-path'); - }); -}); diff --git a/app/javascript/chat/chat.jsx b/app/javascript/chat/chat.jsx index 9a2c3228f..a083a1879 100644 --- a/app/javascript/chat/chat.jsx +++ b/app/javascript/chat/chat.jsx @@ -36,7 +36,6 @@ import { Compose } from './compose'; import { Message } from './message'; import { ActionMessage } from './actionMessage'; import { Content } from './content'; -import { VideoContent } from './videoContent'; import { DragAndDropZone } from '@utilities/dragAndDrop'; import { dragAndUpload } from '@utilities/dragAndUpload'; import { Button } from '@crayons'; @@ -83,7 +82,6 @@ export class Chat extends Component { notificationsPermission: null, activeContent: {}, fullscreenContent: null, - videoPath: null, expanded: window.innerWidth > NARROW_WIDTH_LIMIT, isMobileDevice: typeof window.orientation !== 'undefined', subscribedPusherChannels: [], @@ -715,14 +713,6 @@ export class Chat extends Component { // should check if user has the privilege if (message.startsWith('/code')) { this.setActiveContentState(activeChannelId, { type_of: 'code_editor' }); - } else if (message.startsWith('/call')) { - const messageObject = { - activeChannelId, - message: '/call', - mentionedUsersId: this.getMentionedUsers(message), - }; - this.setState({ videoPath: `/video_chats/${activeChannelId}` }); - sendMessage(messageObject, this.handleSuccess, this.handleFailure); } else if (message.startsWith('/play ')) { const messageObject = { activeChannelId, @@ -1008,17 +998,6 @@ export class Chat extends Component { path: `/chat_channel_memberships/${activeChannel.id}/edit`, type_of: 'article', }); - } else if (content.startsWith('sidecar-content-plus-video')) { - this.setActiveContentState(activeChannelId, { - type_of: 'loading-post', - }); - this.setActiveContent({ - path: target.href || target.parentElement.href, - type_of: 'article', - }); - this.setState({ videoPath: `/video_chats/${activeChannelId}` }); - } else if (content.startsWith('sidecar-video')) { - this.setState({ videoPath: target.href || target.parentElement.href }); } else if ( content.startsWith('sidecar') || content.startsWith('article') @@ -1596,11 +1575,6 @@ export class Chat extends Component { fullscreen={state.fullscreenContent === 'sidecar'} closeReportAbuseForm={this.closeReportAbuseForm} /> - ); }; @@ -1626,23 +1600,6 @@ export class Chat extends Component { } }; - onTriggerVideoContent = (e) => { - if (e.target.dataset.content === 'exit') { - this.setState({ - videoPath: null, - fullscreenContent: null, - expanded: window.innerWidth > 600, - }); - } else if (this.state.fullscreenContent === 'video') { - this.setState({ fullscreenContent: null }); - } else { - this.setState({ - fullscreenContent: 'video', - expanded: window.innerWidth > WIDE_WIDTH_LIMIT, - }); - } - }; - handleMention = (e) => { const { activeChannel } = this.state; const mention = e.keyCode === 64; @@ -2010,12 +1967,10 @@ export class Chat extends Component { data-testid="chat" className={`chat chat--expanded chat--${ - state.videoPath ? 'video-visible' : 'video-not-visible' - } chat--${ - state.activeContent[state.activeChannelId] - ? 'content-visible' - : 'content-not-visible' - } ${fullscreenMode}`} + state.activeContent[state.activeChannelId] + ? 'content-visible' + : 'content-not-visible' + } ${fullscreenMode}`} data-no-instant aria-expanded={state.expanded} > diff --git a/app/javascript/chat/content.jsx b/app/javascript/chat/content.jsx index 6359618d1..f69db256c 100644 --- a/app/javascript/chat/content.jsx +++ b/app/javascript/chat/content.jsx @@ -14,7 +14,7 @@ const smartSvgIcon = (content, d) => ( viewBox="0 0 24 24" width="24" height="24" - style={{ marginLeft:'-12px', marginTop:'-4px' }} + style={{ marginLeft: '-12px', marginTop: '-4px' }} > @@ -75,7 +75,7 @@ export class Content extends Component { type="button" className="activechatchannel__activecontentexitbutton activechatchannel__activecontentexitbutton--fullscreen crayons-btn crayons-btn--secondary" data-content="fullscreen" - style={{ left: "-80px", marginLeft: "0px" }} + style={{ left: '-80px', marginLeft: '0px' }} title="fullscreen" > {' '} diff --git a/app/javascript/chat/videoContent.jsx b/app/javascript/chat/videoContent.jsx deleted file mode 100644 index ea32464bc..000000000 --- a/app/javascript/chat/videoContent.jsx +++ /dev/null @@ -1,70 +0,0 @@ -import { h } from 'preact'; - -const smartSvgIcon = (content, d) => ( - - - - -); - -/** - * Displays video in Connect. - * - * @param {string} props.videoPath The URL of a video - * @param {function} props.onTriggerVideoContent Fires when a video is clicked on - * @param {boolean} props.fullscreen Whether or not to show the video in fullscreen - * - * @returns A video component - */ -export function VideoContent(props) { - const { videoPath, onTriggerVideoContent, fullscreen } = props; - - if (!videoPath) { - return null; - } - - return ( -