From a0049bc95fe7176d17189ae36670cdea26f4153b Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Sun, 16 Mar 2025 22:26:23 +0530
Subject: [PATCH 01/20] Update ipns.js

---
 src/bundles/ipns.js | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/bundles/ipns.js b/src/bundles/ipns.js
index d05b8bd1a..7674efac0 100644
--- a/src/bundles/ipns.js
+++ b/src/bundles/ipns.js
@@ -47,14 +47,12 @@ const ipnsBundle = {
   doRemoveIpnsKey: (name) => async ({ getIpfs, store }) => {
     const ipfs = getIpfs()
     await ipfs.key.rm(name)
-
     store.doFetchIpnsKeys()
   },
 
   doRenameIpnsKey: (oldName, newName) => async ({ getIpfs, store }) => {
     const ipfs = getIpfs()
     await ipfs.key.rename(oldName, newName)
-
     store.doFetchIpnsKeys()
   },
 
@@ -63,9 +61,31 @@ const ipnsBundle = {
     await ipfs.name.publish(cid, { key })
   },
 
+  doImportIpnsKey: (file) => async ({ getIpfs, store }) => {
+    const ipfs = getIpfs()
+    const reader = new FileReader()
+    reader.onload = async (event) => {
+      const key = event.target.result
+      await ipfs.key.import(file.name, key)
+      store.doFetchIpnsKeys()
+    }
+    reader.readAsText(file)
+  },
+
+  doExportIpnsKey: (name) => async ({ getIpfs }) => {
+    const ipfs = getIpfs()
+    const key = await ipfs.key.export(name)
+    const blob = new Blob([key], { type: 'text/plain' })
+    const url = URL.createObjectURL(blob)
+    const a = document.createElement('a')
+    a.href = url
+    a.download = `${name}.key`
+    document.body.appendChild(a)
+    a.click()
+    document.body.removeChild(a)
+  },
+
   doUpdateExpectedPublishTime: (time) => async ({ store, dispatch }) => {
-    // moderate expectation: publishing should take no longer than average
-    // between old expectation and the length of the last publish + some buffer
     const oldExpectedTime = store.selectExpectedPublishTime()
     const avg = Math.floor((time * 1.5 + oldExpectedTime) / 2)
     await writeSetting('expectedPublishTime', avg)

From a80c661adb6cb0266da21c136a33a0fd10a958da Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Sun, 16 Mar 2025 22:28:04 +0530
Subject: [PATCH 02/20] Update IpnsManager.js

---
 src/components/ipns-manager/IpnsManager.js | 32 ++++++++++++++++++----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index 95c2075d3..c148423ce 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -9,7 +9,6 @@ import Overlay from '../overlay/Overlay.js'
 import GenerateKeyModal from './generate-key-modal/GenerateKeyModal.js'
 import RenameKeyModal from './rename-key-modal/RenameKeyModal.js'
 import RemoveKeyModal from './remove-key-modal/RemoveKeyModal.js'
-
 import ContextMenu from '../context-menu/ContextMenu.js'
 import ContextMenuItem from '../context-menu/ContextMenuItem.js'
 import GlyphDots from '../../icons/GlyphDots.js'
@@ -19,14 +18,14 @@ import StrokeCancel from '../../icons/StrokeCancel.js'
 const ROW_HEIGHT = 50
 const HEADER_HEIGHT = 32
 
-const AutoOptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => (
+const AutoOptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExportIpnsKey }) => (
   <div className='flex justify-end'>
     { name !== 'self' && <OptionsCell
-      name={name} t={t} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} /> }
+      name={name} t={t} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} doExportIpnsKey={doExportIpnsKey} /> }
   </div>
 )
 
-const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => {
+const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExportIpnsKey }) => {
   const buttonRef = useRef()
   const [isContextVisible, setContextVisibility] = useState(false)
 
@@ -48,12 +47,15 @@ const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => {
         <ContextMenuItem className='pv2 ph1' onClick={handle(showRemoveKeyModal)}>
           <StrokeCancel width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.remove')}</span>
         </ContextMenuItem>
+        <ContextMenuItem className='pv2 ph1' onClick={handle(doExportIpnsKey)}>
+          <StrokeCancel width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.export')}</span>
+        </ContextMenuItem>
       </ContextMenu>
     </div>
   )
 }
 
-export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, availableGateway, ipnsKeys }) => {
+export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, doImportIpnsKey, doExportIpnsKey, availableGateway, ipnsKeys }) => {
   const [isGenerateKeyModalOpen, setGenerateKeyModalOpen] = useState(false)
   const showGenerateKeyModal = () => setGenerateKeyModalOpen(true)
   const hideGenerateKeyModal = () => setGenerateKeyModalOpen(false)
@@ -81,6 +83,13 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
     (ipnsKeys || []).sort(sortByProperty(sortSettings.sortBy, sortSettings.sortDirection === SortDirection.ASC ? 1 : -1)),
   [ipnsKeys, sortSettings.sortBy, sortSettings.sortDirection])
 
