Merge pull request #4845 from urbit/m/version-notification

landscape: version negotiation notification
This commit is contained in:
fang 2021-05-01 00:03:33 +02:00 committed by GitHub
commit b9d73e693b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 8 deletions

View File

@ -191,9 +191,14 @@
^- (unit (unit cage))
?. (team:title our.bowl src.bowl) ~
?+ path [~ ~]
[%x %tiles ~] ``noun+!>([tiles tile-ordering])
[%x %first-time ~] ``noun+!>(first-time)
[%x %keys ~] ``noun+!>(~(key by tiles))
[%x %tiles ~] ``noun+!>([tiles tile-ordering])
[%x %first-time ~] ``noun+!>(first-time)
[%x %keys ~] ``noun+!>(~(key by tiles))
::
[%x %runtime-lag ~]
:^ ~ ~ %json
!> ^- json
b+.^(? //(scot %p our.bowl)//(scot %da now.bowl)/zen/lag)
==
::
++ on-arvo

View File

@ -8,6 +8,12 @@ export default class LocalApi extends BaseApi<StoreState> {
});
}
getRuntimeLag() {
return this.scry<boolean>('launch', '/runtime-lag').then((runtimeLag) => {
this.store.handleEvent({ data: { runtimeLag } });
});
}
dehydrate() {
this.store.dehydrate();
}

View File

@ -38,6 +38,13 @@ export default class LaunchReducer {
state.baseHash = baseHash;
})
}
const runtimeLag = _.get(json, 'runtimeLag', null);
if (runtimeLag !== null) {
useLaunchState.getState().set(state => {
state.runtimeLag = runtimeLag;
});
}
}
}

View File

