Merge pull request #2238 from urbit/mp/os1/launch
launch: os1 home screen
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 4.7 KiB |
@ -8,7 +8,17 @@
|
||||
==
|
||||
=, format
|
||||
::
|
||||
|%
|
||||
::
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
$% state-zero
|
||||
==
|
||||
+$ state-zero [%0 data=json]
|
||||
--
|
||||
%+ verb |
|
||||
=| state-zero
|
||||
=* state -
|
||||
^- agent:gall
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
@ -17,7 +27,7 @@
|
||||
++ on-init
|
||||
^- (quip card:agent:gall _this)
|
||||
=/ launcha
|
||||
[%launch-action !>([%clock /tile '/~clock/js/tile.js'])]
|
||||
[%launch-action !>([%clock /clocktile '/~clock/js/tile.js'])]
|
||||
:_ this
|
||||
:~ [%pass / %arvo %e %connect [~ /'~clock'] %clock]
|
||||
[%pass /clock %agent [our.bowl %launch] %poke launcha]
|
||||
@ -39,6 +49,9 @@
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card:agent:gall _this)
|
||||
|^
|
||||
?: ?=(%json mark)
|
||||
(poke-json !<(json vase))
|
||||
?. ?=(%handle-http-request mark)
|
||||
(on-poke:def mark vase)
|
||||
=+ !<([eyre-id=@ta =inbound-request:eyre] vase)
|
||||
@ -60,14 +73,22 @@
|
||||
(js-response:gen tile-js)
|
||||
not-found:gen
|
||||
::
|
||||
++ poke-json
|
||||
|= jon=json
|
||||
^- (quip card:agent:gall _this)
|
||||
=. data.state jon
|
||||
:_ this
|
||||
[%give %fact ~[/clocktile] %json !>(jon)]~
|
||||
--
|
||||
::
|
||||
++ on-watch
|
||||
|= =path
|
||||
^- (quip card:agent:gall _this)
|
||||
?: ?=([%http-response *] path)
|
||||
`this
|
||||
?. =(/tile path)
|
||||
?. =(/clocktile path)
|
||||
(on-watch:def path)
|
||||
[[%give %fact ~ %json !>(*json)]~ this]
|
||||
[[%give %fact ~ %json !>(data.state)]~ this]
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 549 B |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 960 B |
Before Width: | Height: | Size: 897 B |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 593 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 589 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 512 B |
Before Width: | Height: | Size: 521 B |
@ -20,62 +20,35 @@ export default class ChatTile extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
let invSuffix = (inviteNum === 1) ? (
|
||||
<span>Invite</span>
|
||||
) : (
|
||||
<span>Invites</span>
|
||||
);
|
||||
let numInvElem = (inviteNum > 0) ? (
|
||||
<p className="absolute white"
|
||||
style={{
|
||||
top: 180,
|
||||
fontWeight: 600,
|
||||
fontSize: 16,
|
||||
lineHeight: '20px'
|
||||
}}>
|
||||
<span style={{
|
||||
color: '#2AA779'
|
||||
}}>{inviteNum} </span>
|
||||
{invSuffix}
|
||||
</p>
|
||||
) : (
|
||||
<div />
|
||||
);
|
||||
let notificationsNum = inviteNum + msgNum;
|
||||
|
||||
let msgSuffix = (msgNum === 1) ? (
|
||||
<span>New Message</span>
|
||||
) : (
|
||||
<span>New Messages</span>
|
||||
);
|
||||
let numMsgElem = (msgNum > 0) ? (
|
||||
<p className="absolute white"
|
||||
let numNotificationsElem =
|
||||
notificationsNum > 0 ? (
|
||||
<p
|
||||
className="absolute green2"
|
||||
style={{
|
||||
top: 207,
|
||||
fontWeight: 600,
|
||||
fontSize: 16,
|
||||
lineHeight: '20px'
|
||||
bottom: 6,
|
||||
fontWeight: 400,
|
||||
fontSize: 12,
|
||||
lineHeight: "20px"
|
||||
}}>
|
||||
<span style={{
|
||||
color: '#2AA779'
|
||||
}}>{msgNum} </span>
|
||||
{msgSuffix}
|
||||
{notificationsNum > 99 ? "99+" : notificationsNum}
|
||||
</p>
|
||||
) : (
|
||||
<div />
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="w-100 h-100 relative" style={{ background: '#1a1a1a' }}>
|
||||
<div className="w-100 h-100 relative bg-white ba b--black">
|
||||
<a className="w-100 h-100 db pa2 no-underline" href="/~chat">
|
||||
<p className="gray label-regular b absolute" style={{left: 8, top: 4}}>Chat</p>
|
||||
<p className="black gray absolute f9" style={{left: 8, top: 8}}>Messaging</p>
|
||||
<img
|
||||
className="absolute"
|
||||
style={{ left: 68, top: 65 }}
|
||||
style={{ left: 39, top: 39 }}
|
||||
src="/~chat/img/Tile.png"
|
||||
width={106}
|
||||
height={98} />
|
||||
{numInvElem}
|
||||
{numMsgElem}
|
||||
width={48}
|
||||
height={48} />
|
||||
{numNotificationsElem}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
@ -3,8 +3,8 @@ import classnames from 'classnames';
|
||||
import moment from 'moment'
|
||||
import SunCalc from 'suncalc'
|
||||
|
||||
const outerSize = 234; //tile size
|
||||
const innerSize = 218; //clock size
|
||||
const outerSize = 124; //tile size
|
||||
const innerSize = 124; //clock size
|
||||
|
||||
//polar to cartesian
|
||||
// var ptc = function(r, theta) {
|
||||
@ -105,17 +105,12 @@ class Clock extends Component {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.canvas = initCanvas(
|
||||
this.canvasRef,
|
||||
{ x: innerSize, y: innerSize },
|
||||
4
|
||||
);
|
||||
|
||||
navigator.geolocation.getCurrentPosition((res) => {
|
||||
|
||||
const lat = res.coords.latitude
|
||||
const lon = res.coords.longitude
|
||||
initGeolocation() {
|
||||
if (typeof this.props.data === 'string') {
|
||||
// console.log(typeof this.props.data)
|
||||
const latlon = this.props.data.split(',')
|
||||
const lat = latlon[0]
|
||||
const lon = latlon[1]
|
||||
|
||||
const suncalc = SunCalc.getTimes(new Date(), lat, lon)
|
||||
|
||||
@ -137,10 +132,25 @@ class Clock extends Component {
|
||||
lon,
|
||||
...convertedSunCalc,
|
||||
geolocationSuccess: true,
|
||||
}, (err) => {
|
||||
if (err) console.log(err);
|
||||
}, { maximumAge: Infinity, timeout: 10000 });
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps !== this.props) {
|
||||
this.initGeolocation()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this.canvas = initCanvas(
|
||||
this.canvasRef,
|
||||
{ x: innerSize, y: innerSize },
|
||||
4
|
||||
);
|
||||
|
||||
this.initGeolocation()
|
||||
this.animate()
|
||||
}
|
||||
|
||||
@ -151,7 +161,7 @@ class Clock extends Component {
|
||||
const { state } = this
|
||||
const time = new Date();
|
||||
const ctx = this.canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, c.width, c.height);
|
||||
ctx.clearRect(0, 0, ctx.width, ctx.height);
|
||||
ctx.save();
|
||||
|
||||
const ctr = innerSize / 2
|
||||
@ -161,8 +171,8 @@ class Clock extends Component {
|
||||
var cx = ctr
|
||||
var cy = ctr
|
||||
this.angle = degToRad(convert(time, this.referenceTime))
|
||||
var newX = cx + (ctr - 24) * Math.cos(this.angle);
|
||||
var newY = cy + (ctr - 24) * Math.sin(this.angle);
|
||||
var newX = cx + (ctr - 15) * Math.cos(this.angle);
|
||||
var newY = cy + (ctr - 15) * Math.sin(this.angle);
|
||||
|
||||
// Initial background
|
||||
circle(
|
||||
@ -239,7 +249,7 @@ class Clock extends Component {
|
||||
ctx,
|
||||
newX-1/2,
|
||||
newY-1/2,
|
||||
16,
|
||||
8,
|
||||
0,
|
||||
2 * Math.PI,
|
||||
'#FCC440'
|
||||
@ -250,7 +260,7 @@ class Clock extends Component {
|
||||
ctx,
|
||||
newX-1/2,
|
||||
newY-1/2,
|
||||
16,
|
||||
8,
|
||||
0,
|
||||
2 * Math.PI,
|
||||
'#6792FF',
|
||||
@ -262,7 +272,7 @@ class Clock extends Component {
|
||||
ctx,
|
||||
newX-1/2,
|
||||
newY-1/2,
|
||||
16,
|
||||
8,
|
||||
0,
|
||||
2 * Math.PI,
|
||||
'#FFFFFF'
|
||||
@ -272,7 +282,7 @@ class Clock extends Component {
|
||||
ctx,
|
||||
newX-1/2,
|
||||
newY-1/2,
|
||||
16,
|
||||
8,
|
||||
0,
|
||||
2 * Math.PI,
|
||||
'#000000',
|
||||
@ -296,13 +306,25 @@ class Clock extends Component {
|
||||
ctx,
|
||||
ctr,
|
||||
ctr,
|
||||
ctr,
|
||||
ctr-1,
|
||||
-1,
|
||||
2 * Math.PI,
|
||||
'#000000',
|
||||
1
|
||||
);
|
||||
|
||||
// Outer borders
|
||||
circleOutline(
|
||||
ctx,
|
||||
ctr,
|
||||
ctr,
|
||||
ctr,
|
||||
-1,
|
||||
2 * Math.PI,
|
||||
'#FFFFFF',
|
||||
1
|
||||
);
|
||||
|
||||
// Center white circle with time and date
|
||||
circle(
|
||||
ctx,
|
||||
@ -311,7 +333,7 @@ class Clock extends Component {
|
||||
ctr/1.85,
|
||||
-1,
|
||||
2 * Math.PI,
|
||||
'#000000'
|
||||
'#FFFFFF'
|
||||
)
|
||||
|
||||
// Center white circle border
|
||||
@ -322,7 +344,7 @@ class Clock extends Component {
|
||||
ctr/1.85,
|
||||
-1,
|
||||
2 * Math.PI,
|
||||
'rgb(26, 26, 26)',
|
||||
'#000000',
|
||||
1
|
||||
);
|
||||
|
||||
@ -332,12 +354,12 @@ class Clock extends Component {
|
||||
: moment().format('h:mm A')
|
||||
const dateText = moment().format('MMM Do')
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = '#FFFFFF'
|
||||
ctx.font = '16px Inter'
|
||||
ctx.fillText(timeText, ctr, ctr + 6 - 12)
|
||||
ctx.fillStyle = '#000000'
|
||||
ctx.font = '12px Inter'
|
||||
ctx.fillText(timeText, ctr, ctr + 6 - 7)
|
||||
ctx.fillStyle = '#B1B1B1'
|
||||
ctx.font = '16px Inter'
|
||||
ctx.fillText(dateText, ctr, ctr + 6 + 12)
|
||||
ctx.font = '12px Inter'
|
||||
ctx.fillText(dateText, ctr, ctr + 6 + 7)
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
@ -359,10 +381,10 @@ export default class ClockTile extends Component {
|
||||
|
||||
renderWrapper(child) {
|
||||
return (
|
||||
<div className="pa2" style={{
|
||||
<div className="" style={{
|
||||
width: outerSize,
|
||||
height: outerSize,
|
||||
background: 'rgba(0,0,0,1)'
|
||||
background: '#fff'
|
||||
}}>
|
||||
{child}
|
||||
</div>
|
||||
@ -371,9 +393,8 @@ export default class ClockTile extends Component {
|
||||
|
||||
render() {
|
||||
let data = !!this.props.data ? this.props.data : {};
|
||||
|
||||
return this.renderWrapper((
|
||||
<Clock/>
|
||||
<Clock data={data}/>
|
||||
));
|
||||
|
||||
}
|
||||
|
41
pkg/interface/contacts/package-lock.json
generated
@ -2148,7 +2148,8 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -2172,13 +2173,15 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -2195,19 +2198,22 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -2338,7 +2344,8 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -2352,6 +2359,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -2368,6 +2376,7 @@
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -2376,13 +2385,15 @@
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -2403,6 +2414,7 @@
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -2491,7 +2503,8 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -2505,6 +2518,7 @@
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -2600,7 +2614,8 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -2642,6 +2657,7 @@
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -2663,6 +2679,7 @@
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -2711,13 +2728,15 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,19 +9,19 @@ export default class ContactTile extends Component {
|
||||
const { props } = this;
|
||||
|
||||
return (
|
||||
<div className="w-100 h-100 relative" style={{ background: "#286E55" }}>
|
||||
<a className="w-100 h-100 db pa2 no-underline" href="/~contacts">
|
||||
<div className="w-100 h-100 relative bg-white b--black ba">
|
||||
<a className="w-100 h-100 db pa2 bn" href="/~contacts">
|
||||
<p
|
||||
className="white label-regular b absolute"
|
||||
style={{ left: 8, top: 4 }}>
|
||||
className="black absolute f9"
|
||||
style={{ left: 8, top: 8 }}>
|
||||
Contacts
|
||||
</p>
|
||||
<img
|
||||
className="absolute"
|
||||
style={{ left: 69, top: 69 }}
|
||||
style={{ left: 39, top: 39 }}
|
||||
src="/~contacts/img/Tile.png"
|
||||
width={96}
|
||||
height={96}
|
||||
width={48}
|
||||
height={48}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
140
pkg/interface/launch/package-lock.json
generated
@ -1106,6 +1106,25 @@
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"dev": true
|
||||
},
|
||||
"deep-rename-keys": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz",
|
||||
"integrity": "sha1-7eeFN9emaivmFRfir5Vtf1ij8dg=",
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2",
|
||||
"rename-keys": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"kind-of": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"default-compare": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
|
||||
@ -1418,6 +1437,11 @@
|
||||
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
|
||||
"dev": true
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||
"integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
|
||||
},
|
||||
"expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
@ -2371,8 +2395,7 @@
|
||||
"get-value": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
@ -2916,6 +2939,14 @@
|
||||
"integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
|
||||
"dev": true
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
@ -2976,8 +3007,7 @@
|
||||
"is-buffer": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
|
||||
},
|
||||
"is-callable": {
|
||||
"version": "1.1.4",
|
||||
@ -3130,7 +3160,6 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
@ -3218,8 +3247,7 @@
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
@ -3916,6 +3944,56 @@
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"omit-deep": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz",
|
||||
"integrity": "sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w=",
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.1",
|
||||
"unset-value": "^0.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"has-value": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
|
||||
"integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
|
||||
"requires": {
|
||||
"get-value": "^2.0.3",
|
||||
"has-values": "^0.1.4",
|
||||
"isobject": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"isobject": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
|
||||
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
|
||||
"requires": {
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-values": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
|
||||
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"unset-value": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
|
||||
"integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
|
||||
"requires": {
|
||||
"has-value": "^0.3.1",
|
||||
"isobject": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
@ -4709,6 +4787,11 @@
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||
"dev": true
|
||||
},
|
||||
"rename-keys": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz",
|
||||
"integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg=="
|
||||
},
|
||||
"repeat-element": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
|
||||
@ -5410,6 +5493,16 @@
|
||||
"util.promisify": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"svgson": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svgson/-/svgson-4.0.0.tgz",
|
||||
"integrity": "sha512-4xmo8f7IREKzSimfKLxdFmffWn8ngstS6EYC8Hqoo4twyzLxc1BETdSBz++wx8k9s8EH8hLNi+VoH+7T2pkIgw==",
|
||||
"requires": {
|
||||
"deep-rename-keys": "^0.2.1",
|
||||
"omit-deep": "0.3.0",
|
||||
"xml-reader": "2.4.3"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "3.17.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
|
||||
@ -5579,6 +5672,11 @@
|
||||
"through2": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"transformation-matrix": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz",
|
||||
"integrity": "sha512-74MoNHhwLVuzwaPDcAecFjSkOA9vwWqyOdkeB0Be8Jc/IWSS5SNZKapFllqzkTliqZptkvqX5CZnVeDvfhN8cw=="
|
||||
},
|
||||
"type": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
|
||||
@ -5720,6 +5818,17 @@
|
||||
"integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"urbit-sigil-js": {
|
||||
"version": "1.3.13",
|
||||
"resolved": "https://registry.npmjs.org/urbit-sigil-js/-/urbit-sigil-js-1.3.13.tgz",
|
||||
"integrity": "sha512-g6tC7K65O/4rMCd9/Cy+BVyVSzC3GNjfd0R4EaXEl4aXnjRIiIkD0xkZl56yzLwNk6W9bniDQJALcGPxY3IROw==",
|
||||
"requires": {
|
||||
"invariant": "^2.2.4",
|
||||
"react": "^16.8.6",
|
||||
"svgson": "^4.0.0",
|
||||
"transformation-matrix": "2.1.1"
|
||||
}
|
||||
},
|
||||
"urix": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
|
||||
@ -5899,6 +6008,23 @@
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xml-lexer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz",
|
||||
"integrity": "sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY=",
|
||||
"requires": {
|
||||
"eventemitter3": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"xml-reader": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz",
|
||||
"integrity": "sha1-n4EMr3xCWlqvuEixxFEDyecddTA=",
|
||||
"requires": {
|
||||
"eventemitter3": "^2.0.0",
|
||||
"xml-lexer": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
|
@ -31,7 +31,8 @@
|
||||
"moment": "^2.20.1",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-router-dom": "^5.0.0"
|
||||
"react-router-dom": "^5.0.0",
|
||||
"urbit-sigil-js": "^1.3.13"
|
||||
},
|
||||
"resolutions": {
|
||||
"natives": "1.1.3"
|
||||
|
@ -1,3 +1,10 @@
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: "Inter", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6, a, input, textarea, button {
|
||||
margin-block-end: unset;
|
||||
margin-block-start: unset;
|
||||
@ -12,63 +19,10 @@ a:-webkit-any-link {
|
||||
|
||||
textarea, select, input, button { outline: none; }
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
line-height: 48px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.body-regular {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.body-large {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.label-regular {
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.label-small {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.label-small-mono {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
.mono {
|
||||
font-family: "Source Code Pro", monospace;
|
||||
}
|
||||
|
||||
.body-regular-400 {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.plus-font {
|
||||
font-size: 48px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.fw-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bg-v-light-gray {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.gray-30 {
|
||||
color: #B1B2B3;
|
||||
}
|
||||
|
||||
.green-medium {
|
||||
color: #2ED196;
|
||||
.mix-blend-diff {
|
||||
mix-blend-mode: difference;
|
||||
}
|
1
pkg/interface/launch/src/css/indigo-static.css
Normal file
@ -1,4 +1,4 @@
|
||||
@import 'css/tachyons.css';
|
||||
@import 'css/indigo-static.css';
|
||||
@import 'css/fonts.css';
|
||||
@import 'css/custom.css';
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import { subscription } from '/subscription';
|
||||
import { api } from '/lib/api';
|
||||
import classnames from 'classnames';
|
||||
|
||||
let style = {
|
||||
circle: {
|
||||
width: '2em',
|
||||
height: '2em',
|
||||
background: '#000000',
|
||||
border: '4px solid #333333',
|
||||
'borderRadius': '2em'
|
||||
},
|
||||
triangle: {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
'borderTop': '8px solid #FFFFFF',
|
||||
'borderLeft': '8px solid transparent',
|
||||
'borderRight': '8px solid transparent',
|
||||
'fontSize': 0,
|
||||
'lineHeight': 0,
|
||||
'marginLeft': 'auto',
|
||||
'marginRight': 'auto',
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default class Dropdown extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className="ml2" style={style.circle}>
|
||||
<div className="mt2" style={style.triangle}></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,51 +1,28 @@
|
||||
import React, { Component } from 'react';
|
||||
import { subscription } from '/subscription';
|
||||
import { api } from '/lib/api';
|
||||
import classnames from 'classnames';
|
||||
import moment from 'moment';
|
||||
|
||||
import Dropdown from '/components/dropdown';
|
||||
import { Sigil } from './sigil';
|
||||
|
||||
export default class Header extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.interval = null;
|
||||
this.timeout = null;
|
||||
|
||||
this.state = {
|
||||
moment: moment()
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let sec = parseInt(moment().format("s"), 10);
|
||||
|
||||
this.timeout = setTimeout(() => {
|
||||
this.setState({
|
||||
moment: moment()
|
||||
});
|
||||
this.interval = setInterval(() => {
|
||||
this.setState({
|
||||
moment: moment()
|
||||
});
|
||||
}, 60000);
|
||||
}, (60 - sec) * 1000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<header className="w-100 h2 cf">
|
||||
<div className="fl h2 bg-black">
|
||||
</div>
|
||||
<div className="fr h2 bg-black">
|
||||
<p className="white v-mid h2 sans-serif dtc pr2">{this.state.moment.format("MMM DD")}</p>
|
||||
<p className="white v-mid h2 sans-serif dtc pr2">{this.state.moment.format("hh:mm a")}</p>
|
||||
<header
|
||||
className="bg-white bg-gray0-d w-100 justify-between relative tc pt3"
|
||||
style={{ height: 40 }}>
|
||||
<span
|
||||
className="f9 white-d inter dib"
|
||||
style={{
|
||||
verticalAlign: "text-top",
|
||||
paddingTop: 3
|
||||
}}>
|
||||
Home
|
||||
</span>
|
||||
<div className="absolute right-1 lh-copy" style={{ top: 12 }}>
|
||||
<Sigil
|
||||
ship={"~" + window.ship}
|
||||
size={16} color={"#000000"}
|
||||
classes="mix-blend-diff v-mid" />
|
||||
<span className="mono white-d f9 ml2">
|
||||
{"~" + window.ship}
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
@ -23,9 +23,11 @@ export default class Home extends Component {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="fl w-100 vh-100 bg-black center">
|
||||
<div className="fl w-100 h-100 bg-white center">
|
||||
<Header />
|
||||
<div className="v-mid pa2 dtc">
|
||||
<div className={"v-mid pa2 dtc-m dtc-l dtc-xl " +
|
||||
"flex justify-between flex-wrap"}
|
||||
style={{maxWidth: "40rem"}}>
|
||||
{tileElems}
|
||||
</div>
|
||||
</div>
|
||||
|
31
pkg/interface/launch/src/js/components/sigil.js
Normal file
@ -0,0 +1,31 @@
|
||||
import React, { Component } from "react";
|
||||
import { sigil, reactRenderer } from "urbit-sigil-js";
|
||||
|
||||
export class Sigil extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
|
||||
let classes = props.classes || "";
|
||||
|
||||
if (props.ship.length > 14) {
|
||||
return (
|
||||
<div
|
||||
className="bg-black dib"
|
||||
style={{ width: props.size, height: props.size }}></div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
className={"dib " + classes}
|
||||
style={{ flexBasis: 16, backgroundColor: props.color }}>
|
||||
{sigil({
|
||||
patp: props.ship,
|
||||
renderer: reactRenderer,
|
||||
size: props.size,
|
||||
colors: [props.color, "white"]
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ export default class Tile extends Component {
|
||||
|
||||
return (
|
||||
<div className="fl ma2 bg-white overflow-hidden"
|
||||
style={{ height: '234px', width: '234px' }}>
|
||||
style={{ height: '126px', width: '126px' }}>
|
||||
{ !!SpecificTile ?
|
||||
<SpecificTile data={this.props.data} />
|
||||
: <div></div>
|
||||
|
@ -9,19 +9,19 @@ export default class LinkTile extends Component {
|
||||
const { props } = this;
|
||||
|
||||
return (
|
||||
<div className="w-100 h-100 relative ba b--black" style={{ background: "#FFFFFF" }}>
|
||||
<a className="w-100 h-100 db pa2 no-underline" href="/~link">
|
||||
<div className="w-100 h-100 relative ba b--black bg-white">
|
||||
<a className="w-100 h-100 db pa2 bn" href="/~link">
|
||||
<p
|
||||
className="label-regular b absolute"
|
||||
style={{ left: 8, top: 4 }}>
|
||||
className="f9 black absolute"
|
||||
style={{ left: 8, top: 8 }}>
|
||||
Links
|
||||
</p>
|
||||
<img
|
||||
className="absolute"
|
||||
style={{ left: 69, top: 69 }}
|
||||
style={{ left: 39, top: 39 }}
|
||||
src="/~link/img/Tile.png"
|
||||
width={96}
|
||||
height={96}
|
||||
width={48}
|
||||
height={48}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -10,22 +10,36 @@ export default class PublishTile extends Component {
|
||||
|
||||
|
||||
render(){
|
||||
|
||||
let notificationsNum = this.props.data.notifications;
|
||||
|
||||
if (notificationsNum === 0) {
|
||||
notificationsNum = "";
|
||||
}
|
||||
else if (notificationsNum > 99) {
|
||||
notificationsNum = "99+";
|
||||
}
|
||||
else if (isNaN(notificationsNum)) {
|
||||
notificationsNum = "";
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-100 h-100 relative" style={{background: "#1a1a1a"}}>
|
||||
<div className="w-100 h-100 relative bg-white ba b--black">
|
||||
<a className="w-100 h-100 db no-underline" href="/~publish">
|
||||
<p className="gray label-regular b absolute"
|
||||
style={{left: 8, top: 4}}>
|
||||
Publish
|
||||
<p className="black f9 absolute" style={{ left: 8, top: 8 }}>
|
||||
Publishing
|
||||
</p>
|
||||
<img
|
||||
className="absolute"
|
||||
style={{left: 60, top: 66}}
|
||||
style={{ left: 39, top: 39 }}
|
||||
src="/~publish/tile.png"
|
||||
width={113}
|
||||
height={102} />
|
||||
<div className="absolute w-100 flex-col body-regular white"
|
||||
width={48}
|
||||
height={48}
|
||||
/>
|
||||
<div
|
||||
className="absolute w-100 flex-col f9"
|
||||
style={{ verticalAlign: "bottom", bottom: 8, left: 8 }}>
|
||||
<span className="green-medium">{this.props.data.notifications}</span>
|
||||
<span className="green2">{notificationsNum}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -7,15 +7,20 @@ export default class sotoTile extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="w-100 h-100 relative" style={{background: "#1a1a1a"}}>
|
||||
<a className="w-100 h-100 db no-underline" href="/~dojo">
|
||||
<p className="gray label-regular b absolute"
|
||||
style={{ left: 8, top: 4 }}>
|
||||
<div className="w-100 h-100 relative bg-black">
|
||||
<a className="w-100 h-100 db bn" href="/~dojo">
|
||||
<p className="white f9 absolute"
|
||||
style={{ left: 8, top: 8 }}>
|
||||
Dojo
|
||||
</p>
|
||||
<img src="~dojo/img/Tile.png"
|
||||
className="absolute"
|
||||
style={{ left: 30, top: 30, height: "174px", width: "174px"}}
|
||||
style={{
|
||||
left: 39,
|
||||
top: 39,
|
||||
height: 48,
|
||||
width: 48
|
||||
}}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -8,12 +8,7 @@ class IconWithData extends Component {
|
||||
|
||||
return (
|
||||
<div className='mt2'>
|
||||
<img
|
||||
src={'/~weather/img/' + props.icon + '.png'}
|
||||
width={20}
|
||||
height={20}
|
||||
className="dib mr2" />
|
||||
<p className="label-small dib white">{props.text}</p>
|
||||
<p className="f9 white">{props.text}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -36,13 +31,13 @@ export default class WeatherTile extends Component {
|
||||
|
||||
locationSubmit() {
|
||||
navigator.geolocation.getCurrentPosition((res) => {
|
||||
console.log(res);
|
||||
let latlng = `${res.coords.latitude},${res.coords.longitude}`;
|
||||
this.setState({
|
||||
latlng
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
}, { maximumAge: Infinity, timeout: 10000 });
|
||||
api.action("clock", "json", latlng);
|
||||
api.action('weather', 'json', latlng);
|
||||
});
|
||||
}
|
||||
@ -55,6 +50,7 @@ export default class WeatherTile extends Component {
|
||||
if (latlngParse.test(latlngNoSpace)) {
|
||||
let latlng = latlngNoSpace;
|
||||
this.setState({latlng}, (err) => {console.log(err)}, {maximumAge: Infinity, timeout: 10000});
|
||||
api.action("clock", "json", latlng);
|
||||
api.action('weather', 'json', latlng);
|
||||
this.setState({manualEntry: !this.state.manualEntry});
|
||||
}
|
||||
@ -73,10 +69,11 @@ export default class WeatherTile extends Component {
|
||||
|
||||
renderWrapper(child) {
|
||||
return (
|
||||
<div className="pa2 relative" style={{
|
||||
width: 234,
|
||||
height: 234,
|
||||
background: '#1a1a1a'
|
||||
<div
|
||||
className="pa2 relative bg-white b--black ba"
|
||||
style={{
|
||||
width: 126,
|
||||
height: 126,
|
||||
}}>
|
||||
{child}
|
||||
</div>
|
||||
@ -88,53 +85,65 @@ export default class WeatherTile extends Component {
|
||||
let error;
|
||||
if (this.state.error === true) {
|
||||
error = <p
|
||||
className="label-small red pt1">
|
||||
className="f9 red2 pt1">
|
||||
Incorrect latitude/longitude formatting. Please try again. <br/>
|
||||
(eg. "29.558107, -95.089023")
|
||||
</p>
|
||||
}
|
||||
if (location.protocol === "https:") {
|
||||
secureCheck = <a
|
||||
className="label-regular b gray absolute pointer"
|
||||
style={{right: 8, top: 4}}
|
||||
onClick={() => this.locationSubmit()}>Detect location -></a>
|
||||
className="black f9 absolute pointer"
|
||||
style={{right: 8, top: 8}}
|
||||
onClick={() => this.locationSubmit()}>Detect -></a>
|
||||
}
|
||||
return this.renderWrapper((
|
||||
return this.renderWrapper(
|
||||
<div>
|
||||
<a style={{"color": "white", "cursor": "pointer"}}
|
||||
onClick={() => this.setState({manualEntry: !this.state.manualEntry})}>
|
||||
<a
|
||||
className="f9 black pointer"
|
||||
onClick={() =>
|
||||
this.setState({ manualEntry: !this.state.manualEntry })
|
||||
}>
|
||||
<-
|
||||
</a>
|
||||
{secureCheck}
|
||||
<p className="label-regular white pt2">
|
||||
Please enter your <a className="white" href="https://latitudeandlongitude.org/" target="_blank">latitude and longitude</a>.</p>
|
||||
<p className="f9 black pt2">
|
||||
Please enter your{" "}
|
||||
<a
|
||||
className="white"
|
||||
href="https://latitudeandlongitude.org/"
|
||||
target="_blank">
|
||||
latitude and longitude
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
{error}
|
||||
<form className="flex absolute" style={{"bottom": 0, "left": 8}}>
|
||||
<input id="gps"
|
||||
className="white pa1 bg-transparent outline-0 bn bb-ns b--white"
|
||||
style={{width: "86%"}}
|
||||
<div className="flex">
|
||||
<form className="flex absolute" style={{ bottom: 0, left: 8 }}>
|
||||
<input
|
||||
id="gps"
|
||||
className="w-100 black pa1 bg-transparent outline-0 bn bb-ns b--black f9"
|
||||
type="text"
|
||||
placeholder="29.558107, -95.089023"
|
||||
onKeyDown={this.keyPress.bind(this)}>
|
||||
</input>
|
||||
<input className="bg-transparent inter white w-20 outliner-0 bn pointer"
|
||||
onKeyDown={this.keyPress.bind(this)}></input>
|
||||
<input
|
||||
className="bg-transparent black outliner-0 bn pointer f9 flex-shrink-0"
|
||||
type="submit"
|
||||
onClick={() => this.manualLocationSubmit()}
|
||||
value="->">
|
||||
</input>
|
||||
value="->"></input>
|
||||
</form>
|
||||
</div>
|
||||
))
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderNoData() {
|
||||
return this.renderWrapper((
|
||||
<div onClick={() => this.setState({manualEntry: !this.state.manualEntry})}>
|
||||
<p className="gray label-regular b absolute"
|
||||
style={{left: 8, top: 4}}>
|
||||
<p className="black f9 absolute"
|
||||
style={{left: 8, top: 8}}>
|
||||
Weather
|
||||
</p>
|
||||
<p className="absolute w-100 flex-col body-regular white" style={{verticalAlign: "bottom", bottom: 8, left: 8, cursor: "pointer"}}>-> Set location</p>
|
||||
<p className="absolute w-100 flex-col f9 black" style={{verticalAlign: "bottom", bottom: 8, left: 8, cursor: "pointer"}}>-> Set location</p>
|
||||
</div>
|
||||
));
|
||||
}
|
||||
@ -145,58 +154,26 @@ export default class WeatherTile extends Component {
|
||||
|
||||
let da = moment.unix(d.sunsetTime).format('h:mm a') || '';
|
||||
|
||||
return this.renderWrapper((
|
||||
return this.renderWrapper(
|
||||
<div>
|
||||
<p className="gray label-regular b absolute"
|
||||
style={{left: 8, top: 4}}>
|
||||
<p className="black f9 absolute" style={{ left: 8, top: 8 }}>
|
||||
Weather
|
||||
</p>
|
||||
<a className="label-regular b gray absolute pointer"
|
||||
style={{right: 8, top: 4}}
|
||||
onClick={() => this.setState({manualEntry: !this.state.manualEntry})}>Update location -></a>
|
||||
<div className="w-100 mb2 mt2 absolute"
|
||||
style={{left: 18, top: 28}}>
|
||||
<img
|
||||
src={'/~weather/img/' + c.icon + '.png'}
|
||||
width={64}
|
||||
height={64}
|
||||
className="dib" />
|
||||
<h2
|
||||
className="dib ml2 white"
|
||||
style={{
|
||||
fontSize: 72,
|
||||
lineHeight: '64px',
|
||||
fontWeight: 400
|
||||
}}>
|
||||
{Math.round(c.temperature)}°</h2>
|
||||
</div>
|
||||
<div className="w-100 cf absolute"
|
||||
style={{ left: 18, top: 118 }}>
|
||||
<div className="fl w-50">
|
||||
<IconWithData
|
||||
icon='winddirection'
|
||||
text={c.windBearing + '°'} />
|
||||
<IconWithData
|
||||
icon='chancerain'
|
||||
text={(c.precipProbability * 100) + '%'} />
|
||||
<IconWithData
|
||||
icon='windspeed'
|
||||
text={Math.round(c.windSpeed) + ' mph'} />
|
||||
</div>
|
||||
<div className="fr w-50">
|
||||
<IconWithData
|
||||
icon='sunset'
|
||||
text={da} />
|
||||
<IconWithData
|
||||
icon='low'
|
||||
text={Math.round(d.temperatureLow) + '°'} />
|
||||
<IconWithData
|
||||
icon='high'
|
||||
text={Math.round(d.temperatureHigh) + '°'} />
|
||||
<a
|
||||
className="black f9 absolute pointer"
|
||||
style={{ right: 8, top: 8 }}
|
||||
onClick={() =>
|
||||
this.setState({ manualEntry: !this.state.manualEntry })
|
||||
}>
|
||||
->
|
||||
</a>
|
||||
<div className="w-100 absolute" style={{ left: 8, bottom: 8 }}>
|
||||
<p className="f9 black">{c.summary}</p>
|
||||
<p className="f9 pt1 black">{Math.round(c.temperature)}°</p>
|
||||
<p className="f9 pt1 black">Sunset at {da}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|