+  const handleImportKey = (event) => {
+    const file = event.target.files[0]
+    if (file) {
+      doImportIpnsKey(file)
+    }
+  }
+
   return (
     <Fragment>
       <div className="mv4 pinningManager">
@@ -125,7 +134,7 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
                   dataKey='options'
                   width={width * 0.1}
                   flexShrink={1}
-                  cellRenderer={({ rowData }) => <AutoOptionsCell t={t} name={rowData.name} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} />}
+                  cellRenderer={({ rowData }) => <AutoOptionsCell t={t} name={rowData.name} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} doExportIpnsKey={() => doExportIpnsKey(rowData.name)} />}
                   className='pinningManagerColumn charcoal truncate f6 pl2' />
               </Table>
             )}
@@ -136,6 +145,15 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
           <Button className="tc mt2" bg='bg-navy' onClick={showGenerateKeyModal}>
             <span><span className="aqua">+</span> {t('actions.generateKey')}</span>
           </Button>
+          <input
+            type="file"
+            onChange={handleImportKey}
+            style={{ display: 'none' }}
+            id="ipns-key-import-input"
+          />
+          <label htmlFor="ipns-key-import-input" className="button ma2">
+            {t('app:actions.import')}
+          </label>
         </div>
       </div>
 
@@ -189,5 +207,7 @@ export default connect(
   'doGenerateIpnsKey',
   'doRemoveIpnsKey',
   'doRenameIpnsKey',
+  'doImportIpnsKey',
+  'doExportIpnsKey',
   IpnsManager
 )

From 4fab5e155961eb2dd4fbc114441d610258f8f71e Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Sun, 16 Mar 2025 22:35:56 +0530
Subject: [PATCH 03/20] Update IpnsManager.js


From 06d91758ba2747f220d19e685a1e2f3e8156147a Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Sun, 16 Mar 2025 22:37:49 +0530
Subject: [PATCH 04/20] Update settings.json

---
 public/locales/en/settings.json | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/public/locales/en/settings.json b/public/locales/en/settings.json
index b76ed9a7c..ae72e2686 100644
--- a/public/locales/en/settings.json
+++ b/public/locales/en/settings.json
@@ -66,7 +66,9 @@
     "save": "Save",
     "cancel": "Cancel",
     "enable": "Enable",
-    "disable": "Disable"
+    "disable": "Disable",
+    "import": "Import Key",
+    "export": "Export Key"
   },
   "edit": "Edit",
   "visitService": "Visit service",

From 3cbf55b9446c2446dff823b5683de3b911570e0c Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Tue, 18 Mar 2025 23:11:02 +0530
Subject: [PATCH 05/20] Update src/components/ipns-manager/IpnsManager.js

Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com>
---
 src/components/ipns-manager/IpnsManager.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index c148423ce..62e01a656 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -48,7 +48,7 @@ const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExport
           <StrokeCancel width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.remove')}</span>
         </ContextMenuItem>
         <ContextMenuItem className='pv2 ph1' onClick={handle(doExportIpnsKey)}>
-          <StrokeCancel width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.export')}</span>
+          <StrokeShare width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.export')}</span>
         </ContextMenuItem>
       </ContextMenu>
     </div>

From d2b141f5d647effd9c78fd77c44cc0b1683db52b Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Tue, 18 Mar 2025 23:11:33 +0530
Subject: [PATCH 06/20] Update src/components/ipns-manager/IpnsManager.js

Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com>
---
 src/components/ipns-manager/IpnsManager.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index 62e01a656..0a7b7e90f 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -145,7 +145,7 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
           <Button className="tc mt2" bg='bg-navy' onClick={showGenerateKeyModal}>
             <span><span className="aqua">+</span> {t('actions.generateKey')}</span>
           </Button>
-          <input
+          <Button
             type="file"
             onChange={handleImportKey}
             style={{ display: 'none' }}

From 2b6bdc74b3e39a24152bbf78277a9d72d4c2d635 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Wed, 19 Mar 2025 14:04:09 +0530
Subject: [PATCH 07/20] Update ipns.js

---
 src/bundles/ipns.js | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/src/bundles/ipns.js b/src/bundles/ipns.js
index 7674efac0..71a31d090 100644
--- a/src/bundles/ipns.js
+++ b/src/bundles/ipns.js
@@ -72,18 +72,7 @@ const ipnsBundle = {
     reader.readAsText(file)
   },
 
