mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-09-20 23:18:00 +03:00
Merge remote-tracking branch 'origin/master' into philip/latter
This commit is contained in:
commit
eae479f829
@ -680,11 +680,11 @@
|
||||
|= [kel=weft except=(set desk) force=?]
|
||||
^+ kiln
|
||||
=/ ded (find-blocked kel except)
|
||||
?: force
|
||||
=. kiln (suspend-many ded)
|
||||
(bump-many kel (all-desks-but (~(uni in except) ded)))
|
||||
?: =(~ ded)
|
||||
(bump-many kel (all-desks-but except))
|
||||
=? kiln force (suspend-many ded)
|
||||
?: |(force =(~ ded))
|
||||
?: !=(zuse+zuse kel)
|
||||
(bump-one kel %base)
|
||||
(bump-many (all-desks-but (~(uni in except) ded)))
|
||||
=- (^emit (pyre:pass leaf/- ~))
|
||||
"kiln: desks blocked upgrade to {<zuse/zuse>}: {<ded>}"
|
||||
::
|
||||
@ -704,7 +704,7 @@
|
||||
$(ded t.ded, kiln abet:(suspend i.ded))
|
||||
::
|
||||
++ bump-many
|
||||
|= [kel=weft live=(set desk)]
|
||||
|= live=(set desk)
|
||||
^+ kiln
|
||||
:: ensure %base is always reloaded first
|
||||
::
|
||||
@ -718,7 +718,7 @@
|
||||
::
|
||||
|- ^+ kiln
|
||||
?~ liv kiln
|
||||
$(liv t.liv, kiln (bump-one kel i.liv))
|
||||
$(liv t.liv, kiln (bump-one zuse+zuse i.liv))
|
||||
::
|
||||
++ bump-one
|
||||
|= [kel=weft =desk]
|
||||
@ -733,7 +733,7 @@
|
||||
?: =(kel u.kul)
|
||||
~> %slog.(fmt "{here} already at {<[lal num]:kel>}")
|
||||
update-running-dudes
|
||||
=^ tem rail.rak (crank-next %| kel)
|
||||
=^ tem rail.rak (crank-next kel)
|
||||
?^ tem
|
||||
(emit merge-main:pass)
|
||||
=- (emit (pyre:pass leaf/- ~))
|
||||
@ -861,7 +861,8 @@
|
||||
++ kelvin-same
|
||||
^+ vats
|
||||
~> %slog.(fmt "merging into {here}")
|
||||
=. rail.rak +:(crank-next %& (dec aeon:ral))
|
||||
?> ?=(^ rail.rak)
|
||||
=. next.u.rail.rak ~
|
||||
(emil ~[merge-main sync-ud]:pass)
|
||||
::
|
||||
++ do-base
|
||||
@ -878,7 +879,8 @@
|
||||
=/ =diff [%block loc rak new-weft blockers]
|
||||
(emil sync-ud:pass (diff:give diff) ~)
|
||||
~> %slog.(fmt "applying OTA to {here}, kelvin: {<new-weft>}")
|
||||
=. rail.rak +:(crank-next %& (dec aeon:ral))
|
||||
?> ?=(^ rail.rak)
|
||||
=. next.u.rail.rak ~
|
||||
=. wef
|
||||
?: =(old-weft new-weft) ~
|
||||
`new-weft
|
||||
@ -912,11 +914,7 @@
|
||||
update-running-dudes
|
||||
?. =(%base loc)
|
||||
kiln
|
||||
=/ kel=[@tas @ud]
|
||||
?~ rail.rak zuse/zuse
|
||||
?~ next.u.rail.rak zuse/zuse
|
||||
weft.i.next.u.rail.rak
|
||||
(bump-many kel (all-desks-but (get-unblockers ark)))
|
||||
(bump-many (all-desks-but (get-unblockers ark)))
|
||||
::
|
||||
++ take-merge-main
|
||||
|= syn=sign-arvo
|
||||
@ -991,7 +989,7 @@
|
||||
:: +crank-next: pop stale items from .next until one matches
|
||||
::
|
||||
++ crank-next
|
||||
|= new=(each aeon weft)
|
||||
|= new=weft
|
||||
^+ [match=*(unit rung) rail.rak]
|
||||
?~ rail.rak
|
||||
~| [%no-rail-for desk=loc]
|
||||
@ -1000,10 +998,7 @@
|
||||
=- [match `u.rail.rak(next next)]
|
||||
|- ^- [match=(unit rung) next=(list rung)]
|
||||
?~ rog [~ next.u.rail.rak]
|
||||
?: ?- -.new
|
||||
%& =(p.new aeon.i.rog)
|
||||
%| =(p.new weft.i.rog)
|
||||
==
|
||||
?: =(new weft.i.rog)
|
||||
[`i.rog t.rog]
|
||||
$(rog t.rog)
|
||||
::
|
||||
|
@ -1,5 +1,5 @@
|
||||
|%
|
||||
+$ bump [%kiln-bump except=(set desk) force=_|]
|
||||
+$ bump [except=(set desk) force=_|]
|
||||
--
|
||||
|_ b=bump
|
||||
++ grad %noun
|
||||
@ -9,7 +9,6 @@
|
||||
++ json
|
||||
^- $-(^json bump)
|
||||
=, dejs:format
|
||||
%+ pe %kiln-bump
|
||||
%- ot
|
||||
:~ except+(as so)
|
||||
force+bo
|
||||
|
@ -1,10 +1,10 @@
|
||||
:~ title+'System'
|
||||
info+'An app launcher for Urbit.'
|
||||
color+0xee.5432
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v4.64ana.19ug9.ik7l6.og080.68ce4.glob' 0v4.64ana.19ug9.ik7l6.og080.68ce4]
|
||||
::glob-ames+~zod^0v0
|
||||
base+'grid'
|
||||
version+[1 0 1]
|
||||
version+[1 0 2]
|
||||
website+'https://tlon.io'
|
||||
license+'MIT'
|
||||
==
|
||||
|
@ -49,8 +49,6 @@ const AppRoutes = () => {
|
||||
}
|
||||
}, [isDarkMode, theme]);
|
||||
|
||||
useEffect(() => {}, []);
|
||||
|
||||
useEffect(
|
||||
handleError(() => {
|
||||
window.name = 'grid';
|
||||
|
@ -227,6 +227,7 @@ export const Leap = React.forwardRef(
|
||||
[selection, rawInput, match, matches, selectedMatch]
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<div className="relative z-50 w-full">
|
||||
<form
|
||||
@ -234,6 +235,7 @@ export const Leap = React.forwardRef(
|
||||
'flex items-center h-full w-full px-2 rounded-full bg-white default-ring focus-within:ring-2',
|
||||
shouldDim && 'opacity-60',
|
||||
!navOpen ? 'bg-gray-50' : '',
|
||||
menu === 'upgrading' ? 'bg-orange-500' : '',
|
||||
className
|
||||
)}
|
||||
onSubmit={onSubmit}
|
||||
@ -241,28 +243,32 @@ export const Leap = React.forwardRef(
|
||||
<label
|
||||
htmlFor="leap"
|
||||
className={classNames(
|
||||
'inline-block flex-none p-2 h4 text-blue-400',
|
||||
!selection && 'sr-only'
|
||||
'inline-block flex-none p-2 h4 ',
|
||||
menu === 'upgrading' ? 'text-white' : !selection ? 'sr-only' : 'text-blue-400'
|
||||
)}
|
||||
>
|
||||
{selection || 'Search'}
|
||||
{menu === 'upgrading'
|
||||
? 'Your Urbit is being updated, this page will update when ready'
|
||||
: selection || 'Search'}
|
||||
</label>
|
||||
<input
|
||||
id="leap"
|
||||
type="text"
|
||||
ref={inputRef}
|
||||
placeholder={selection ? '' : 'Search'}
|
||||
className="flex-1 w-full h-full px-2 h4 text-base rounded-full bg-transparent outline-none"
|
||||
value={rawInput}
|
||||
onClick={toggleSearch}
|
||||
onFocus={onFocus}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
autoComplete="off"
|
||||
aria-autocomplete="both"
|
||||
aria-controls={dropdown}
|
||||
aria-activedescendant={selectedMatch?.display || selectedMatch?.value}
|
||||
/>
|
||||
{menu !== 'upgrading' ? (
|
||||
<input
|
||||
id="leap"
|
||||
type="text"
|
||||
ref={inputRef}
|
||||
placeholder={selection ? '' : 'Search'}
|
||||
className="flex-1 w-full h-full px-2 h4 text-base rounded-full bg-transparent outline-none"
|
||||
value={rawInput}
|
||||
onClick={toggleSearch}
|
||||
onFocus={onFocus}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
autoComplete="off"
|
||||
aria-autocomplete="both"
|
||||
aria-controls={dropdown}
|
||||
aria-activedescendant={selectedMatch?.display || selectedMatch?.value}
|
||||
/>
|
||||
) : null}
|
||||
</form>
|
||||
{menu === 'search' && (
|
||||
<Link
|
||||
|
@ -52,7 +52,8 @@ export type MenuState =
|
||||
| 'search'
|
||||
| 'notifications'
|
||||
| 'help-and-support'
|
||||
| 'system-preferences';
|
||||
| 'system-preferences'
|
||||
| 'upgrading';
|
||||
|
||||
interface NavProps {
|
||||
menu?: MenuState;
|
||||
@ -68,7 +69,7 @@ export const Nav: FunctionComponent<NavProps> = ({ menu }) => {
|
||||
const select = useLeapStore((state) => state.select);
|
||||
|
||||
const menuState = menu || 'closed';
|
||||
const isOpen = menuState !== 'closed';
|
||||
const isOpen = menuState !== 'upgrading' && menuState !== 'closed';
|
||||
const eitherOpen = isOpen || systemMenuOpen;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -12,7 +12,7 @@ function renderNotification(notification: Notification, key: string, lid: HarkLi
|
||||
if (notification.bin.place.path === '/lag') {
|
||||
return <RuntimeLagNotification key={key} />;
|
||||
}
|
||||
if (notification.bin.place.path === '/blocked') {
|
||||
if (notification.bin.path === '/blocked' && notification.bin.place.path === '/desk/base') {
|
||||
return <BaseBlockedNotification key={key} />;
|
||||
}
|
||||
if (notification.bin.place.path === '/onboard') {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { pick } from 'lodash';
|
||||
import { pick, pickBy, partition } from 'lodash';
|
||||
import React, { useCallback } from 'react';
|
||||
import { kilnBump } from '@urbit/api/hood';
|
||||
import { AppList } from '../../components/AppList';
|
||||
@ -7,9 +7,12 @@ import { Dialog, DialogClose, DialogContent, DialogTrigger } from '../../compone
|
||||
import { Elbow } from '../../components/icons/Elbow';
|
||||
import api from '../../state/api';
|
||||
import { useCharges } from '../../state/docket';
|
||||
import useKilnState, { useVat } from '../../state/kiln';
|
||||
|
||||
import { NotificationButton } from './NotificationButton';
|
||||
import { disableDefault } from '../../state/util';
|
||||
import { Vat } from '@urbit/api';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
|
||||
export const RuntimeLagNotification = () => (
|
||||
<section
|
||||
@ -35,16 +38,29 @@ export const RuntimeLagNotification = () => (
|
||||
</section>
|
||||
);
|
||||
|
||||
function vatIsBlocked(newKelvin: number, vat: Vat) {
|
||||
return !(vat.arak?.rail?.next || []).find(({ aeon, weft }) => weft.kelvin === newKelvin);
|
||||
}
|
||||
|
||||
export const BaseBlockedNotification = () => {
|
||||
const desks: string[] = [];
|
||||
const base = useVat('base');
|
||||
const { push } = useHistory();
|
||||
// TODO: assert weft.name === 'zuse'??
|
||||
const newKelvin = base?.arak?.rail?.next?.[0]?.weft?.kelvin || 420;
|
||||
const charges = useCharges();
|
||||
const blockedCharges = Object.values(pick(charges, desks));
|
||||
const [blocked, unblocked] = useKilnState((s) => {
|
||||
const [b, u] = partition(Object.entries(s.vats), ([desk, vat]) => vatIsBlocked(newKelvin, vat));
|
||||
return [b.map(([d]) => d), u.map(([d]) => d)] as const;
|
||||
});
|
||||
|
||||
const blockedCharges = Object.values(pick(charges, blocked));
|
||||
const count = blockedCharges.length;
|
||||
|
||||
const handlePauseOTAs = useCallback(() => {}, []);
|
||||
|
||||
const handleArchiveApps = useCallback(async () => {
|
||||
api.poke(kilnBump(true));
|
||||
push('/leap/upgrading');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -1,27 +1,51 @@
|
||||
import { map, omit } from 'lodash';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent, useEffect } from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { Route, RouteComponentProps } from 'react-router-dom';
|
||||
import { Route, RouteComponentProps, useHistory, useParams } from 'react-router-dom';
|
||||
import { ErrorAlert } from '../components/ErrorAlert';
|
||||
import { MenuState, Nav } from '../nav/Nav';
|
||||
import { useCharges } from '../state/docket';
|
||||
import useKilnState from '../state/kiln';
|
||||
import { RemoveApp } from '../tiles/RemoveApp';
|
||||
import { SuspendApp } from '../tiles/SuspendApp';
|
||||
import { Tile } from '../tiles/Tile';
|
||||
import { TileInfo } from '../tiles/TileInfo';
|
||||
|
||||
type GridProps = RouteComponentProps<{
|
||||
interface RouteProps {
|
||||
menu?: MenuState;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const Grid: FunctionComponent<GridProps> = ({ match, history }) => {
|
||||
export const Grid: FunctionComponent<{}> = () => {
|
||||
const charges = useCharges();
|
||||
const { push } = useHistory();
|
||||
const { menu } = useParams<RouteProps>();
|
||||
const chargesLoaded = Object.keys(charges).length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
// TOOD: rework
|
||||
// Heuristically detect reload completion and redirect
|
||||
async function attempt(count = 0) {
|
||||
if(count > 5) {
|
||||
window.location.reload();
|
||||
}
|
||||
const start = performance.now();
|
||||
await useKilnState.getState().fetchVats();
|
||||
await useKilnState.getState().fetchVats();
|
||||
if((performance.now() - start) > 5000) {
|
||||
attempt(count+1);
|
||||
} else {
|
||||
push('/');
|
||||
}
|
||||
}
|
||||
if(menu === 'upgrading') {
|
||||
attempt();
|
||||
}
|
||||
}, [menu])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<header className="fixed sm:sticky bottom-0 sm:bottom-auto sm:top-0 left-0 z-30 flex justify-center w-full px-4">
|
||||
<Nav menu={match.params.menu} />
|
||||
<Nav menu={menu} />
|
||||
</header>
|
||||
|
||||
<main className="h-full w-full flex justify-center pt-4 md:pt-16 pb-32 relative z-0">
|
||||
@ -30,11 +54,11 @@ export const Grid: FunctionComponent<GridProps> = ({ match, history }) => {
|
||||
<div className="grid justify-center grid-cols-2 sm:grid-cols-[repeat(auto-fit,minmax(auto,250px))] gap-4 px-4 md:px-8 w-full max-w-6xl">
|
||||
{charges &&
|
||||
map(omit(charges, window.desk), (charge, desk) => (
|
||||
<Tile key={desk} charge={charge} desk={desk} />
|
||||
<Tile key={desk} charge={charge} desk={desk} disabled={menu === 'upgrading'} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<ErrorBoundary FallbackComponent={ErrorAlert} onReset={() => history.push('/')}>
|
||||
<ErrorBoundary FallbackComponent={ErrorAlert} onReset={() => push('/')}>
|
||||
<Route exact path="/app/:desk">
|
||||
<TileInfo />
|
||||
</Route>
|
||||
|
@ -241,7 +241,17 @@ function createMockSysNotification(path: string, body: HarkBody[] = []) {
|
||||
}
|
||||
|
||||
const lag = createMockSysNotification('/lag');
|
||||
const blocked = createMockSysNotification('/blocked');
|
||||
const blocked = {
|
||||
bin: {
|
||||
place: {
|
||||
desk: window.desk,
|
||||
path: '/desk/base'
|
||||
},
|
||||
path: '/blocked'
|
||||
},
|
||||
time: Date.now() - 3_600,
|
||||
body: []
|
||||
};
|
||||
const onboard = createMockSysNotification('/onboard');
|
||||
|
||||
const updateNotification = createMockSysNotification('/desk/bitcoin', [
|
||||
|
@ -13,19 +13,20 @@ import { Bullet } from '../components/icons/Bullet';
|
||||
type TileProps = {
|
||||
charge: ChargeWithDesk;
|
||||
desk: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
|
||||
export const Tile: FunctionComponent<TileProps> = ({ charge, desk, disabled = false }) => {
|
||||
const addRecentApp = useRecentsStore((state) => state.addRecentApp);
|
||||
const { title, image, color, chad, href } = charge;
|
||||
const vat = useVat(desk);
|
||||
const { lightText, tileColor, menuColor, suspendColor, suspendMenuColor } = useTileColor(color);
|
||||
const loading = 'install' in chad;
|
||||
const suspended = 'suspend' in chad;
|
||||
const loading = !disabled && 'install' in chad;
|
||||
const suspended = disabled || 'suspend' in chad;
|
||||
const hung = 'hung' in chad;
|
||||
const active = chadIsRunning(chad);
|
||||
const active = !disabled && chadIsRunning(chad);
|
||||
const link = getAppHref(href);
|
||||
const backgroundColor = active ? tileColor || 'purple' : suspendColor;
|
||||
const backgroundColor = suspended ? suspendColor : active ? tileColor || 'purple' : suspendColor;
|
||||
|
||||
return (
|
||||
<a
|
||||
@ -47,14 +48,12 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
|
||||
<>
|
||||
{loading && <Spinner className="h-6 w-6 mr-2" />}
|
||||
<span className="text-gray-500">
|
||||
{suspended && 'Suspended'}
|
||||
{loading && 'Installing'}
|
||||
{hung && 'Errored'}
|
||||
{suspended ? 'Suspended' : loading ? 'Installing' : hung ? 'Errored' : null }
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{vat?.arak.rail?.paused && (
|
||||
{vat?.arak.rail?.paused && !disabled && (
|
||||
<Bullet className="absolute z-10 top-5 left-5 sm:top-7 sm:left-7 w-4 h-4 text-orange-500 dark:text-black" />
|
||||
)}
|
||||
<TileMenu
|
||||
|
Loading…
Reference in New Issue
Block a user