@ -12,6 +12,7 @@ export interface LaunchState extends BaseState<LaunchState> {
weather: WeatherState | null | Record<string, never> | boolean,
userLocation: string | null;
baseHash: string | null;
runtimeLag: boolean;
};
const useLaunchState = createState<LaunchState>('Launch', {
@ -20,7 +21,8 @@ const useLaunchState = createState<LaunchState>('Launch', {
tiles: {},
weather: null,
userLocation: null,
baseHash: null
baseHash: null,
runtimeLag: false,
});

View File

@ -13,6 +13,10 @@ interface LocalUpdateBaseHash {
baseHash: string;
}
interface LocalUpdateRuntimeLag {
runtimeLag: boolean;
}
interface LocalUpdateBackgroundConfig {
backgroundConfig: BackgroundConfig;
}
@ -51,6 +55,7 @@ export type BackgroundConfig = BackgroundConfigUrl | BackgroundConfigColor | und
export type LocalUpdate =
| LocalUpdateSetDark
| LocalUpdateBaseHash
| LocalUpdateRuntimeLag
| LocalUpdateBackgroundConfig
| LocalUpdateHideAvatars
| LocalUpdateHideNicknames

View File

@ -106,6 +106,7 @@ class App extends React.Component {
this.updateTheme(this.themeWatcher);
}, 500);
this.api.local.getBaseHash();
this.api.local.getRuntimeLag(); //TODO consider polling periodically
this.api.settings.getAll();
gcpManager.start();
Mousetrap.bindGlobal(['command+/', 'ctrl+/'], (e) => {

View File

@ -47,7 +47,7 @@ const tutSelector = f.pick(['tutorialProgress', 'nextTutStep', 'hideGroups']);
export default function LaunchApp(props) {
const { connection } = props;
const baseHash = useLaunchState(state => state.baseHash);
const { baseHash, runtimeLag } = useLaunchState(state => state);
const [hashText, setHashText] = useState(baseHash);
const [exitingTut, setExitingTut] = useState(false);
const seen = useSettingsState(s => s?.tutorial?.seen) ?? true;
@ -82,7 +82,10 @@ export default function LaunchApp(props) {
}, 2000);
}}
>
<Box backgroundColor="washedGray" p={2}>
<Box
backgroundColor={runtimeLag ? 'yellow' : 'washedGray'}
p={2}
>
<Text mono bold>{hashText || baseHash}</Text>
</Box>
</Box>

View File

@ -4,7 +4,15 @@ import _ from 'lodash';
import moment from 'moment';
import { BigInteger } from 'big-integer';
import { Col, Center, Box, Text, LoadingSpinner } from '@tlon/indigo-react';
import {
Col,
Center,
Box,
Text,
LoadingSpinner,
Icon
} from '@tlon/indigo-react';
import {
Associations,
Notifications,
@ -23,6 +31,7 @@ import GlobalApi from '~/logic/api/global';
import { Notification } from './notification';
import { Invites } from './invites';
import { useLazyScroll } from '~/logic/lib/useLazyScroll';
import useLaunchState from '~/logic/state/launch';
import useHarkState from '~/logic/state/hark';
import useInviteState from '~/logic/state/invite';
import useMetadataState from '~/logic/state/metadata';
@ -65,6 +74,8 @@ export default function Inbox(props: {
};
}, []);
const runtimeLag = useLaunchState(state => state.runtimeLag);
const ready = useHarkState(
s => Object.keys(s.unreads.graph).length > 0
);
@ -122,6 +133,16 @@ export default function Inbox(props: {
return (
<Col p="1" ref={scrollRef} position="relative" height="100%" overflowY="auto">
{runtimeLag && (
<Box bg="yellow" borderRadius={2} p={2} m={2}>
<Icon verticalAlign="middle" mr={2} icon="Tutorial" />
<Text verticalAlign="middle">
Update your binary to continue receiving updates.
</Text>
</Box>
)}
<Invites pendingJoin={props.pendingJoin} api={api} />
{[...notificationsByDayMap.keys()].sort().reverse().map((day, index) => {
const timeboxes = notificationsByDayMap.get(day)!;

View File

@ -18,6 +18,7 @@ import { uxToHex } from '~/logic/lib/util';
import { ProfileStatus } from './ProfileStatus';
import { useTutorialModal } from './useTutorialModal';
import useLaunchState from '~/logic/state/launch';
import useHarkState from '~/logic/state/hark';
import useInviteState from '~/logic/state/invite';
import useContactState from '~/logic/state/contact';
@ -30,6 +31,7 @@ const localSel = selectLocalState(['toggleOmnibox']);
const StatusBar = (props) => {
const { api, ship } = props;
const history = useHistory();
const runtimeLag = useLaunchState(state => state.runtimeLag);
const ourContact = useContactState((state) => state.contacts[`~${ship}`]);
const notificationsCount = useHarkState((state) => state.notificationsCount);
const doNotDisturb = useHarkState((state) => state.doNotDisturb);
@ -86,6 +88,11 @@ const StatusBar = (props) => {
<Icon icon='Dashboard' color='black' />
</Button>
<StatusBarItem float={floatLeap} mr={2} onClick={() => toggleOmnibox()}>
{!doNotDisturb && runtimeLag && (
<Box display='block' right='-8px' top='-8px' position='absolute'>
<Icon color='yellow' icon='Bullet' />
</Box>
)}
{!doNotDisturb && (notificationsCount > 0 || invites.length > 0) && (
<Box display='block' right='-8px' top='-8px' position='absolute'>
<Icon color='blue' icon='Bullet' />

View File

@ -4,6 +4,7 @@ import defaultApps from '~/logic/lib/default-apps';
import Sigil from '~/logic/lib/sigil';
import { uxToHex, cite } from '~/logic/lib/util';
import withState from '~/logic/lib/withState';
import useLaunchState from '~/logic/state/launch';
import useHarkState from '~/logic/state/hark';
import useContactState from '~/logic/state/contact';
import useInviteState from '~/logic/state/invite';
@ -31,11 +32,13 @@ export class OmniboxResult extends Component {
}
}
getIcon(icon, selected, link, invites, notifications, text, color) {
getIcon(icon, selected, link, invites, notifications, lag, text, color) {
const iconFill =
this.state.hovered || selected === link ? 'white' : 'black';
const bulletFill =
this.state.hovered || selected === link ? 'white' : 'blue';
const lagFill =
this.state.hovered || selected === link ? 'white' : 'yellow';
const inviteCount = [].concat(
...Object.values(invites).map((obj) => Object.values(obj))
@ -70,6 +73,14 @@ export class OmniboxResult extends Component {
size='18px'
color={iconFill}
/>
{lag && (
<Icon
display='inline-block'
icon='Bullet'
style={{ position: 'absolute', top: -5, left: 5 }}
color={lagFill}
/>
)}
{(notifications > 0 || inviteCount.length > 0) && (
<Icon
display='inline-block'
@ -178,6 +189,7 @@ export class OmniboxResult extends Component {
selected,
invites,
notificationsCount,
runtimeLag,
contacts,
setSelection
} = this.props;
@ -191,6 +203,7 @@ export class OmniboxResult extends Component {
link,
invites,
notificationsCount,
runtimeLag,
text,
color
);
@ -252,6 +265,7 @@ export class OmniboxResult extends Component {
}
export default withState(OmniboxResult, [
[useLaunchState, ['runtimeLag']],
[useInviteState],
[useHarkState, ['notificationsCount']],
[useContactState]