-  doExportIpnsKey: (name) => async ({ getIpfs }) => {
-    const ipfs = getIpfs()
-    const key = await ipfs.key.export(name)
-    const blob = new Blob([key], { type: 'text/plain' })
-    const url = URL.createObjectURL(blob)
-    const a = document.createElement('a')
-    a.href = url
-    a.download = `${name}.key`
-    document.body.appendChild(a)
-    a.click()
-    document.body.removeChild(a)
-  },
+ 
 
   doUpdateExpectedPublishTime: (time) => async ({ store, dispatch }) => {
     const oldExpectedTime = store.selectExpectedPublishTime()

From 4e9a56d5dbb486cd115c23c74605a40845c4f66e Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Wed, 19 Mar 2025 14:06:20 +0530
Subject: [PATCH 08/20] Update settings.json

---
 public/locales/en/settings.json | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/public/locales/en/settings.json b/public/locales/en/settings.json
index ae72e2686..d8c4f9825 100644
--- a/public/locales/en/settings.json
+++ b/public/locales/en/settings.json
@@ -67,8 +67,7 @@
     "cancel": "Cancel",
     "enable": "Enable",
     "disable": "Disable",
-    "import": "Import Key",
-    "export": "Export Key"
+    "import": "Import Key"    
   },
   "edit": "Edit",
   "visitService": "Visit service",

From 6b6bc0df97d2b19135822ab68170dce004f8e5b1 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Wed, 19 Mar 2025 14:12:11 +0530
Subject: [PATCH 09/20] Update IpnsManager.js

---
 src/components/ipns-manager/IpnsManager.js | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index 0a7b7e90f..6b4d6fd95 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -18,14 +18,14 @@ import StrokeCancel from '../../icons/StrokeCancel.js'
 const ROW_HEIGHT = 50
 const HEADER_HEIGHT = 32
 
-const AutoOptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExportIpnsKey }) => (
+const AutoOptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => (
   <div className='flex justify-end'>
     { name !== 'self' && <OptionsCell
-      name={name} t={t} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} doExportIpnsKey={doExportIpnsKey} /> }
+      name={name} t={t} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} /> }
   </div>
 )
 
-const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExportIpnsKey }) => {
+const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => {
   const buttonRef = useRef()
   const [isContextVisible, setContextVisibility] = useState(false)
 
@@ -47,15 +47,12 @@ const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal, doExport
         <ContextMenuItem className='pv2 ph1' onClick={handle(showRemoveKeyModal)}>
           <StrokeCancel width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.remove')}</span>
         </ContextMenuItem>
-        <ContextMenuItem className='pv2 ph1' onClick={handle(doExportIpnsKey)}>
-          <StrokeShare width="28" className='fill-aqua'/> <span className="ph1">{t('app:actions.export')}</span>
-        </ContextMenuItem>
       </ContextMenu>
     </div>
   )
 }
 
-export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, doImportIpnsKey, doExportIpnsKey, availableGateway, ipnsKeys }) => {
+export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, doImportIpnsKey, availableGateway, ipnsKeys }) => {
   const [isGenerateKeyModalOpen, setGenerateKeyModalOpen] = useState(false)
   const showGenerateKeyModal = () => setGenerateKeyModalOpen(true)
   const hideGenerateKeyModal = () => setGenerateKeyModalOpen(false)
@@ -134,7 +131,7 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
                   dataKey='options'
                   width={width * 0.1}
                   flexShrink={1}
-                  cellRenderer={({ rowData }) => <AutoOptionsCell t={t} name={rowData.name} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} doExportIpnsKey={() => doExportIpnsKey(rowData.name)} />}
+                  cellRenderer={({ rowData }) => <AutoOptionsCell t={t} name={rowData.name} showRenameKeyModal={showRenameKeyModal} showRemoveKeyModal={showRemoveKeyModal} />}
                   className='pinningManagerColumn charcoal truncate f6 pl2' />
               </Table>
             )}
@@ -145,7 +142,7 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
           <Button className="tc mt2" bg='bg-navy' onClick={showGenerateKeyModal}>
             <span><span className="aqua">+</span> {t('actions.generateKey')}</span>
           </Button>
-          <Button
+          <input
             type="file"
             onChange={handleImportKey}
             style={{ display: 'none' }}
@@ -208,6 +205,5 @@ export default connect(
   'doRemoveIpnsKey',
   'doRenameIpnsKey',
   'doImportIpnsKey',
-  'doExportIpnsKey',
   IpnsManager
 )

From a2b04ba9c7a302399628c545751c472d2c2b2489 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 00:55:59 +0530
Subject: [PATCH 10/20] Create hooks

---
 src/hooks | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 src/hooks

diff --git a/src/hooks b/src/hooks
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/hooks
@@ -0,0 +1 @@
+

From d350c44ac00e5861b5ebbc41227632ba2bc856b7 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 00:56:29 +0530
Subject: [PATCH 11/20] Delete src/hooks

---
 src/hooks | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 src/hooks

