From c3930b8fe080bd52844ad03c7966dcdec4b054da Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Mon, 28 Mar 2022 00:06:09 -0700 Subject: [PATCH] Add twitter forwarder frontend (#2038) * Got basic add twitter forwarder account working * Got delete twitter account working * Link to profile page from twitter account card * Simplify text for delete twitter account button * Update frontend build --- frontend/src/App.js | 4 + frontend/src/api/client.js | 37 +++ frontend/src/components/Twitter/index.js | 175 ++++++++++ frontend/src/components/Twitter/style.scss | 298 ++++++++++++++++++ .../twitterAccounts/TwitterAccountCard.js | 98 ++++++ .../twitterAccounts/TwitterAccounts.js | 40 +++ .../twitterAccounts/twitterAccountsSlice.js | 120 +++++++ frontend/src/store.js | 2 + .../webapp/static/build/asset-manifest.json | 40 +-- .../admin/webapp/static/build/index.html | 2 +- ...nifest.870a9e1208d76edf8f15550442969c46.js | 54 ++++ ...nifest.cfb9b2fbb1308e3b0f1e4d95184e56a0.js | 54 ---- .../webapp/static/build/service-worker.js | 2 +- ...da16.chunk.css => main.6b2fbaff.chunk.css} | 4 +- .../static/css/main.6b2fbaff.chunk.css.map | 1 + .../static/css/main.af20da16.chunk.css.map | 1 - .../build/static/js/2.9336a0d0.chunk.js | 3 + ...SE.txt => 2.9336a0d0.chunk.js.LICENSE.txt} | 0 .../build/static/js/2.9336a0d0.chunk.js.map | 1 + .../build/static/js/2.efd8ed9d.chunk.js | 3 - .../build/static/js/2.efd8ed9d.chunk.js.map | 1 - ....92446fb0.chunk.js => 3.79deefcb.chunk.js} | 4 +- ...0.chunk.js.map => 3.79deefcb.chunk.js.map} | 2 +- ....ab2b1a69.chunk.js => 4.ea7fc71b.chunk.js} | 4 +- ...9.chunk.js.map => 4.ea7fc71b.chunk.js.map} | 2 +- ....0a538691.chunk.js => 5.a9bd75b8.chunk.js} | 4 +- ...1.chunk.js.map => 5.a9bd75b8.chunk.js.map} | 2 +- .../build/static/js/main.1709487d.chunk.js | 2 + .../static/js/main.1709487d.chunk.js.map | 1 + .../build/static/js/main.43e8a892.chunk.js | 2 - .../static/js/main.43e8a892.chunk.js.map | 1 - ...n.c2d88949.js => runtime-main.cf643d5e.js} | 4 +- ...49.js.map => runtime-main.cf643d5e.js.map} | 2 +- 33 files changed, 872 insertions(+), 98 deletions(-) create mode 100644 frontend/src/components/Twitter/index.js create mode 100644 frontend/src/components/Twitter/style.scss create mode 100644 frontend/src/features/twitterAccounts/TwitterAccountCard.js create mode 100644 frontend/src/features/twitterAccounts/TwitterAccounts.js create mode 100644 frontend/src/features/twitterAccounts/twitterAccountsSlice.js create mode 100644 squeaknode/admin/webapp/static/build/precache-manifest.870a9e1208d76edf8f15550442969c46.js delete mode 100644 squeaknode/admin/webapp/static/build/precache-manifest.cfb9b2fbb1308e3b0f1e4d95184e56a0.js rename squeaknode/admin/webapp/static/build/static/css/{main.af20da16.chunk.css => main.6b2fbaff.chunk.css} (73%) create mode 100644 squeaknode/admin/webapp/static/build/static/css/main.6b2fbaff.chunk.css.map delete mode 100644 squeaknode/admin/webapp/static/build/static/css/main.af20da16.chunk.css.map create mode 100644 squeaknode/admin/webapp/static/build/static/js/2.9336a0d0.chunk.js rename squeaknode/admin/webapp/static/build/static/js/{2.efd8ed9d.chunk.js.LICENSE.txt => 2.9336a0d0.chunk.js.LICENSE.txt} (100%) create mode 100644 squeaknode/admin/webapp/static/build/static/js/2.9336a0d0.chunk.js.map delete mode 100644 squeaknode/admin/webapp/static/build/static/js/2.efd8ed9d.chunk.js delete mode 100644 squeaknode/admin/webapp/static/build/static/js/2.efd8ed9d.chunk.js.map rename squeaknode/admin/webapp/static/build/static/js/{3.92446fb0.chunk.js => 3.79deefcb.chunk.js} (82%) rename squeaknode/admin/webapp/static/build/static/js/{3.92446fb0.chunk.js.map => 3.79deefcb.chunk.js.map} (97%) rename squeaknode/admin/webapp/static/build/static/js/{4.ab2b1a69.chunk.js => 4.ea7fc71b.chunk.js} (97%) rename squeaknode/admin/webapp/static/build/static/js/{4.ab2b1a69.chunk.js.map => 4.ea7fc71b.chunk.js.map} (99%) rename squeaknode/admin/webapp/static/build/static/js/{5.0a538691.chunk.js => 5.a9bd75b8.chunk.js} (97%) rename squeaknode/admin/webapp/static/build/static/js/{5.0a538691.chunk.js.map => 5.a9bd75b8.chunk.js.map} (99%) create mode 100644 squeaknode/admin/webapp/static/build/static/js/main.1709487d.chunk.js create mode 100644 squeaknode/admin/webapp/static/build/static/js/main.1709487d.chunk.js.map delete mode 100644 squeaknode/admin/webapp/static/build/static/js/main.43e8a892.chunk.js delete mode 100644 squeaknode/admin/webapp/static/build/static/js/main.43e8a892.chunk.js.map rename squeaknode/admin/webapp/static/build/static/js/{runtime-main.c2d88949.js => runtime-main.cf643d5e.js} (65%) rename squeaknode/admin/webapp/static/build/static/js/{runtime-main.c2d88949.js.map => runtime-main.cf643d5e.js.map} (98%) 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"/> +
+
+
+
+ +
+