Merge pull request #2410 from urbit/mp/os1/invite-launch

launch: subscribe to invite-view, show group invite count in tile
This commit is contained in:
ixv 2020-03-10 12:17:34 -07:00 committed by GitHub
commit 9d0fe998c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 159 additions and 13 deletions

View File

@ -119,7 +119,7 @@ export class NewScreen extends Component {
"focus-b--black focus-b--white-d"
}
rows={1}
placeholder="Two trumpeteers and a microphone"
placeholder="Two trumpeters and a microphone"
style={{
resize: "none",
height: 48,

View File

@ -8,13 +8,36 @@ export default class ContactTile extends Component {
render() {
const { props } = this;
let data = _.get(props.data, "invites", false);
let inviteNum = 0;
if (data && "/contacts" in data) {
inviteNum = Object.keys(data["/contacts"]).length;
}
let numNotificationsElem =
inviteNum > 0 ? (
<p
className="absolute green2 white-d"
style={{
bottom: 6,
fontWeight: 400,
fontSize: 12,
lineHeight: "20px"
}}>
{inviteNum > 99 ? "99+" : inviteNum}
</p>
) : (
<div />
);
return (
<div className={"w-100 h-100 relative bg-white bg-gray0-d " +
"b--black b--gray1-d ba"}>
<div
className={
"w-100 h-100 relative bg-white bg-gray0-d " + "b--black b--gray1-d ba"
}>
<a className="w-100 h-100 db pa2 bn" href="/~groups">
<p
className="black white-d absolute f9"
style={{ left: 8, top: 8 }}>
<p className="black white-d absolute f9" style={{ left: 8, top: 8 }}>
Groups
</p>
<img
@ -24,6 +47,7 @@ export default class ContactTile extends Component {
width={48}
height={48}
/>
{numNotificationsElem}
</a>
</div>
);

View File

@ -1,8 +1,50 @@
import React, { Component } from 'react';
import { Sigil } from './sigil';
import _ from 'lodash';
export default class Header extends Component {
render() {
let data = _.get(this.props.data, "invites", false);
let inviteNum = 0;
if (data && "/contacts" in data) {
inviteNum = Object.keys(data["/contacts"]).length;
}
let numNotificationsElem =
inviteNum > 0 ? (
<a href="/~groups">
<p
className="absolute ph1 br2 ba b--gray2 green2 white-d f9 lh-solid"
title={"Invitations to new groups"}
style={{
bottom: "-2",
fontWeight: 600,
fontSize: "8pt",
padding: "0.15rem 0.4rem",
right: 64
}}>
{inviteNum > 99 ? "99+" : inviteNum}
</p>
</a>
) : (
<a href="/~groups">
<p
className="absolute ph1 br2 ba b--gray2 gray2 white-d f9 lh-solid"
title={"No new invitations to new groups"}
style={{
bottom: "-2",
fontWeight: 600,
fontSize: "8pt",
padding: "0.15rem 0.4rem",
right: 64
}}>
0
</p>
</a>
);
return (
<header
className="bg-white bg-gray0-d w-100 justify-between relative tc pt3"
@ -16,6 +58,7 @@ export default class Header extends Component {
Home
</span>
<div className="absolute right-1 lh-copy" style={{ top: 12 }}>
{numNotificationsElem}
<Sigil
ship={"~" + window.ship}
size={16} color={"#000000"}

View File

@ -17,14 +17,25 @@ export default class Home extends Component {
render() {
let keys = [...this.props.keys];
let tileElems = keys.map((tile) => {
return (
<Tile key={tile} type={tile} data={this.props.data[tile]} />
);
let tileData = {};
if (tile in this.props.data && tile !== "invites") {
tileData = this.props.data[tile] !== null
? this.props.data[tile] : {};
tileData["invites"] = ("invites" in this.props.data)
? this.props.data["invites"] : {};
}
return <Tile key={tile} type={tile} data={tileData} />;
});
let headerData = {};
if ("invites" in this.props.data) {
headerData["invites"] = this.props.data["invites"];
}
return (
<div className="fl w-100 h-100 bg-white bg-gray0-d center">
<Header />
<Header data={headerData}/>
<div className={"v-mid pa2 dtc-m dtc-l dtc-xl " +
"flex justify-between flex-wrap"}
style={{maxWidth: "40rem"}}>

View File

@ -0,0 +1,55 @@
import _ from 'lodash';
export class InviteReducer {
reduce(json, state) {
let data = _.get(json, "invite-initial", false);
if (data) {
state.invites = data;
}
data = _.get(json, "invite-update", false);
if (data) {
this.create(data, state);
this.delete(data, state);
this.invite(data, state);
this.accepted(data, state);
this.decline(data, state);
}
}
create(json, state) {
let data = _.get(json, "create", false);
if (data) {
state.invites[data.path] = {};
}
}
delete(json, state) {
let data = _.get(json, "delete", false);
if (data) {
delete state.invites[data.path];
}
}
invite(json, state) {
let data = _.get(json, "invite", false);
if (data) {
state.invites[data.path][data.uid] = data.invite;
}
}
accepted(json, state) {
let data = _.get(json, "accepted", false);
if (data) {
console.log(data);
delete state.invites[data.path][data.uid];
}
}
decline(json, state) {
let data = _.get(json, "decline", false);
if (data) {
delete state.invites[data.path][data.uid];
}
}
}

View File

@ -1,8 +1,12 @@
import { InviteReducer } from '/reducers/invite.js';
class Store {
constructor() {
this.state = {};
this.state = {
invites: {}
};
this.setState = () => {};
this.inviteReducer = new InviteReducer();
}
setStateHandler(setState) {
@ -10,9 +14,14 @@ class Store {
}
handleEvent(data) {
if (("from" in data) && data.from.app === "invite-view") {
this.inviteReducer.reduce(data.data, this.state)
}
else {
let json = data.data;
this.setState(json);
}
this.setState(this.state);
}
}

View File

@ -26,7 +26,11 @@ export class Subscription {
this.handleEvent.bind(this),
this.handleError.bind(this),
ship);
}
api.bind("invite-view", '/primary',
this.handleEvent.bind(this),
this.handleError.bind(this),
ship);
}
handleEvent(diff) {
store.handleEvent(diff);