Combine contact profiles and signing profiles (#1078)

* Include key icon in profile list item when signing profile

* Fix event propagation in avatar click

* Show contact and signing profiles in same list

* Update frontend build
This commit is contained in:
Jonathan Zernik 2021-08-27 18:11:58 -07:00 committed by GitHub
parent 2fabdd87df
commit 7058fb074d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 103 additions and 65 deletions

View file

@ -2,11 +2,13 @@ import React from "react";
import {useHistory} from "react-router-dom";
import Card from '@material-ui/core/Card';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';
import CardHeader from "@material-ui/core/CardHeader";
// icons
import RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';
import VpnKeyIcon from '@material-ui/icons/VpnKey';
import useStyles from "../../pages/wallet/styles";
import SqueakUserAvatar from "../../components/SqueakUserAvatar";
@ -57,6 +59,22 @@ export default function ProfileListItem({
// return pieces[1];
// }
const name = profile.getProfileName();
const address = profile.getAddress();
function ProfileCardContent() {
return (
<>
<Box>
{profile.getHasPrivateKey() && <VpnKeyIcon />}
</Box>
<Box>
{`Address: ${address}`}
</Box>
</>
)
}
return (
<Card
className={classes.root}
@ -66,8 +84,8 @@ export default function ProfileListItem({
avatar={<SqueakUserAvatar
squeakProfile={profile}
/>}
title={`Name: ${profile.getProfileName()}`}
subheader={`Address: ${profile.getAddress()}`}
title={`Name: ${name}`}
subheader={ProfileCardContent()}
// action={<Button size="small">View Peer</Button>}
/>
</Card>

View file

@ -22,11 +22,14 @@ export default function SqueakUserAvatar({
}) {
const history = useHistory();
const handleAvatarClick = () => {
const onAvatarClick = (event) => {
event.preventDefault();
event.stopPropagation();
console.log("Handling avatar click...");
if (squeakProfile) {
goToSqueakAddressPage(history, squeakProfile.getAddress());
}
};
}
function AvatarImage() {
return (
@ -36,7 +39,7 @@ export default function SqueakUserAvatar({
return (
<TimelineDot
onClick={handleAvatarClick}
onClick={onAvatarClick}
style={{cursor: 'pointer'}}
>
{squeakProfile ?

View file

@ -29,8 +29,7 @@ import ProfileListItem from "../../components/ProfileListItem";
import mock from "../dashboard/mock";
import {
getSigningProfilesRequest,
getContactProfilesRequest,
getProfilesRequest,
} from "../../squeakclient/requests"
import {
goToProfilePage,
@ -47,8 +46,7 @@ const useStyles = makeStyles((theme) => ({
export default function Profiles() {
const classes = useStyles();
const [signingProfiles, setSigningProfiles] = useState([]);
const [contactProfiles, setContactProfiles] = useState([]);
const [profiles, setProfiles] = useState([]);
const [createSigningProfileDialogOpen, setCreateSigningProfileDialogOpen] = useState(false);
const [importSigningProfileDialogOpen, setImportSigningProfileDialogOpen] = useState(false);
const [createContactProfileDialogOpen, setCreateContactProfileDialogOpen] = useState(false);
@ -66,11 +64,8 @@ export default function Profiles() {
setValue(newValue);
};
const loadSigningProfiles = () => {
getSigningProfilesRequest(setSigningProfiles);
};
const loadContactProfiles = () => {
getContactProfilesRequest(setContactProfiles);
const loadProfiles = () => {
getProfilesRequest(setProfiles);
};
const handleClickOpenCreateSigningProfileDialog = () => {
@ -98,10 +93,7 @@ export default function Profiles() {
};
useEffect(() => {
loadSigningProfiles()
}, []);
useEffect(() => {
loadContactProfiles()
loadProfiles();
}, []);
function TabPanel(props) {
@ -127,21 +119,17 @@ export default function Profiles() {
<>
<AppBar position="static" color="default">
<Tabs value={value} onChange={handleChange} aria-label="simple tabs example">
<Tab label="Signing Profiles" {...a11yProps(0)} />
<Tab label="Contact Profiles" {...a11yProps(1)} />
<Tab label="Profiles" {...a11yProps(0)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0}>
{SigningProfilesContent()}
</TabPanel>
<TabPanel value={value} index={1}>
{ContactProfilesContent()}
{ProfilesContent()}
</TabPanel>
</>
)
}
function SigningProfilesContent() {
function ProfilesContent() {
return (
<>
<Grid container spacing={4}>
@ -149,7 +137,8 @@ export default function Profiles() {
<Widget disableWidgetMenu>
{CreateSigningProfileButton()}
{ImportSigningProfileButton()}
{ProfilesGridItem(signingProfiles)}
{CreateContactProfileButton()}
{ProfilesGridItem(profiles)}
</Widget>
</Grid>
</Grid>
@ -176,21 +165,6 @@ export default function Profiles() {
)
}
function ContactProfilesContent() {
return (
<>
<Grid container spacing={4}>
<Grid item xs={12}>
<Widget disableWidgetMenu>
{CreateContactProfileButton()}
{ProfilesGridItem(contactProfiles)}
</Widget>
</Grid>
</Grid>
</>
)
}
function CreateSigningProfileButton() {
return (
<>

View file

@ -36,6 +36,7 @@ import {
GetPeerRequest,
SetPeerAutoconnectRequest,
GetSigningProfilesRequest,
GetProfilesRequest,
GetContactProfilesRequest,
MakeSqueakRequest,
GetSqueakDisplayRequest,
@ -349,6 +350,13 @@ export function setPeerAutoconnectRequest(id, autoconnect, handleResponse) {
});
}
export function getProfilesRequest(handleResponse) {
var request = new GetProfilesRequest();
client.getProfiles(request, {}, (err, response) => {
handleResponse(response.getSqueakProfilesList());
});
}
export function getSigningProfilesRequest(handleResponse) {
var request = new GetSigningProfilesRequest();
client.getSigningProfiles(request, {}, (err, response) => {

View file

@ -76,6 +76,10 @@ service SqueakAdmin {
*/
rpc ImportSigningProfile (ImportSigningProfileRequest) returns (ImportSigningProfileReply) {}
/** sqkadmin: `getprofiles`
*/
rpc GetProfiles (GetProfilesRequest) returns (GetProfilesReply) {}
/** sqkadmin: `getsigningprofiles`
*/
rpc GetSigningProfiles (GetSigningProfilesRequest) returns (GetSigningProfilesReply) {}
@ -306,6 +310,14 @@ message CreateContactProfileReply {
int32 profile_id = 1;
}
message GetProfilesRequest {
}
message GetProfilesReply {
/// The squeak profiles
repeated SqueakProfile squeak_profiles = 1;
}
message GetSigningProfilesRequest {
}

View file

@ -123,6 +123,14 @@ class SqueakAdminServerHandler(object):
profile_id=profile_id,
)
def handle_get_profiles(self, request):
logger.info("Handle get profiles.")
profiles = self.squeak_controller.get_profiles()
logger.info("Got number of profiles: {}".format(len(profiles)))
profile_msgs = [squeak_profile_to_message(
profile) for profile in profiles]
return squeak_admin_pb2.GetProfilesReply(squeak_profiles=profile_msgs)
def handle_get_signing_profiles(self, request):
logger.info("Handle get signing profiles.")
profiles = self.squeak_controller.get_signing_profiles()

View file

@ -81,6 +81,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
def CreateContactProfile(self, request, context):
return self.handler.handle_create_contact_profile(request)
def GetProfiles(self, request, context):
return self.handler.handle_get_profiles(request)
def GetSigningProfiles(self, request, context):
return self.handler.handle_get_signing_profiles(request)

View file

@ -1,17 +1,17 @@
{
"files": {
"main.js": "/static/js/main.d4b4f12c.chunk.js",
"main.js.map": "/static/js/main.d4b4f12c.chunk.js.map",
"main.js": "/static/js/main.317b6c9d.chunk.js",
"main.js.map": "/static/js/main.317b6c9d.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.9f0ba400.js",
"runtime-main.js.map": "/static/js/runtime-main.9f0ba400.js.map",
"static/css/2.ea4ba2f0.chunk.css": "/static/css/2.ea4ba2f0.chunk.css",
"static/js/2.b9c300d2.chunk.js": "/static/js/2.b9c300d2.chunk.js",
"static/js/2.b9c300d2.chunk.js.map": "/static/js/2.b9c300d2.chunk.js.map",
"static/js/2.248267c1.chunk.js": "/static/js/2.248267c1.chunk.js",
"static/js/2.248267c1.chunk.js.map": "/static/js/2.248267c1.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.ee0732b6174e80bd6e6324ed8fc3545d.js": "/precache-manifest.ee0732b6174e80bd6e6324ed8fc3545d.js",
"precache-manifest.e78d06cb584521fc0bad25ae80bb588a.js": "/precache-manifest.e78d06cb584521fc0bad25ae80bb588a.js",
"service-worker.js": "/service-worker.js",
"static/css/2.ea4ba2f0.chunk.css.map": "/static/css/2.ea4ba2f0.chunk.css.map",
"static/js/2.b9c300d2.chunk.js.LICENSE.txt": "/static/js/2.b9c300d2.chunk.js.LICENSE.txt",
"static/js/2.248267c1.chunk.js.LICENSE.txt": "/static/js/2.248267c1.chunk.js.LICENSE.txt",
"static/media/font-awesome.min.css": "/static/media/fontawesome-webfont.fee66e71.woff",
"static/media/google.svg": "/static/media/google.695a3160.svg",
"static/media/logo.svg": "/static/media/logo.a0185b04.svg"
@ -19,7 +19,7 @@
"entrypoints": [
"static/js/runtime-main.9f0ba400.js",
"static/css/2.ea4ba2f0.chunk.css",
"static/js/2.b9c300d2.chunk.js",
"static/js/main.d4b4f12c.chunk.js"
"static/js/2.248267c1.chunk.js",
"static/js/main.317b6c9d.chunk.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.b9c300d2.chunk.js"></script><script src="/static/js/main.d4b4f12c.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.248267c1.chunk.js"></script><script src="/static/js/main.317b6c9d.chunk.js"></script></body></html>

View file

@ -1,23 +1,23 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "b5000d404a4fcd12b585855011b5f1aa",
"revision": "0d83b2c3039dc9f8cf54f4ebb614a5bc",
"url": "/index.html"
},
{
"revision": "f23bb3a596c7a4e008d8",
"revision": "cd160927f2499f9d5606",
"url": "/static/css/2.ea4ba2f0.chunk.css"
},
{
"revision": "f23bb3a596c7a4e008d8",
"url": "/static/js/2.b9c300d2.chunk.js"
"revision": "cd160927f2499f9d5606",
"url": "/static/js/2.248267c1.chunk.js"
},
{
"revision": "7156b2c9571000777b9be03b3c6006ee",
"url": "/static/js/2.b9c300d2.chunk.js.LICENSE.txt"
"url": "/static/js/2.248267c1.chunk.js.LICENSE.txt"
},
{
"revision": "4559792f9d9c64006e72",
"url": "/static/js/main.d4b4f12c.chunk.js"
"revision": "e6d01ab27976f255c68e",
"url": "/static/js/main.317b6c9d.chunk.js"
},
{
"revision": "cc9816de5a8639d377ea",

View file

@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.ee0732b6174e80bd6e6324ed8fc3545d.js"
"/precache-manifest.e78d06cb584521fc0bad25ae80bb588a.js"
);
self.addEventListener('message', (event) => {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -556,6 +556,15 @@ class SqueakDb:
profile_id = res.inserted_primary_key[0]
return profile_id
def get_profiles(self) -> List[SqueakProfile]:
""" Get all profiles. """
s = select([self.profiles])
with self.get_connection() as connection:
result = connection.execute(s)
rows = result.fetchall()
profiles = [self._parse_squeak_profile(row) for row in rows]
return profiles
def get_signing_profiles(self) -> List[SqueakProfile]:
""" Get all signing profiles. """
s = select([self.profiles]).where(self.profile_has_private_key)

View file

@ -198,6 +198,9 @@ class SqueakController:
self.update_subscriptions()
return profile_id
def get_profiles(self) -> List[SqueakProfile]:
return self.squeak_db.get_profiles()
def get_signing_profiles(self) -> List[SqueakProfile]:
return self.squeak_db.get_signing_profiles()