diff --git a/frontend/src/App.js b/frontend/src/App.js index 213787ca..3d505c55 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -12,6 +12,7 @@ import Payments from './components/Payments' import Peers from './components/Peers' import Feed from './components/Feed' import Search from './components/Search' +import Twitter from './components/Twitter' import Notifications from './components/Notifications' import Alerts from './components/Alerts' @@ -50,6 +51,9 @@ const DefaultContainer = withRouter(({ history }) => { + + + diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js index 38950158..0fdf1186 100644 --- a/frontend/src/api/client.js +++ b/frontend/src/api/client.js @@ -744,3 +744,40 @@ export const downloadSqueak = (squeakHash) => { deser: deser, }); } + +export const getTwitterAccounts = () => { + console.log('Calling getTwitterAccounts'); + const request = new GetTwitterAccountsRequest(); + const deser = GetTwitterAccountsReply.deserializeBinary; + return baseRequest({ + url: '/gettwitteraccounts', + req: request, + deser: deser, + }); +} + +export const createTwitterAccount = (twitterHandle, profileId, bearerToken) => { + console.log('Calling createTwitterAccount'); + const request = new AddTwitterAccountRequest(); + request.setHandle(twitterHandle); + request.setProfileId(profileId); + request.setBearerToken(bearerToken); + const deser = AddTwitterAccountReply.deserializeBinary; + return baseRequest({ + url: '/addtwitteraccount', + req: request, + deser: deser, + }); +} + +export const deleteTwitterAccount = (twitterAccountId) => { + console.log('Calling deleteTwitterAccount'); + const request = new DeleteTwitterAccountRequest(); + request.setTwitterAccountId(twitterAccountId); + const deser = DeleteTwitterAccountReply.deserializeBinary; + return baseRequest({ + url: '/deletetwitteraccount', + req: request, + deser: deser, + }); +} diff --git a/frontend/src/components/Twitter/index.js b/frontend/src/components/Twitter/index.js new file mode 100644 index 00000000..8abbb5ae --- /dev/null +++ b/frontend/src/components/Twitter/index.js @@ -0,0 +1,175 @@ +import React, { useEffect, useState, useContext } from 'react' +import './style.scss' +import { withRouter, Link } from 'react-router-dom' +import { ICON_SEARCH, ICON_ARROWBACK, ICON_CLOSE } from '../../Icons' +import { getProfileImageSrcString } from '../../squeakimages/images'; +import Loader from '../Loader' +import SqueakCard from '../SqueakCard' +import Select from 'react-select' + + +import { unwrapResult } from '@reduxjs/toolkit' +import { useDispatch } from 'react-redux' +import { useSelector } from 'react-redux' + +import TwitterAccounts from '../../features/twitterAccounts/TwitterAccounts' +import { + setCreateSigningProfile, +} from '../../features/profiles/profilesSlice' + +import { + setCreateTwitterAccount, +} from '../../features/twitterAccounts/twitterAccountsSlice' + +import { + selectSigningProfiles, + fetchSigningProfiles, +} from '../../features/profiles/profilesSlice' + + +const Twitter = (props) => { + const [tab, setTab] = useState('Signing Profiles') + const [twitterAccountModalOpen, setTwitterAccountModalOpen] = useState(false) + const [styleBody, setStyleBody] = useState(false) + const [twitterHandle, setTwitterHandle] = useState('') + const [newProfilePubkey, setNewProfilePubkey] = useState('') + const [bearerToken, setBearerToken] = useState('') + const [signingProfile, setSigningProfile] = useState(null) + + const signingProfiles = useSelector(selectSigningProfiles); + + const dispatch = useDispatch() + + const searchOnChange = (param) => { + if(tab !== 'Search'){setTab('Search')} + if(param.length>0){ + // TODO: search for a profile by name. + } + } + + const optionsFromProfiles = (profiles) => { + return profiles.map((p) => { + return { value: p, label: p.getProfileName() } + // return { value: 'chocolate', label: 'Chocolate' } + }); + } + + const toggleCreateTwitterAccountModal = (param, type) => { + setStyleBody(!styleBody) + setTimeout(()=>{ setTwitterAccountModalOpen(!twitterAccountModalOpen) },20) + } + + const createTwitterAccount = () => { + console.log('Create twitter account with handle:', twitterHandle); + if (!signingProfile) { + alert('Signing profile must be set.'); + return; + } + dispatch(setCreateTwitterAccount({ + twitterHandle: twitterHandle, + profileId: signingProfile.getProfileId(), + bearerToken: bearerToken, + })) + .then(unwrapResult) + .then((pubkey) => { + console.log('Created twitter account with handle', twitterHandle); + }) + .catch((err) => { + alert(err.message); + }); + toggleCreateTwitterAccountModal(); + } + + const handleModalClick = (e) => { + e.stopPropagation() + } + + const handleChangeSigningProfile = (e) => { + setSigningProfile(e.value); + } + + + return( +
+ +
+
+
+
+ +
+
+ searchOnChange(e.target.value)} placeholder="Search for people" type="text" name="search"/> +
+
+
+
+
+
toggleCreateTwitterAccountModal('edit')} + className='profiles-create-button'> + Add Twitter Account +
+
+
+
+
+
setTab('Signing Profiles')} className={tab === 'Signing Profiles' ? `explore-nav-item activeTab` : `explore-nav-item`}> + Twitter Accounts +
+
+ +
+
+ + + {/* Modal for create signing profile */} +
toggleCreateTwitterAccountModal()} style={{display: twitterAccountModalOpen ? 'block' : 'none'}} className="modal-edit"> +
handleModalClick(e)} className="modal-content"> +
+
+
toggleCreateTwitterAccountModal()} className="modal-closeIcon-wrap"> + +
+
+

Add Twitter Account

+ +
+
+ Submit +
+
+
+ +
+
+
+
+ + setTwitterHandle(e.target.value)} type="text" name="name" className="edit-input"/> +
+
+
+
+ + setBearerToken(e.target.value)} type="text" name="name" className="edit-input"/> +
+
+
+
+ +
+