diff --git a/src/hooks b/src/hooks
deleted file mode 100644
index 8b1378917..000000000
--- a/src/hooks
+++ /dev/null
@@ -1 +0,0 @@
-

From cc6d74af7c266db33efdc84ea755f625f4f2b161 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 00:56:57 +0530
Subject: [PATCH 12/20] Create useShortcut.js

---
 src/hooks/useShortcut.js | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 src/hooks/useShortcut.js

diff --git a/src/hooks/useShortcut.js b/src/hooks/useShortcut.js
new file mode 100644
index 000000000..ef937fb8b
--- /dev/null
+++ b/src/hooks/useShortcut.js
@@ -0,0 +1,34 @@
+import { useState, useEffect, useRef } from 'react';
+
+const useShortcut = (props) => {
+  const dropdownMenuRef = useRef();
+  const [dropdown, setDropdown] = useState(false);
+
+  const wrap = (name, cliOptions) => () => {
+    if (name === 'onCliTutorMode' && cliOptions) {
+      props.doSetCliOptions(cliOptions);
+    }
+    props.handleClick();
+    props[name]();
+  };
+
+  useEffect(() => {
+    if (props.autofocus && props.isOpen) {
+      if (!dropdownMenuRef.current) return;
+
+      const firstButton = dropdownMenuRef.current.querySelector('button');
+      if (!firstButton) return;
+
+      firstButton.focus();
+    }
+  }, [props.autofocus, props.isOpen]);
+
+  return {
+    dropdownMenuRef,
+    dropdown,
+    setDropdown,
+    wrap
+  };
+};
+
+export default useShortcut;

From 6fd4629e43c89dab4b744bffb7ca07464f2e9d6e Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:00:02 +0530
Subject: [PATCH 13/20] Update cli-tutor-mode.js

---
 src/bundles/cli-tutor-mode.js | 69 ++++++++++-------------------------
 1 file changed, 20 insertions(+), 49 deletions(-)

diff --git a/src/bundles/cli-tutor-mode.js b/src/bundles/cli-tutor-mode.js
index d5b7e4e5c..2f428085c 100644
--- a/src/bundles/cli-tutor-mode.js
+++ b/src/bundles/cli-tutor-mode.js
@@ -1,74 +1,45 @@
-import { createAsyncResourceBundle, createSelector } from 'redux-bundler'
+import { createAsyncResourceBundle, createSelector } from 'redux-bundler';
+import useCliTutorMode from '../../hooks/useCliTutorMode';
 
 const bundle = createAsyncResourceBundle({
   name: 'cliTutorMode',
   actionBaseType: 'CLI_TUTOR_MODE_TOGGLE',
   persist: true,
   checkIfOnline: false,
-  getPromise: () => {}
-})
+  getPromise: () => {},
+});
 
 bundle.reactIsCliTutorModeEnabled = createSelector(
   'selectIsCliTutorModeEnabled',
   (isCliTutorModeEnabled) => {
-    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')))
+    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
 
     if (isCliTutorModeEnabled !== undefined && isCliTutorModeEnabled !== isEnabled) {
-      localStorage.setItem('isCliTutorModeEnabled', isCliTutorModeEnabled)
+      localStorage.setItem('isCliTutorModeEnabled', isCliTutorModeEnabled);
     }
   }
-)
+);
 
-bundle.selectIsCliTutorModeEnabled = state => state.cliTutorMode.isCliTutorModeEnabled
-
-bundle.selectIsCliTutorModalOpen = state => !!state.cliTutorMode.showCliTutorModal
-
-bundle.selectCliOptions = state => state.cliTutorMode.cliOptions
+bundle.selectIsCliTutorModeEnabled = state => state.cliTutorMode.isCliTutorModeEnabled;
+bundle.selectIsCliTutorModalOpen = state => !!state.cliTutorMode.showCliTutorModal;
+bundle.selectCliOptions = state => state.cliTutorMode.cliOptions;
 
 bundle.reducer = (state = {}, action) => {
   if (action.type === 'CLI_TUTOR_MODE_TOGGLE') {
-    return { ...state, isCliTutorModeEnabled: action.payload }
+    return { ...state, isCliTutorModeEnabled: action.payload };
   }
   if (action.type === 'CLI_TUTOR_MODAL_ENABLE') {
-    return { ...state, showCliTutorModal: action.payload }
+    return { ...state, showCliTutorModal: action.payload };
   }
   if (action.type === 'CLI_OPTIONS') {
-    return { ...state, cliOptions: action.payload }
+    return { ...state, cliOptions: action.payload };
   }
-
-  return state
-}
-
-bundle.doToggleCliTutorMode = key => ({ dispatch }) => {
-  dispatch({
-    type: 'CLI_TUTOR_MODE_TOGGLE',
-    payload: key
-  })
-}
-
-bundle.doSetCliOptions = cliOptions => ({ dispatch }) => {
-  dispatch({
-    type: 'CLI_OPTIONS',
-    payload: cliOptions
-  })
-}
-
-bundle.doOpenCliTutorModal = openModal => ({ dispatch }) => {
-  dispatch({
-    type: 'CLI_TUTOR_MODAL_ENABLE',
-    payload: openModal
-  })
-}
-
-bundle.doOpenCliTutorModal = openModal => ({ dispatch }) => {
-  dispatch({
-    type: 'CLI_TUTOR_MODAL_ENABLE',
-    payload: openModal
-  })
-}
+  return state;
+};
 
 bundle.init = store => {
-  const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')))
-  return store.doToggleCliTutorMode(isEnabled)
-}
-export default bundle
+  const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
+  return store.doToggleCliTutorMode(isEnabled);
+};
+
+export default bundle;

