Browse Source

WIP

pull/1/head
Sacha Weatherstone 5 years ago
parent
commit
f898b1dd49
  1. 6
      package.json
  2. 2
      src/App.tsx
  3. 19
      src/components/ChatMessage.tsx
  4. 17
      src/components/MessageBox.tsx
  5. 13
      src/components/Sidebar.tsx
  6. 6
      src/components/Sidebar/Device/Settings.tsx
  7. 2
      src/components/Sidebar/Nodes/Index.tsx
  8. 4
      src/components/Sidebar/Nodes/Node.tsx
  9. 3
      src/components/basic/Dropdown.tsx
  10. 7
      src/index.tsx
  11. 7
      src/slices/appSlice.ts
  12. 6
      src/slices/meshtasticSlice.ts
  13. 8
      src/store.ts
  14. 2
      tsconfig.json
  15. 34
      yarn.lock

6
package.json

@ -13,14 +13,14 @@
"dependencies": { "dependencies": {
"@headlessui/react": "^1.3.0", "@headlessui/react": "^1.3.0",
"@heroicons/react": "^1.0.1", "@heroicons/react": "^1.0.1",
"@meshtastic/meshtasticjs": "^0.6.15", "@meshtastic/meshtasticjs": "^0.6.16",
"@reduxjs/toolkit": "^1.6.0", "@reduxjs/toolkit": "^1.6.0",
"boring-avatars": "^1.5.8", "boring-avatars": "^1.5.8",
"framer-motion": "^4.1.17", "framer-motion": "^4.1.17",
"i18next": "^20.3.5", "i18next": "^20.3.5",
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"react": "^18.0.0-alpha-6bf111772-20210701", "react": "^17.0.2",
"react-dom": "^18.0.0-alpha-6bf111772-20210701", "react-dom": "^17.0.2",
"react-flags-select": "^2.1.2", "react-flags-select": "^2.1.2",
"react-hook-form": "^7.9.0", "react-hook-form": "^7.9.0",
"react-i18next": "^11.11.4", "react-i18next": "^11.11.4",

2
src/App.tsx

@ -11,7 +11,6 @@ import {
addNode, addNode,
setDeviceStatus, setDeviceStatus,
setLastMeshInterraction, setLastMeshInterraction,
setMyId,
setMyNodeInfo, setMyNodeInfo,
setPreferences, setPreferences,
setReady, setReady,
@ -45,7 +44,6 @@ const App = (): JSX.Element => {
connection.onMyNodeInfo.subscribe((nodeInfo) => { connection.onMyNodeInfo.subscribe((nodeInfo) => {
dispatch(setMyNodeInfo(nodeInfo)); dispatch(setMyNodeInfo(nodeInfo));
dispatch(setMyId(nodeInfo.myNodeNum));
}); });
connection.onNodeInfoPacket.subscribe((nodeInfoPacket) => connection.onNodeInfoPacket.subscribe((nodeInfoPacket) =>

19
src/components/ChatMessage.tsx

@ -15,11 +15,11 @@ interface ChatMessageProps {
} }
export const ChatMessage = (props: ChatMessageProps): JSX.Element => { export const ChatMessage = (props: ChatMessageProps): JSX.Element => {
const myId = useAppSelector((state) => state.meshtastic.myId); const myNodeInfo = useAppSelector((state) => state.meshtastic.myNodeInfo);
const nodes = useAppSelector((state) => state.meshtastic.nodes); const nodes = useAppSelector((state) => state.meshtastic.nodes);
const node = nodes.find((node) => { const node = nodes.find((node) => {
node.num === props.message.message.packet.from; return node.num === props.message.message.packet.from;
}); });
return ( return (
@ -39,8 +39,8 @@ export const ChatMessage = (props: ChatMessageProps): JSX.Element => {
} }
> >
<div <div
className={`px-4 py-2 rounded-md shadow-md ${ className={`px-4 py-2 rounded-3xl shadow-md ${
props.message.message.packet.from !== myId props.message.message.packet.from !== myNodeInfo.myNodeNum
? 'bg-gray-300' ? 'bg-gray-300'
: 'bg-green-200' : 'bg-green-200'
}`} }`}
@ -58,11 +58,12 @@ export const ChatMessage = (props: ChatMessageProps): JSX.Element => {
</div> </div>
<div className="flex justify-between text-gray-600"> <div className="flex justify-between text-gray-600">
<span className="inline-block">{props.message.message.data}</span> <span className="inline-block">{props.message.message.data}</span>
{props.message.ack ? ( {node?.num === myNodeInfo.myNodeNum &&
<CheckCircleIcon className="my-auto w-5 h-5" /> (props.message.ack ? (
) : ( <CheckCircleIcon className="my-auto w-5 h-5" />
<DotsCircleHorizontalIcon className="my-auto animate-pulse w-5 h-5" /> ) : (
)} <DotsCircleHorizontalIcon className="my-auto animate-pulse w-5 h-5" />
))}
</div> </div>
</div> </div>
</React.Suspense> </React.Suspense>

17
src/components/MessageBox.tsx

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { MenuIcon, PaperAirplaneIcon } from '@heroicons/react/outline'; import { MenuIcon, PaperAirplaneIcon } from '@heroicons/react/outline';
@ -22,14 +23,18 @@ export const MessageBox = (): JSX.Element => {
return ( return (
<div className="flex text-lg font-medium space-x-2 md:space-x-0 w-full"> <div className="flex text-lg font-medium space-x-2 md:space-x-0 w-full">
<div <motion.button
className="flex p-3 text-xl hover:text-gray-500 text-gray-400 rounded-md border shadow-md focus:outline-none cursor-pointer md:hidden" initial={{}}
whileHover={{
backgroundColor: 'rgba(229, 231, 235)',
}}
className="flex h-14 w-14 text-xl hover:text-gray-500 text-gray-400 rounded-full border shadow-md focus:outline-none cursor-pointer md:hidden"
onClick={() => { onClick={() => {
dispatch(toggleSidebar()); dispatch(toggleSidebar());
}} }}
> >
<MenuIcon className="m-auto h-6 2-6" /> <MenuIcon className="m-auto h-6 w-6" />
</div> </motion.button>
<form <form
className="flex flex-wrap relative w-full" className="flex flex-wrap relative w-full"
onSubmit={(e) => { onSubmit={(e) => {
@ -46,11 +51,11 @@ export const MessageBox = (): JSX.Element => {
onChange={(e) => { onChange={(e) => {
setCurrentMessage(e.target.value); setCurrentMessage(e.target.value);
}} }}
className={`p-3 placeholder-gray-400 text-gray-700 relative rounded-md border shadow-md focus:outline-none w-full pr-10 ${ className={`p-3 placeholder-gray-400 text-gray-700 relative rounded-3xl border shadow-md focus:outline-none w-full pr-10 ${
ready ? 'cursor-text' : 'cursor-not-allowed' ready ? 'cursor-text' : 'cursor-not-allowed'
}`} }`}
/> />
<span className="flex z-10 h-full text-gray-400 absolute w-8 right-0"> <span className="flex z-10 h-full text-gray-400 absolute w-8 right-1">
<PaperAirplaneIcon <PaperAirplaneIcon
onClick={sendMessage} onClick={sendMessage}
className={`text-xl hover:text-gray-500 h-6 w-6 my-auto ${ className={`text-xl hover:text-gray-500 h-6 w-6 my-auto ${

13
src/components/Sidebar.tsx

@ -15,9 +15,16 @@ export const Sidebar = (): JSX.Element => {
<AnimatePresence> <AnimatePresence>
{sidebarOpen && ( {sidebarOpen && (
<motion.div <motion.div
className={`${ initial={{
sidebarOpen ? 'flex' : 'hidden md:flex' height: 0,
} flex-col rounded-md md:ml-0 shadow-md border w-full max-w-sm`} }}
animate={{
height: 'auto',
}}
exit={{
height: 0,
}}
className="flex flex-col rounded-3xl md:ml-0 shadow-md border w-full md:max-w-sm"
> >
<Nodes /> <Nodes />
<Device /> <Device />

6
src/components/Sidebar/Device/Settings.tsx

@ -23,7 +23,7 @@ export const Settings = (): JSX.Element => {
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b"> <div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{t('strings.device_region')}</div> <div className="my-auto">{t('strings.device_region')}</div>
<div className="flex shadow-md rounded-md ml-2"> <div className="flex shadow-md rounded-3xl ml-2">
<select <select
{...register('region', { {...register('region', {
valueAsNumber: true, valueAsNumber: true,
@ -61,13 +61,13 @@ export const Settings = (): JSX.Element => {
</div> </div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b"> <div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{t('strings.wifi_ssid')}</div> <div className="my-auto">{t('strings.wifi_ssid')}</div>
<div className="flex shadow-md rounded-md ml-2"> <div className="flex shadow-md rounded-3xl ml-2">
<input {...register('wifiSsid', {})} type="text" /> <input {...register('wifiSsid', {})} type="text" />
</div> </div>
</div> </div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b"> <div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{t('strings.wifi_psk')}</div> <div className="my-auto">{t('strings.wifi_psk')}</div>
<div className="flex shadow-md rounded-md ml-2"> <div className="flex shadow-md rounded-3xl ml-2">
<input {...register('wifiPassword', {})} type="password" /> <input {...register('wifiPassword', {})} type="password" />
</div> </div>
</div> </div>

2
src/components/Sidebar/Nodes/Index.tsx

@ -12,7 +12,7 @@ export const Nodes = (): JSX.Element => {
return ( return (
<Dropdown <Dropdown
icon={<UsersIcon className="my-auto text-gray-600 mr-2 w-5 h-5" />} icon={<UsersIcon className="my-auto text-gray-600 mr-2 w-5 h-5" />}
title={t('placeholder.no_nodes')} title={t('strings.nodes')}
content={<NodeList />} content={<NodeList />}
fallbackMessage={t('placeholder.no_messages')} fallbackMessage={t('placeholder.no_messages')}
/> />

4
src/components/Sidebar/Nodes/Node.tsx

@ -20,7 +20,7 @@ export interface NodeProps {
} }
export const Node = (props: NodeProps): JSX.Element => { export const Node = (props: NodeProps): JSX.Element => {
const myId = useAppSelector((state) => state.meshtastic.myId); const myNodeInfo = useAppSelector((state) => state.meshtastic.myNodeInfo);
return ( return (
<Disclosure> <Disclosure>
@ -34,7 +34,7 @@ export const Node = (props: NodeProps): JSX.Element => {
<ChevronRightIcon className="my-auto w-5 h-5 mr-2" /> <ChevronRightIcon className="my-auto w-5 h-5 mr-2" />
)} )}
<div className="relative"> <div className="relative">
{props.node.num === myId ? ( {props.node.num === myNodeInfo.myNodeNum ? (
<FlagIcon className="absolute -right-1 -top-2 text-yellow-500 my-auto w-4 h-4" /> <FlagIcon className="absolute -right-1 -top-2 text-yellow-500 my-auto w-4 h-4" />
) : null} ) : null}
<Avatar <Avatar

3
src/components/basic/Dropdown.tsx

@ -17,7 +17,7 @@ export const Dropdown = (props: DropdownProps): JSX.Element => {
<Disclosure> <Disclosure>
{({ open }) => ( {({ open }) => (
<> <>
<Disclosure.Button className="bg-white flex w-full text-lg font-medium justify-between p-3 border-b hover:bg-gray-200 cursor-pointer"> <Disclosure.Button className="flex w-full text-lg font-medium justify-between p-3 border-b hover:bg-gray-200 cursor-pointer first:rounded-t-3xl last:rounded-b-3xl">
<div className="flex"> <div className="flex">
<motion.div <motion.div
className="my-auto mr-2" className="my-auto mr-2"
@ -41,7 +41,6 @@ export const Dropdown = (props: DropdownProps): JSX.Element => {
{open && ( {open && (
<Disclosure.Panel <Disclosure.Panel
as={motion.div} as={motion.div}
static
initial={{ initial={{
height: 0, height: 0,
}} }}

7
src/index.tsx

@ -9,16 +9,13 @@ import { Provider } from 'react-redux';
import App from './App'; import App from './App';
import { store } from './store'; import { store } from './store';
const rootElement = document.getElementById('root'); ReactDOM.render(
if (!rootElement) throw new Error('Failed to find the root element');
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode> <React.StrictMode>
<Provider store={store}> <Provider store={store}>
<App /> <App />
</Provider> </Provider>
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root'),
); );
// Hot Module Replacement (HMR) - Remove this snippet to remove HMR. // Hot Module Replacement (HMR) - Remove this snippet to remove HMR.

7
src/slices/appSlice.ts

@ -1,7 +1,5 @@
import { createSlice } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit';
import type { RootState } from '../store';
interface AppState { interface AppState {
sidebarOpen: boolean; sidebarOpen: boolean;
darkMode: boolean; darkMode: boolean;
@ -13,7 +11,7 @@ const initialState: AppState = {
}; };
export const appSlice = createSlice({ export const appSlice = createSlice({
name: 'auth', name: 'app',
initialState, initialState,
reducers: { reducers: {
openSidebar(state) { openSidebar(state) {
@ -29,6 +27,5 @@ export const appSlice = createSlice({
}); });
export const { openSidebar, closeSidebar, toggleSidebar } = appSlice.actions; export const { openSidebar, closeSidebar, toggleSidebar } = appSlice.actions;
export const selectOpenState = (state: RootState): boolean =>
state.app.sidebarOpen;
export default appSlice.reducer; export default appSlice.reducer;

6
src/slices/meshtasticSlice.ts

@ -4,7 +4,6 @@ import { createSlice } from '@reduxjs/toolkit';
interface AppState { interface AppState {
deviceStatus: Types.DeviceStatusEnum; deviceStatus: Types.DeviceStatusEnum;
myId: number;
lastMeshInterraction: number; lastMeshInterraction: number;
ready: boolean; ready: boolean;
fromRaioPackets: Protobuf.FromRadio[]; fromRaioPackets: Protobuf.FromRadio[];
@ -23,7 +22,6 @@ interface AppState {
const initialState: AppState = { const initialState: AppState = {
deviceStatus: Types.DeviceStatusEnum.DEVICE_DISCONNECTED, deviceStatus: Types.DeviceStatusEnum.DEVICE_DISCONNECTED,
myId: 0,
lastMeshInterraction: 0, lastMeshInterraction: 0,
ready: false, ready: false,
fromRaioPackets: [], fromRaioPackets: [],
@ -47,9 +45,6 @@ export const meshtasticSlice = createSlice({
setDeviceStatus: (state, action: PayloadAction<Types.DeviceStatusEnum>) => { setDeviceStatus: (state, action: PayloadAction<Types.DeviceStatusEnum>) => {
state.deviceStatus = action.payload; state.deviceStatus = action.payload;
}, },
setMyId: (state, action: PayloadAction<number>) => {
state.myId = action.payload;
},
setLastMeshInterraction: (state, action: PayloadAction<number>) => { setLastMeshInterraction: (state, action: PayloadAction<number>) => {
state.lastMeshInterraction = action.payload; state.lastMeshInterraction = action.payload;
}, },
@ -119,7 +114,6 @@ export const meshtasticSlice = createSlice({
export const { export const {
setDeviceStatus, setDeviceStatus,
setMyId,
setLastMeshInterraction, setLastMeshInterraction,
setReady, setReady,
addFromRadioPacket, addFromRadioPacket,

8
src/store.ts

@ -1,12 +1,12 @@
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import appSlice from './slices/appSlice'; import appReducer from './slices/appSlice';
import meshtasticSlice from './slices/meshtasticSlice'; import meshtasticReducer from './slices/meshtasticSlice';
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
app: appSlice, app: appReducer,
meshtastic: meshtasticSlice, meshtastic: meshtasticReducer,
}, },
middleware: (getDefaultMiddleware) => middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({ getDefaultMiddleware({

2
tsconfig.json

@ -19,7 +19,7 @@
"strict": true, "strict": true,
"strictNullChecks": true, "strictNullChecks": true,
"skipLibCheck": true, "skipLibCheck": true,
"types": ["react/next", "react-dom/next", "snowpack-env"], "types": ["snowpack-env"],
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,

34
yarn.lock

@ -278,10 +278,10 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
"@meshtastic/meshtasticjs@^0.6.15": "@meshtastic/meshtasticjs@^0.6.16":
version "0.6.15" version "0.6.16"
resolved "https://registry.yarnpkg.com/@meshtastic/meshtasticjs/-/meshtasticjs-0.6.15.tgz#4bb45a5c501cade542134e7f63fb5b960e68dc67" resolved "https://registry.yarnpkg.com/@meshtastic/meshtasticjs/-/meshtasticjs-0.6.16.tgz#aa2fe3808af90b4c4aa43d2e2223dbf420977c65"
integrity sha512-nelWkWb9DhWS7CffDatIUaPjL4vj+AsMAGqdeKoTm+sCRooi2+7V2bt2Pppl2obfSbE1hl+HdDoSntzvxeXo6A== integrity sha512-nozIJJYdxouDBCWTJtF3oKPqkuJbL8lA9xTuzpSCVz4MRzlNPiSxc0O4C4lwwBrDEi9uymn+DJbub/lWv8m+wA==
dependencies: dependencies:
"@protobuf-ts/runtime" "^1.0.13" "@protobuf-ts/runtime" "^1.0.13"
sub-events "^1.8.9" sub-events "^1.8.9"
@ -4130,14 +4130,14 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
react-dom@^18.0.0-alpha-6bf111772-20210701: react-dom@^17.0.2:
version "18.0.0-alpha-ed6c091fe-20210701" version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0-alpha-ed6c091fe-20210701.tgz#f07510c6b0a5fa38ce2ab48d39caf39e8cc320d8" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
integrity sha512-AdtHYY5PRP8KNe7ijIwTSG5ckip0+h6kksvy+8K/mV+VHYEYUIrfaerrZzFOuV/oeJxnM2zXh9/93cheAjJ2UQ== integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
scheduler "0.21.0-alpha-ed6c091fe-20210701" scheduler "^0.20.2"
react-flags-select@^2.1.2: react-flags-select@^2.1.2:
version "2.1.2" version "2.1.2"
@ -4181,10 +4181,10 @@ react-refresh@^0.9.0:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==
react@^18.0.0-alpha-6bf111772-20210701: react@^17.0.2:
version "18.0.0-alpha-ed6c091fe-20210701" version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-18.0.0-alpha-ed6c091fe-20210701.tgz#238c16a3262b0d30f5c9483335b42a28656c1e81" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
integrity sha512-zfb1gZyRC0AxtNLb48jM1zPhP60OS79Jekj28Qve/HaogOp9a/hjoC6THx4YXtEdP4bq6Z/OS+ecAeJ8I4JSug== integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
@ -4433,10 +4433,10 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
scheduler@0.21.0-alpha-ed6c091fe-20210701: scheduler@^0.20.2:
version "0.21.0-alpha-ed6c091fe-20210701" version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0-alpha-ed6c091fe-20210701.tgz#281f04c3d2b0276b528c1c04c3e51f68db4241f6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
integrity sha512-DBDJeyzJXEWV1AvQr8Jw/66q9RNyMjCeVVRrOtGZb6iqHeI5Up9aWK08K5KZlbemkr8dVlD9fIDDTzxTZZpd2Q== integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"

Loading…
Cancel
Save