diff --git a/package.json b/package.json index 3f28a885..dbb56e6d 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@tippyjs/react": "^4.2.6", "base64-js": "^1.5.1", "boring-avatars": "^1.6.1", + "graphql-request": "^3.7.0", "i18next": "^21.6.6", "i18next-browser-languagedetector": "^6.1.2", "mapbox-gl": "^2.6.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 742d17cc..b976e8be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,7 @@ specifiers: eslint-plugin-import: ^2.25.4 eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 + graphql-request: ^3.7.0 gzipper: ^6.2.1 i18next: ^21.6.6 i18next-browser-languagedetector: ^6.1.2 @@ -71,6 +72,7 @@ dependencies: '@tippyjs/react': 4.2.6_react-dom@17.0.2+react@17.0.2 base64-js: 1.5.1 boring-avatars: 1.6.1 + graphql-request: 3.7.0 i18next: 21.6.6 i18next-browser-languagedetector: 6.1.2 mapbox-gl: 2.6.1 @@ -2211,6 +2213,10 @@ packages: resolution: {integrity: sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=} dev: true + /asynckit/0.4.0: + resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + dev: false + /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} @@ -2449,6 +2455,13 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + /commander/2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true @@ -2509,6 +2522,12 @@ packages: yaml: 1.10.2 dev: true + /cross-fetch/3.1.4: + resolution: {integrity: sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==} + dependencies: + node-fetch: 2.6.1 + dev: false + /cross-spawn/7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -2618,6 +2637,11 @@ packages: resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=} dev: true + /delayed-stream/1.0.0: + resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} + engines: {node: '>=0.4.0'} + dev: false + /delegates/1.0.0: resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} dev: true @@ -3364,6 +3388,11 @@ packages: engines: {node: '>=6'} dev: true + /extract-files/9.0.0: + resolution: {integrity: sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==} + engines: {node: ^10.17.0 || ^12.0.0 || >= 13.7.0} + dev: false + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -3451,6 +3480,15 @@ packages: resolution: {integrity: sha1-C+4AUBiusmDQo6865ljdATbsG5k=} dev: true + /form-data/3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.34 + dev: false + /fraction.js/4.1.2: resolution: {integrity: sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==} dev: true @@ -3604,6 +3642,16 @@ packages: resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} dev: true + /graphql-request/3.7.0: + resolution: {integrity: sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==} + peerDependencies: + graphql: 14 - 16 + dependencies: + cross-fetch: 3.1.4 + extract-files: 9.0.0 + form-data: 3.0.1 + dev: false + /grid-index/1.1.0: resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==} dev: false @@ -4191,6 +4239,18 @@ packages: picomatch: 2.3.1 dev: true + /mime-db/1.51.0: + resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types/2.1.34: + resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.51.0 + dev: false + /mimic-response/2.1.0: resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} engines: {node: '>=8'} @@ -4270,6 +4330,11 @@ packages: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} dev: true + /node-fetch/2.6.1: + resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} + engines: {node: 4.x || >=6.0.0} + dev: false + /node-releases/2.0.1: resolution: {integrity: sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==} dev: true diff --git a/src/components/Channel.tsx b/src/components/Channel.tsx index 9787262c..ff995b8c 100644 --- a/src/components/Channel.tsx +++ b/src/components/Channel.tsx @@ -77,6 +77,7 @@ export const Channel = ({ channel }: ChannelProps): JSX.Element => { }); await connection.setChannel(channelData, (): Promise => { + reset({ ...data }); setLoading(false); return Promise.resolve(); }); diff --git a/src/core/slices/appSlice.ts b/src/core/slices/appSlice.ts index 799aeda8..d20717c8 100644 --- a/src/core/slices/appSlice.ts +++ b/src/core/slices/appSlice.ts @@ -23,6 +23,7 @@ interface Notification { interface AppState { mobileNavOpen: boolean; + navCollapsed: boolean; connectionModalOpen: boolean; darkMode: boolean; currentPage: currentPageName; @@ -37,6 +38,7 @@ interface AppState { const initialState: AppState = { mobileNavOpen: false, + navCollapsed: false, connectionModalOpen: true, darkMode: localStorage.getItem('darkMode') === 'true' ?? false, currentPage: 'messages', diff --git a/src/pages/Plugins/ExternalNotification.tsx b/src/pages/Plugins/ExternalNotification.tsx index 8bd2483d..5f739912 100644 --- a/src/pages/Plugins/ExternalNotification.tsx +++ b/src/pages/Plugins/ExternalNotification.tsx @@ -52,7 +52,11 @@ export const ExternalNotification = ({ }, [reset, preferences]); const onSubmit = handleSubmit((data) => { - void connection.setPreferences(data); + void connection.setPreferences(data, async (): Promise => { + //add loading indicator + reset({ ...data }); + await Promise.resolve(); + }); }); //todo, add loading indicator diff --git a/src/pages/Plugins/RangeTest.tsx b/src/pages/Plugins/RangeTest.tsx index 24624ce2..8a13849c 100644 --- a/src/pages/Plugins/RangeTest.tsx +++ b/src/pages/Plugins/RangeTest.tsx @@ -41,7 +41,11 @@ export const RangeTest = ({ }, [reset, preferences]); const onSubmit = handleSubmit((data) => { - void connection.setPreferences(data); + void connection.setPreferences(data, async (): Promise => { + //add loading indicator + reset({ ...data }); + await Promise.resolve(); + }); }); //todo, add loading indicator diff --git a/src/pages/Plugins/Serial.tsx b/src/pages/Plugins/Serial.tsx index 1bd705c4..b176a8b1 100644 --- a/src/pages/Plugins/Serial.tsx +++ b/src/pages/Plugins/Serial.tsx @@ -44,7 +44,11 @@ export const Serial = ({ navOpen, setNavOpen }: SerialProps): JSX.Element => { }, [reset, preferences]); const onSubmit = handleSubmit((data) => { - void connection.setPreferences(data); + void connection.setPreferences(data, async (): Promise => { + //add loading indicator + reset({ ...data }); + await Promise.resolve(); + }); }); //todo, add loading indicator diff --git a/src/pages/Plugins/StoreAndForward.tsx b/src/pages/Plugins/StoreAndForward.tsx index 9fefea6c..8379abde 100644 --- a/src/pages/Plugins/StoreAndForward.tsx +++ b/src/pages/Plugins/StoreAndForward.tsx @@ -39,7 +39,11 @@ export const StoreAndForward = ({ }, [reset, preferences]); const onSubmit = handleSubmit((data) => { - void connection.setPreferences(data); + void connection.setPreferences(data, async (): Promise => { + //add loading indicator + reset({ ...data }); + await Promise.resolve(); + }); }); //todo, add loading indicator diff --git a/src/pages/settings/Channels.tsx b/src/pages/settings/Channels.tsx index a79f6f0b..40344d3d 100644 --- a/src/pages/settings/Channels.tsx +++ b/src/pages/settings/Channels.tsx @@ -59,6 +59,7 @@ export const Channels = ({ }); await connection.setChannel(channelData, (): Promise => { + reset({ ...data }); setLoading(false); return Promise.resolve(); }); diff --git a/src/pages/settings/Position.tsx b/src/pages/settings/Position.tsx index bb905080..5da3fe52 100644 --- a/src/pages/settings/Position.tsx +++ b/src/pages/settings/Position.tsx @@ -62,8 +62,9 @@ export const Position = ({ const onSubmit = handleSubmit((data) => { setLoading(true); void connection.setPreferences(data, async () => { - await Promise.resolve(); + reset({ ...data }); setLoading(false); + await Promise.resolve(); }); }); diff --git a/src/pages/settings/Power.tsx b/src/pages/settings/Power.tsx index eca15374..3cbdc117 100644 --- a/src/pages/settings/Power.tsx +++ b/src/pages/settings/Power.tsx @@ -38,8 +38,9 @@ export const Power = ({ navOpen, setNavOpen }: PowerProps): JSX.Element => { const onSubmit = handleSubmit((data) => { setLoading(true); void connection.setPreferences(data, async () => { - await Promise.resolve(); + reset({ ...data }); setLoading(false); + await Promise.resolve(); }); }); return ( diff --git a/src/pages/settings/Radio.tsx b/src/pages/settings/Radio.tsx index f7cf1ea2..eeb8fab5 100644 --- a/src/pages/settings/Radio.tsx +++ b/src/pages/settings/Radio.tsx @@ -35,8 +35,9 @@ export const Radio = ({ navOpen, setNavOpen }: RadioProps): JSX.Element => { const onSubmit = handleSubmit((data) => { setLoading(true); void connection.setPreferences(data, async () => { - await Promise.resolve(); + reset({ ...data }); setLoading(false); + await Promise.resolve(); }); }); return ( diff --git a/src/pages/settings/User.tsx b/src/pages/settings/User.tsx index 9a4876eb..f449ad13 100644 --- a/src/pages/settings/User.tsx +++ b/src/pages/settings/User.tsx @@ -67,8 +67,9 @@ export const User = ({ navOpen, setNavOpen }: UserProps): JSX.Element => { if (node?.user) { void connection.setOwner({ ...node.user, ...data }, async () => { - await Promise.resolve(); + reset({ ...data }); setLoading(false); + await Promise.resolve(); }); // TODO: can be removed once getUser is implemented // dispatch( diff --git a/src/pages/settings/WiFi.tsx b/src/pages/settings/WiFi.tsx index 733e8dd0..d4db2d95 100644 --- a/src/pages/settings/WiFi.tsx +++ b/src/pages/settings/WiFi.tsx @@ -49,8 +49,9 @@ export const WiFi = ({ navOpen, setNavOpen }: WiFiProps): JSX.Element => { const onSubmit = handleSubmit((data) => { setLoading(true); void connection.setPreferences(data, async () => { - await Promise.resolve(); + reset({ ...data }); setLoading(false); + await Promise.resolve(); }); }); return (