From 9fef7553f7fee34064a460c7086ccf4c0391dad2 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:00:33 +0530
Subject: [PATCH 14/20] Create useCliTutorMode.js

---
 src/hooks/useCliTutorMode.js | 47 ++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 src/hooks/useCliTutorMode.js

diff --git a/src/hooks/useCliTutorMode.js b/src/hooks/useCliTutorMode.js
new file mode 100644
index 000000000..cdce73a9c
--- /dev/null
+++ b/src/hooks/useCliTutorMode.js
@@ -0,0 +1,47 @@
+import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { createAsyncResourceBundle, createSelector } from 'redux-bundler';
+
+const useCliTutorMode = () => {
+  const dispatch = useDispatch();
+  const isCliTutorModeEnabled = useSelector(state => state.cliTutorMode.isCliTutorModeEnabled);
+  const showCliTutorModal = useSelector(state => !!state.cliTutorMode.showCliTutorModal);
+  const cliOptions = useSelector(state => state.cliTutorMode.cliOptions);
+
+  const doToggleCliTutorMode = (key) => {
+    dispatch({
+      type: 'CLI_TUTOR_MODE_TOGGLE',
+      payload: key,
+    });
+  };
+
+  const doSetCliOptions = (cliOptions) => {
+    dispatch({
+      type: 'CLI_OPTIONS',
+      payload: cliOptions,
+    });
+  };
+
+  const doOpenCliTutorModal = (openModal) => {
+    dispatch({
+      type: 'CLI_TUTOR_MODAL_ENABLE',
+      payload: openModal,
+    });
+  };
+
+  useEffect(() => {
+    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
+    doToggleCliTutorMode(isEnabled);
+  }, []);
+
+  return {
+    isCliTutorModeEnabled,
+    showCliTutorModal,
+    cliOptions,
+    doToggleCliTutorMode,
+    doSetCliOptions,
+    doOpenCliTutorModal,
+  };
+};
+
+export default useCliTutorMode;

From de63efdaeafcc8c1edeee87522bd71f45add8bb4 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:08:44 +0530
Subject: [PATCH 15/20] Update IpnsManager.js

---
 src/components/ipns-manager/IpnsManager.js | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index 6b4d6fd95..0f8eb768c 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -2,6 +2,7 @@ import React, { Fragment, useState, useRef, useMemo, useEffect } from 'react'
 import { connect } from 'redux-bundler-react'
 import { sortByProperty } from '../../lib/sort.js'
 import { AutoSizer, Table, Column, SortDirection } from 'react-virtualized'
+import useCliTutorMode from '../../hooks/useCliTutorMode' // Import the custom hook
 
 // Components
 import Button from '../button/button.tsx'
@@ -87,6 +88,16 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
     }
   }
 
