-
Recent Apps
-
-
-
Recent Developers
-
+
+
+
+
+
+
+ {!hasNotifications && }
+ {hasNotifications && (
+
+ {notifications.map((n) => renderNotification(n))}
+
+ )}
);
};
diff --git a/pkg/grid/src/nav/notifications/BasicNotification.tsx b/pkg/grid/src/nav/notifications/BasicNotification.tsx
new file mode 100644
index 000000000..64e9741c7
--- /dev/null
+++ b/pkg/grid/src/nav/notifications/BasicNotification.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import { BasicNotification as BasicNotificationType } from '../../state/hark-types';
+
+interface BasicNotificationProps {
+ notification: BasicNotificationType;
+}
+
+export const BasicNotification = ({ notification }: BasicNotificationProps) => (
+
{notification.message}
+);
diff --git a/pkg/grid/src/nav/notifications/SystemNotification.tsx b/pkg/grid/src/nav/notifications/SystemNotification.tsx
new file mode 100644
index 000000000..e4be4ece1
--- /dev/null
+++ b/pkg/grid/src/nav/notifications/SystemNotification.tsx
@@ -0,0 +1,37 @@
+import { pick } from 'lodash-es';
+import React from 'react';
+import { AppList } from '../../components/AppList';
+import { Elbow } from '../../components/icons/Elbow';
+import { useCharges } from '../../state/docket';
+import { SystemNotification as SystemNotificationType } from '../../state/hark-types';
+
+interface SystemNotificationProps {
+ notification: SystemNotificationType;
+}
+
+export const SystemNotification = ({ notification }: SystemNotificationProps) => {
+ const keys = notification.charges;
+ const charges = useCharges();
+ const blockedCharges = Object.values(pick(charges, keys));
+
+ return (
+
+
+
+
+ Landscape
+
+
+
+
+ The following ({blockedCharges.length}) apps blocked a System Update:
+
+
+
+
+
+ );
+};
diff --git a/pkg/grid/src/state/docket.ts b/pkg/grid/src/state/docket.ts
index f60ff5faf..be035ea24 100644
--- a/pkg/grid/src/state/docket.ts
+++ b/pkg/grid/src/state/docket.ts
@@ -22,6 +22,7 @@ import {
import { kilnRevive, kilnSuspend } from '@urbit/api/hood';
import api from './api';
import { mockAllies, mockCharges, mockTreaties } from './mock-data';
+import { fakeRequest } from './util';
const useMockData = import.meta.env.MODE === 'mock';
@@ -38,14 +39,6 @@ interface DocketState {
uninstallDocket: (desk: string) => Promise
;
}
-async function fakeRequest(data: T, time = 300): Promise {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve(data);
- }, time);
- });
-}
-
const useDocketState = create((set, get) => ({
fetchCharges: async () => {
const charg = useMockData
diff --git a/pkg/grid/src/state/hark-types.ts b/pkg/grid/src/state/hark-types.ts
new file mode 100644
index 000000000..d17c1f7d1
--- /dev/null
+++ b/pkg/grid/src/state/hark-types.ts
@@ -0,0 +1,18 @@
+/**
+ * I know this doesn't match our current hark type scheme, but since we're talking
+ * about changing that I decided to just throw something together to at least test
+ * this flow for updates.
+ */
+
+export interface SystemNotification {
+ type: 'system-updates-blocked';
+ charges: string[];
+}
+
+export interface BasicNotification {
+ type: 'basic';
+ time: string;
+ message: string;
+}
+
+export type Notification = BasicNotification | SystemNotification;
diff --git a/pkg/grid/src/state/hark.ts b/pkg/grid/src/state/hark.ts
new file mode 100644
index 000000000..b878cffba
--- /dev/null
+++ b/pkg/grid/src/state/hark.ts
@@ -0,0 +1,12 @@
+import create from 'zustand';
+import { Notification } from './hark-types';
+import { mockBlockedChargeNotification } from './mock-data';
+import { useMockData } from './util';
+
+interface HarkStore {
+ notifications: Notification[];
+}
+
+export const useHarkStore = create(() => ({
+ notifications: useMockData ? [mockBlockedChargeNotification] : []
+}));
diff --git a/pkg/grid/src/state/mock-data.ts b/pkg/grid/src/state/mock-data.ts
index 6f6728eaf..185962a2e 100644
--- a/pkg/grid/src/state/mock-data.ts
+++ b/pkg/grid/src/state/mock-data.ts
@@ -1,6 +1,7 @@
import _ from 'lodash-es';
import { Allies, Charges, DocketHrefGlob, Treaties, Treaty } from '@urbit/api/docket';
import systemUrl from '../assets/system.png';
+import { SystemNotification } from './hark-types';
export const appMetaData: Pick = {
cass: '~2021.8.11..05.11.10..b721',
@@ -149,3 +150,8 @@ export const mockAllies: Allies = [
'~nalrex_bannus',
'~nalrys'
].reduce((acc, val) => ({ ...acc, [val]: charter }), {});
+
+export const mockBlockedChargeNotification: SystemNotification = {
+ type: 'system-updates-blocked',
+ charges: ['~zod/groups', '~zod/pomodoro']
+};
diff --git a/pkg/grid/src/state/util.ts b/pkg/grid/src/state/util.ts
index 2ad28781f..1bfd52bdf 100644
--- a/pkg/grid/src/state/util.ts
+++ b/pkg/grid/src/state/util.ts
@@ -1,4 +1,4 @@
-import { DocketHref } from "@urbit/api/docket";
+import { DocketHref } from '@urbit/api/docket';
export function makeKeyFn(key: string) {
return (childKeys: string[] = []) => {
@@ -16,7 +16,6 @@ export async function fakeRequest(data: T, time = 300): Promise {
});
}
-
export function getAppHref(href: DocketHref) {
return 'site' in href ? href.site : `/apps/${href.glob.base}`;
}
diff --git a/pkg/grid/src/styles/components.css b/pkg/grid/src/styles/components.css
index 7ad7a9e3f..7f62df764 100644
--- a/pkg/grid/src/styles/components.css
+++ b/pkg/grid/src/styles/components.css
@@ -22,6 +22,10 @@
@apply min-w-52 p-4 rounded-xl;
}
+.notification {
+ @apply p-4 bg-gray-100 rounded-xl;
+}
+
.spinner {
@apply inline-flex items-center w-6 h-6 animate-spin;
}
diff --git a/pkg/grid/tailwind.config.js b/pkg/grid/tailwind.config.js
index 65122483b..555e92bcb 100644
--- a/pkg/grid/tailwind.config.js
+++ b/pkg/grid/tailwind.config.js
@@ -7,68 +7,61 @@ module.exports = {
theme: {
extend: {
colors: {
- transparent: "transparent",
- white: "#FFFFFF",
- black: "#000000",
+ transparent: 'transparent',
+ white: '#FFFFFF',
+ black: '#000000',
gray: {
...colors.trueGray,
- 100: "#F2F2F2",
- 200: "#CCCCCC",
- 300: "#B3B3B3",
- 400: "#808080",
- 500: "#666666",
+ 100: '#F2F2F2',
+ 200: '#CCCCCC',
+ 300: '#B3B3B3',
+ 400: '#808080',
+ 500: '#666666'
},
blue: {
- 100: "#E9F5FF",
- 200: "#D3EBFF",
- 300: "#BCE2FF",
- 400: "#219DFF",
+ 100: '#E9F5FF',
+ 200: '#D3EBFF',
+ 300: '#BCE2FF',
+ 400: '#219DFF'
},
red: {
- 100: "#FFF6F5",
- 200: "#FFC6C3",
- 400: "#FF4136",
+ 100: '#FFF6F5',
+ 200: '#FFC6C3',
+ 400: '#FF4136'
},
green: {
- 100: "#E6F5F0",
- 200: "#B3E2D1",
- 400: "#009F65",
+ 100: '#E6F5F0',
+ 200: '#B3E2D1',
+ 400: '#009F65'
},
yellow: {
- 100: "#FFF9E6",
- 200: "#FFEEB3",
- 300: "#FFDD66",
- 400: "#FFC700",
+ 100: '#FFF9E6',
+ 200: '#FFEEB3',
+ 300: '#FFDD66',
+ 400: '#FFC700'
},
+ orange: colors.orange
},
fontFamily: {
sans: [
'"Inter"',
'"Inter UI"',
- "-apple-system",
- "BlinkMacSystemFont",
+ '-apple-system',
+ 'BlinkMacSystemFont',
'"San Francisco"',
'"Helvetica Neue"',
- "Arial",
- "sans-serif",
- ],
- mono: [
- '"Source Code Pro"',
- '"Roboto mono"',
- '"Courier New"',
- "monospace",
+ 'Arial',
+ 'sans-serif'
],
+ mono: ['"Source Code Pro"', '"Roboto mono"', '"Courier New"', 'monospace']
},
- minWidth: theme => theme('spacing'),
- },
+ minWidth: (theme) => theme('spacing')
+ }
},
variants: {
extend: {
opacity: ['hover-none']
- },
+ }
},
- plugins: [
- require('@tailwindcss/aspect-ratio'),
- require('tailwindcss-touch')()
- ],
-}
+ plugins: [require('@tailwindcss/aspect-ratio'), require('tailwindcss-touch')()]
+};