+  // Use the CLI Tutor Mode hook
+  const {
+    isCliTutorModeEnabled,
+    showCliTutorModal,
+    cliOptions,
+    doToggleCliTutorMode,
+    doSetCliOptions,
+    doOpenCliTutorModal,
+  } = useCliTutorMode()
+
   return (
     <Fragment>
       <div className="mv4 pinningManager">

From 509eb4c83d2b0d224c501c7c6df5eee0295f3b19 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:11:18 +0530
Subject: [PATCH 16/20] Update CliTutorMode.js

---
 src/components/cli-tutor-mode/CliTutorMode.js | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/components/cli-tutor-mode/CliTutorMode.js b/src/components/cli-tutor-mode/CliTutorMode.js
index 6c7ae41e1..b03b3c44f 100644
--- a/src/components/cli-tutor-mode/CliTutorMode.js
+++ b/src/components/cli-tutor-mode/CliTutorMode.js
@@ -1,6 +1,7 @@
 import React, { Fragment } from 'react'
 import PropTypes from 'prop-types'
 import { connect } from 'redux-bundler-react'
+import useCliTutorMode from '../../hooks/useCliTutorMode' // Import the custom hook
 
 // Components
 import { Modal, ModalBody, ModalActions } from '../modal/Modal.js'
@@ -56,8 +57,14 @@ export const CliTutorialModal = ({ command, t, onLeave, className, downloadConfi
 }
 
 const CliTutorMode = ({
-  t, filesPage, isCliTutorModeEnabled, onLeave, isCliTutorModalOpen, command, config, showIcon, doOpenCliTutorModal
+  t, filesPage, onLeave, command, config, showIcon
 }) => {
+  const {
+    isCliTutorModeEnabled,
+    isCliTutorModalOpen,
+    doOpenCliTutorModal,
+  } = useCliTutorMode() // Use the custom hook
+
   const downloadConfig = (config) => {
     const url = window.URL.createObjectURL(new Blob([config]))
     const link = document.createElement('a')
@@ -102,8 +109,5 @@ CliTutorialModal.defaultProps = {
 }
 
 export default connect(
-  'doOpenCliTutorModal',
-  'selectIsCliTutorModalOpen',
-  'selectIsCliTutorModeEnabled',
   CliTutorMode
 )

From a043d45f1174f45224cf168f749e3ad23158d82a Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:28:54 +0530
Subject: [PATCH 17/20] Delete src/hooks directory

---
 src/hooks/useCliTutorMode.js | 47 ------------------------------------
 src/hooks/useShortcut.js     | 34 --------------------------
 2 files changed, 81 deletions(-)
 delete mode 100644 src/hooks/useCliTutorMode.js
 delete mode 100644 src/hooks/useShortcut.js

diff --git a/src/hooks/useCliTutorMode.js b/src/hooks/useCliTutorMode.js
deleted file mode 100644
index cdce73a9c..000000000
--- a/src/hooks/useCliTutorMode.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { useEffect } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { createAsyncResourceBundle, createSelector } from 'redux-bundler';
-
-const useCliTutorMode = () => {
-  const dispatch = useDispatch();
-  const isCliTutorModeEnabled = useSelector(state => state.cliTutorMode.isCliTutorModeEnabled);
-  const showCliTutorModal = useSelector(state => !!state.cliTutorMode.showCliTutorModal);
-  const cliOptions = useSelector(state => state.cliTutorMode.cliOptions);
-
-  const doToggleCliTutorMode = (key) => {
-    dispatch({
-      type: 'CLI_TUTOR_MODE_TOGGLE',
-      payload: key,
-    });
-  };
-
-  const doSetCliOptions = (cliOptions) => {
-    dispatch({
-      type: 'CLI_OPTIONS',
-      payload: cliOptions,
-    });
-  };
-
-  const doOpenCliTutorModal = (openModal) => {
-    dispatch({
-      type: 'CLI_TUTOR_MODAL_ENABLE',
-      payload: openModal,
-    });
-  };
-
-  useEffect(() => {
-    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
-    doToggleCliTutorMode(isEnabled);
-  }, []);
-
-  return {
-    isCliTutorModeEnabled,
-    showCliTutorModal,
-    cliOptions,
-    doToggleCliTutorMode,
-    doSetCliOptions,
-    doOpenCliTutorModal,
-  };
-};
-
-export default useCliTutorMode;
diff --git a/src/hooks/useShortcut.js b/src/hooks/useShortcut.js
deleted file mode 100644
index ef937fb8b..000000000
--- a/src/hooks/useShortcut.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { useState, useEffect, useRef } from 'react';
-
-const useShortcut = (props) => {
-  const dropdownMenuRef = useRef();
-  const [dropdown, setDropdown] = useState(false);
-
-  const wrap = (name, cliOptions) => () => {
-    if (name === 'onCliTutorMode' && cliOptions) {
-      props.doSetCliOptions(cliOptions);
-    }
-    props.handleClick();
-    props[name]();
-  };
-
-  useEffect(() => {
-    if (props.autofocus && props.isOpen) {
-      if (!dropdownMenuRef.current) return;
-
-      const firstButton = dropdownMenuRef.current.querySelector('button');
-      if (!firstButton) return;
-
-      firstButton.focus();
-    }
-  }, [props.autofocus, props.isOpen]);
-
-  return {
-    dropdownMenuRef,
-    dropdown,
-    setDropdown,
-    wrap
-  };
-};
-
-export default useShortcut;

From 952e349ffdd79f5682f2f150d8dc0fd63f1e509a Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:31:46 +0530
Subject: [PATCH 18/20] Update IpnsManager.js

---
 src/components/ipns-manager/IpnsManager.js | 31 ++--------------------
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/src/components/ipns-manager/IpnsManager.js b/src/components/ipns-manager/IpnsManager.js
index 0f8eb768c..95c2075d3 100644
--- a/src/components/ipns-manager/IpnsManager.js
+++ b/src/components/ipns-manager/IpnsManager.js
@@ -2,7 +2,6 @@ import React, { Fragment, useState, useRef, useMemo, useEffect } from 'react'
 import { connect } from 'redux-bundler-react'
 import { sortByProperty } from '../../lib/sort.js'
 import { AutoSizer, Table, Column, SortDirection } from 'react-virtualized'
-import useCliTutorMode from '../../hooks/useCliTutorMode' // Import the custom hook
 
 // Components
 import Button from '../button/button.tsx'
@@ -10,6 +9,7 @@ import Overlay from '../overlay/Overlay.js'
 import GenerateKeyModal from './generate-key-modal/GenerateKeyModal.js'
 import RenameKeyModal from './rename-key-modal/RenameKeyModal.js'
 import RemoveKeyModal from './remove-key-modal/RemoveKeyModal.js'
+
 import ContextMenu from '../context-menu/ContextMenu.js'
 import ContextMenuItem from '../context-menu/ContextMenuItem.js'
 import GlyphDots from '../../icons/GlyphDots.js'
@@ -53,7 +53,7 @@ const OptionsCell = ({ t, name, showRenameKeyModal, showRemoveKeyModal }) => {
   )
 }
 
-export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, doImportIpnsKey, availableGateway, ipnsKeys }) => {
+export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey, doRenameIpnsKey, doRemoveIpnsKey, availableGateway, ipnsKeys }) => {
   const [isGenerateKeyModalOpen, setGenerateKeyModalOpen] = useState(false)
   const showGenerateKeyModal = () => setGenerateKeyModalOpen(true)
   const hideGenerateKeyModal = () => setGenerateKeyModalOpen(false)
@@ -81,23 +81,6 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
     (ipnsKeys || []).sort(sortByProperty(sortSettings.sortBy, sortSettings.sortDirection === SortDirection.ASC ? 1 : -1)),
   [ipnsKeys, sortSettings.sortBy, sortSettings.sortDirection])
 
-  const handleImportKey = (event) => {
-    const file = event.target.files[0]
-    if (file) {
-      doImportIpnsKey(file)
-    }
-  }
-
-  // Use the CLI Tutor Mode hook
-  const {
-    isCliTutorModeEnabled,
-    showCliTutorModal,
-    cliOptions,
-    doToggleCliTutorMode,
-    doSetCliOptions,
-    doOpenCliTutorModal,
-  } = useCliTutorMode()
-
   return (
     <Fragment>
       <div className="mv4 pinningManager">
@@ -153,15 +136,6 @@ export const IpnsManager = ({ t, ipfsReady, doFetchIpnsKeys, doGenerateIpnsKey,
           <Button className="tc mt2" bg='bg-navy' onClick={showGenerateKeyModal}>
             <span><span className="aqua">+</span> {t('actions.generateKey')}</span>
           </Button>
-          <input
-            type="file"
-            onChange={handleImportKey}
-            style={{ display: 'none' }}
-            id="ipns-key-import-input"
-          />
-          <label htmlFor="ipns-key-import-input" className="button ma2">
-            {t('app:actions.import')}
-          </label>
         </div>
       </div>
 
@@ -215,6 +189,5 @@ export default connect(
   'doGenerateIpnsKey',
   'doRemoveIpnsKey',
   'doRenameIpnsKey',
-  'doImportIpnsKey',
   IpnsManager
 )

From 753a6a486f8f033547b3708f7c6d82d95d23e9c1 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:33:13 +0530
Subject: [PATCH 19/20] Update cli-tutor-mode.js

---
 src/bundles/cli-tutor-mode.js | 69 +++++++++++++++++++++++++----------
 1 file changed, 49 insertions(+), 20 deletions(-)

diff --git a/src/bundles/cli-tutor-mode.js b/src/bundles/cli-tutor-mode.js
index 2f428085c..d5b7e4e5c 100644
--- a/src/bundles/cli-tutor-mode.js
+++ b/src/bundles/cli-tutor-mode.js
@@ -1,45 +1,74 @@
-import { createAsyncResourceBundle, createSelector } from 'redux-bundler';
-import useCliTutorMode from '../../hooks/useCliTutorMode';
+import { createAsyncResourceBundle, createSelector } from 'redux-bundler'
 
 const bundle = createAsyncResourceBundle({
   name: 'cliTutorMode',
   actionBaseType: 'CLI_TUTOR_MODE_TOGGLE',
   persist: true,
   checkIfOnline: false,
-  getPromise: () => {},
-});
+  getPromise: () => {}
+})
 
 bundle.reactIsCliTutorModeEnabled = createSelector(
   'selectIsCliTutorModeEnabled',
   (isCliTutorModeEnabled) => {
-    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
+    const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')))
 
     if (isCliTutorModeEnabled !== undefined && isCliTutorModeEnabled !== isEnabled) {
-      localStorage.setItem('isCliTutorModeEnabled', isCliTutorModeEnabled);
+      localStorage.setItem('isCliTutorModeEnabled', isCliTutorModeEnabled)
     }
   }
-);
+)
 
-bundle.selectIsCliTutorModeEnabled = state => state.cliTutorMode.isCliTutorModeEnabled;
-bundle.selectIsCliTutorModalOpen = state => !!state.cliTutorMode.showCliTutorModal;
-bundle.selectCliOptions = state => state.cliTutorMode.cliOptions;
+bundle.selectIsCliTutorModeEnabled = state => state.cliTutorMode.isCliTutorModeEnabled
+
+bundle.selectIsCliTutorModalOpen = state => !!state.cliTutorMode.showCliTutorModal
+
+bundle.selectCliOptions = state => state.cliTutorMode.cliOptions
 
 bundle.reducer = (state = {}, action) => {
   if (action.type === 'CLI_TUTOR_MODE_TOGGLE') {
-    return { ...state, isCliTutorModeEnabled: action.payload };
+    return { ...state, isCliTutorModeEnabled: action.payload }
   }
   if (action.type === 'CLI_TUTOR_MODAL_ENABLE') {
-    return { ...state, showCliTutorModal: action.payload };
+    return { ...state, showCliTutorModal: action.payload }
   }
   if (action.type === 'CLI_OPTIONS') {
-    return { ...state, cliOptions: action.payload };
+    return { ...state, cliOptions: action.payload }
   }
-  return state;
-};
 
-bundle.init = store => {
-  const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')));
-  return store.doToggleCliTutorMode(isEnabled);
-};
+  return state
+}
+
+bundle.doToggleCliTutorMode = key => ({ dispatch }) => {
+  dispatch({
+    type: 'CLI_TUTOR_MODE_TOGGLE',
+    payload: key
+  })
+}
 
-export default bundle;
+bundle.doSetCliOptions = cliOptions => ({ dispatch }) => {
+  dispatch({
+    type: 'CLI_OPTIONS',
+    payload: cliOptions
+  })
+}
+
+bundle.doOpenCliTutorModal = openModal => ({ dispatch }) => {
+  dispatch({
+    type: 'CLI_TUTOR_MODAL_ENABLE',
+    payload: openModal
+  })
+}
+
+bundle.doOpenCliTutorModal = openModal => ({ dispatch }) => {
+  dispatch({
+    type: 'CLI_TUTOR_MODAL_ENABLE',
+    payload: openModal
+  })
+}
+
+bundle.init = store => {
+  const isEnabled = Boolean(JSON.parse(localStorage.getItem('isCliTutorModeEnabled')))
+  return store.doToggleCliTutorMode(isEnabled)
+}
+export default bundle

From da26389cc8aa4422b70e997891f059f5819b3fd2 Mon Sep 17 00:00:00 2001
From: Shobit garg <122355051+shobit000@users.noreply.github.com>
Date: Mon, 24 Mar 2025 01:35:01 +0530
Subject: [PATCH 20/20] Update CliTutorMode.js

---
 src/components/cli-tutor-mode/CliTutorMode.js | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/components/cli-tutor-mode/CliTutorMode.js b/src/components/cli-tutor-mode/CliTutorMode.js
index b03b3c44f..6c7ae41e1 100644
--- a/src/components/cli-tutor-mode/CliTutorMode.js
+++ b/src/components/cli-tutor-mode/CliTutorMode.js
@@ -1,7 +1,6 @@
 import React, { Fragment } from 'react'
 import PropTypes from 'prop-types'
 import { connect } from 'redux-bundler-react'
-import useCliTutorMode from '../../hooks/useCliTutorMode' // Import the custom hook
 
 // Components
 import { Modal, ModalBody, ModalActions } from '../modal/Modal.js'
@@ -57,14 +56,8 @@ export const CliTutorialModal = ({ command, t, onLeave, className, downloadConfi
 }
 
 const CliTutorMode = ({
-  t, filesPage, onLeave, command, config, showIcon
+  t, filesPage, isCliTutorModeEnabled, onLeave, isCliTutorModalOpen, command, config, showIcon, doOpenCliTutorModal
 }) => {
-  const {
-    isCliTutorModeEnabled,
-    isCliTutorModalOpen,
-    doOpenCliTutorModal,
-  } = useCliTutorMode() // Use the custom hook
-
   const downloadConfig = (config) => {
     const url = window.URL.createObjectURL(new Blob([config]))
     const link = document.createElement('a')
@@ -109,5 +102,8 @@ CliTutorialModal.defaultProps = {
 }
 
 export default connect(
+  'doOpenCliTutorModal',
+  'selectIsCliTutorModalOpen',
+  'selectIsCliTutorModeEnabled',
   CliTutorMode
 )