@electerm/electerm-react 1.60.18 → 1.60.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/client/common/clipboard.js +1 -14
  2. package/client/common/constants.js +0 -43
  3. package/client/common/data-compare.js +55 -0
  4. package/client/common/default-setting.js +2 -10
  5. package/client/common/resolve.js +18 -22
  6. package/client/common/sftp.js +0 -3
  7. package/client/components/ai/ai-chat.jsx +30 -6
  8. package/client/components/ai/ai-config.jsx +17 -6
  9. package/client/components/batch-op/batch-op.jsx +3 -24
  10. package/client/components/bookmark-form/bookmark-group-tree-format.js +7 -9
  11. package/client/components/bookmark-form/form-ssh-common.jsx +0 -2
  12. package/client/components/bookmark-form/ssh-form.jsx +8 -41
  13. package/client/components/bookmark-form/tree-delete.jsx +1 -13
  14. package/client/components/common/animate-text.jsx +3 -4
  15. package/client/components/common/drag-handle.jsx +59 -45
  16. package/client/components/common/drag-handle.styl +2 -1
  17. package/client/components/common/input-auto-focus.jsx +29 -63
  18. package/client/components/common/ref.js +24 -0
  19. package/client/components/footer/batch-input.jsx +1 -6
  20. package/client/components/footer/footer-entry.jsx +13 -16
  21. package/client/components/footer/footer.styl +0 -5
  22. package/client/components/icons/ai-icon.jsx +17 -0
  23. package/client/components/icons/ai-icon.styl +3 -0
  24. package/client/components/layout/layout-item.jsx +14 -0
  25. package/client/components/main/main.jsx +8 -19
  26. package/client/components/main/upgrade.jsx +13 -25
  27. package/client/components/profile/profile-form-elem.jsx +1 -2
  28. package/client/components/quick-commands/on-drop.js +1 -12
  29. package/client/components/quick-commands/quick-command-transport-mod.jsx +3 -13
  30. package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -2
  31. package/client/components/rdp/rdp-session.jsx +4 -4
  32. package/client/components/session/session.jsx +9 -11
  33. package/client/components/setting-panel/on-tree-drop.js +4 -35
  34. package/client/components/setting-panel/setting-common.jsx +4 -1
  35. package/client/components/setting-panel/setting-modal.jsx +7 -5
  36. package/client/components/setting-panel/tab-settings.jsx +0 -1
  37. package/client/components/setting-sync/setting-sync.jsx +0 -1
  38. package/client/components/sftp/address-bookmark-item.jsx +1 -15
  39. package/client/components/sftp/confirm-modal-store.jsx +2 -2
  40. package/client/components/sftp/{file-mode-modal.jsx → file-info-modal.jsx} +137 -37
  41. package/client/components/sftp/file-item.jsx +156 -192
  42. package/client/components/sftp/file-table-header.jsx +98 -0
  43. package/client/components/sftp/list-table-ui.jsx +125 -416
  44. package/client/components/sftp/sftp-entry.jsx +102 -128
  45. package/client/components/sftp/sftp.styl +6 -22
  46. package/client/components/sftp/transfer-conflict-store.jsx +8 -12
  47. package/client/components/sftp/transport-action-store.jsx +7 -15
  48. package/client/components/shortcuts/shortcut-control.jsx +72 -3
  49. package/client/components/shortcuts/shortcut-handler.js +0 -1
  50. package/client/components/side-panel-r/side-panel-r.jsx +7 -4
  51. package/client/components/sidebar/bookmark-select.jsx +5 -3
  52. package/client/components/sidebar/history.jsx +3 -0
  53. package/client/components/sidebar/index.jsx +1 -1
  54. package/client/components/sidebar/info-modal.jsx +3 -0
  55. package/client/components/sidebar/side-panel.jsx +7 -4
  56. package/client/components/sidebar/sidebar-panel.jsx +1 -1
  57. package/client/components/sidebar/sidebar.styl +3 -3
  58. package/client/components/sys-menu/icons-map.jsx +52 -0
  59. package/client/components/{context-menu → sys-menu}/menu-btn.jsx +33 -45
  60. package/client/components/sys-menu/sys-menu.jsx +163 -0
  61. package/client/components/{context-menu/context-menu.styl → sys-menu/sys-menu.styl} +2 -11
  62. package/client/components/tabs/index.jsx +5 -97
  63. package/client/components/tabs/tab.jsx +121 -73
  64. package/client/components/tabs/tabs.styl +4 -1
  65. package/client/components/terminal/term-search.jsx +16 -28
  66. package/client/components/terminal/terminal-interactive.jsx +0 -2
  67. package/client/components/terminal/{index.jsx → terminal.jsx} +110 -240
  68. package/client/components/terminal-info/base.jsx +21 -46
  69. package/client/components/terminal-info/terminal-info.jsx +3 -0
  70. package/client/components/text-editor/text-editor.jsx +38 -53
  71. package/client/components/theme/theme-form.jsx +0 -2
  72. package/client/components/tree-list/bookmark-toolbar.jsx +23 -47
  73. package/client/components/tree-list/bookmark-transport.jsx +2 -90
  74. package/client/components/tree-list/move-item-modal.jsx +101 -0
  75. package/client/components/tree-list/tree-expander.jsx +2 -3
  76. package/client/components/tree-list/tree-list-item.jsx +8 -11
  77. package/client/components/tree-list/tree-list.jsx +75 -296
  78. package/client/components/vnc/vnc-session.jsx +5 -3
  79. package/client/store/app-upgrade.js +2 -5
  80. package/client/store/bookmark-group.js +116 -51
  81. package/client/store/common.js +36 -54
  82. package/client/store/event.js +4 -37
  83. package/client/store/init-state.js +9 -12
  84. package/client/store/item.js +34 -39
  85. package/client/store/load-data.js +5 -1
  86. package/client/store/quick-command.js +2 -12
  87. package/client/store/session.js +6 -7
  88. package/client/store/setting.js +3 -7
  89. package/client/store/sidebar.js +2 -8
  90. package/client/store/store.js +0 -20
  91. package/client/store/system-menu.js +1 -2
  92. package/client/store/tab.js +29 -1
  93. package/client/store/terminal-theme.js +0 -4
  94. package/client/store/watch.js +26 -4
  95. package/package.json +1 -1
  96. package/client/common/post-msg.js +0 -3
  97. package/client/components/common/native-input.jsx +0 -30
  98. package/client/components/context-menu/context-menu.jsx +0 -339
  99. package/client/components/sftp/file-props-modal.jsx +0 -210
  100. package/client/store/context-menu.js +0 -23
  101. /package/client/components/{context-menu → sys-menu}/boomarks.jsx +0 -0
  102. /package/client/components/{context-menu → sys-menu}/history.jsx +0 -0
  103. /package/client/components/{context-menu → sys-menu}/icon-holder.jsx +0 -0
  104. /package/client/components/{context-menu → sys-menu}/sub-tab-menu.jsx +0 -0
  105. /package/client/components/{context-menu → sys-menu}/tabs.jsx +0 -0
  106. /package/client/components/{context-menu → sys-menu}/zoom.jsx +0 -0
@@ -7,6 +7,7 @@ import {
7
7
  defaultBookmarkGroupId,
8
8
  settingMap
9
9
  } from '../common/constants'
10
+ import { action } from 'manate'
10
11
 
11
12
  export default Store => {
12
13
  Store.prototype.getBookmarkGroupsTotal = function () {
@@ -44,69 +45,133 @@ export default Store => {
44
45
  }
45
46
  }
46
47
 
47
- Store.prototype.delBookmarkGroup = function ({ id }) {
48
+ Store.prototype.delBookmarkGroup = action(function ({ id }) {
48
49
  const { store } = window
50
+
51
+ // Cannot delete default group
49
52
  if (id === defaultBookmarkGroupId) {
50
53
  return
51
54
  }
52
- let bookmarkGroups = store.bookmarkGroups
53
- const tobeDel = find(bookmarkGroups, bg => bg.id === id)
54
- if (!tobeDel) {
55
+
56
+ const { bookmarkGroups } = store
57
+ const index = bookmarkGroups.findIndex(bg => bg.id === id)
58
+
59
+ // If group not found, return
60
+ if (index === -1) {
55
61
  return
56
62
  }
57
- let groups = [tobeDel]
58
- if (
59
- tobeDel.level !== 2 &&
60
- tobeDel.bookmarkGroupIds &&
61
- tobeDel.bookmarkGroupIds.length > 0
62
- ) {
63
- const childs = bookmarkGroups.filter(
64
- bg => tobeDel.bookmarkGroupIds.includes(bg.id)
63
+
64
+ const tobeDel = bookmarkGroups[index]
65
+
66
+ // Find parent group
67
+ let parentGroup = null
68
+ if (tobeDel.level === 2) {
69
+ parentGroup = bookmarkGroups.find(bg =>
70
+ (bg.bookmarkGroupIds || []).includes(tobeDel.id)
65
71
  )
66
- groups = [
67
- ...groups,
68
- ...childs
72
+ }
73
+
74
+ // If no parent found, use default group
75
+ if (!parentGroup) {
76
+ parentGroup = bookmarkGroups.find(bg => bg.id === defaultBookmarkGroupId)
77
+ }
78
+
79
+ // Ensure parent group has bookmarkIds and bookmarkGroupIds arrays
80
+ if (!parentGroup.bookmarkIds) {
81
+ parentGroup.bookmarkIds = []
82
+ }
83
+ if (!parentGroup.bookmarkGroupIds) {
84
+ parentGroup.bookmarkGroupIds = []
85
+ }
86
+
87
+ // Transfer bookmarkIds to parent
88
+ if (tobeDel.bookmarkIds && tobeDel.bookmarkIds.length) {
89
+ parentGroup.bookmarkIds = [
90
+ ...new Set([...parentGroup.bookmarkIds, ...tobeDel.bookmarkIds])
69
91
  ]
70
92
  }
71
- const groupIds = groups.map(g => g.id)
72
- const updates = []
73
- const defaultCatIndex = tobeDel.level !== 2
74
- ? bookmarkGroups.findIndex(
75
- g => g.id === defaultBookmarkGroupId
76
- )
77
- : bookmarkGroups.findIndex(
78
- g => (g.bookmarkGroupIds || []).includes(tobeDel.id)
79
- )
80
- for (const g of groups) {
81
- if (g.bookmarkIds.length) {
82
- const def = bookmarkGroups[defaultCatIndex]
83
- def.bookmarkIds = [
84
- ...g.bookmarkIds,
85
- ...def.bookmarkIds
86
- ]
87
- updates.push({
88
- id: def.id,
89
- db: 'bookmarkGroups',
90
- upsert: false,
91
- update: {
92
- bookmarkIds: def.bookmarkIds
93
- }
94
- })
93
+
94
+ // Transfer child groups to parent
95
+ if (tobeDel.bookmarkGroupIds && tobeDel.bookmarkGroupIds.length) {
96
+ parentGroup.bookmarkGroupIds = [
97
+ ...new Set([...parentGroup.bookmarkGroupIds, ...tobeDel.bookmarkGroupIds])
98
+ ]
99
+ }
100
+
101
+ // Remove the group from bookmarkGroups
102
+ bookmarkGroups.splice(index, 1)
103
+
104
+ // Reset current group if it was deleted
105
+ if (id === store.currentBookmarkGroupId) {
106
+ store.currentBookmarkGroupId = parentGroup.id
107
+ }
108
+ })
109
+
110
+ Store.prototype.fixBookmarkGroups = function () {
111
+ const { store } = window
112
+ const { bookmarks, bookmarkGroups } = store
113
+
114
+ // Create sets for quick lookup
115
+ const bookmarkIds = new Set(bookmarks.map(b => b.id))
116
+ const groupIds = new Set(bookmarkGroups.map(g => g.id))
117
+
118
+ // Fix bookmarkGroups
119
+ for (const group of bookmarkGroups) {
120
+ // Fix bookmarkIds - remove non-existent bookmark references
121
+ if (group.bookmarkIds) {
122
+ group.bookmarkIds = group.bookmarkIds.filter(id => bookmarkIds.has(id))
123
+ } else {
124
+ group.bookmarkIds = []
125
+ }
126
+
127
+ // Fix bookmarkGroupIds - remove non-existent group references
128
+ if (group.bookmarkGroupIds) {
129
+ group.bookmarkGroupIds = group.bookmarkGroupIds.filter(id =>
130
+ groupIds.has(id) && id !== group.id // Prevent self-reference
131
+ )
132
+ } else {
133
+ group.bookmarkGroupIds = []
95
134
  }
96
135
  }
97
- bookmarkGroups = bookmarkGroups.filter(t => {
98
- return !groupIds.includes(t.id)
99
- })
100
- store.batchDbUpdate(updates)
101
- store.batchDbDel(groupIds.map(id => {
102
- return {
103
- id,
104
- db: 'bookmarkGroups'
136
+
137
+ // Find stray bookmarks (not belonging to any group)
138
+ const assignedBookmarkIds = new Set(
139
+ bookmarkGroups.reduce((acc, group) =>
140
+ [...acc, ...(group.bookmarkIds || [])],
141
+ [])
142
+ )
143
+ const defaultGroup = bookmarkGroups.find(g => g.id === defaultBookmarkGroupId)
144
+ const strayBookmarkIds = bookmarks
145
+ .map(b => b.id)
146
+ .filter(id => !assignedBookmarkIds.has(id))
147
+
148
+ // Add stray bookmarks to default group
149
+ if (strayBookmarkIds.length) {
150
+ if (defaultGroup) {
151
+ defaultGroup.bookmarkIds = [
152
+ ...new Set([...defaultGroup.bookmarkIds, ...strayBookmarkIds])
153
+ ]
105
154
  }
106
- }))
107
- store.setBookmarkGroups(bookmarkGroups)
108
- if (id === store.currentBookmarkGroupId) {
109
- store.currentBookmarkGroupId = ''
155
+ }
156
+
157
+ // Find stray groups (not belonging to any parent group and not being a top-level group)
158
+ const assignedGroupIds = new Set(
159
+ bookmarkGroups.reduce((acc, group) =>
160
+ [...acc, ...(group.bookmarkGroupIds || [])],
161
+ [])
162
+ )
163
+
164
+ const strayGroups = bookmarkGroups.filter(group =>
165
+ group.level === 2 && // Only check non-top-level groups
166
+ group.id !== defaultBookmarkGroupId && // Exclude default group
167
+ !assignedGroupIds.has(group.id) // Not assigned to any parent
168
+ )
169
+
170
+ // Find a suitable parent for stray groups
171
+ if (strayGroups.length) {
172
+ defaultGroup.bookmarkGroupIds = [
173
+ ...new Set([...defaultGroup.bookmarkGroupIds, ...strayGroups.map(g => g.id)])
174
+ ]
110
175
  }
111
176
  }
112
177
  }
@@ -4,18 +4,16 @@
4
4
 
5
5
  import handleError from '../common/error-handler'
6
6
  import { Modal } from 'antd'
7
- import { debounce, some } from 'lodash-es'
8
- import postMessage from '../common/post-msg'
7
+ import { debounce, some, get } from 'lodash-es'
9
8
  import {
10
- commonActions,
11
9
  modals,
12
10
  leftSidebarWidthKey,
13
11
  rightSidebarWidthKey,
14
12
  dismissDelKeyTipLsKey,
15
- connectionMap,
16
- terminalActions
13
+ connectionMap
17
14
  } from '../common/constants'
18
15
  import * as ls from '../common/safe-local-storage'
16
+ import { refs, refsStatic } from '../components/common/ref'
19
17
  import { action } from 'manate'
20
18
 
21
19
  const e = window.translate
@@ -34,21 +32,6 @@ export default Store => {
34
32
  window.store.setConfig(ext)
35
33
  }
36
34
 
37
- Store.prototype.openFileInfoModal = function (data) {
38
- postMessage({
39
- data,
40
- action: commonActions.showFileInfoModal
41
- })
42
- }
43
-
44
- Store.prototype.openFileModeModal = function (data, file) {
45
- postMessage({
46
- data,
47
- file,
48
- action: commonActions.showFileModeModal
49
- })
50
- }
51
-
52
35
  Store.prototype.openInfoPanel = action(function () {
53
36
  const { store } = window
54
37
  store.rightPanelVisible = true
@@ -56,13 +39,13 @@ export default Store => {
56
39
  store.openInfoPanelAction()
57
40
  })
58
41
 
59
- Store.prototype.openInfoPanelAction = action(function () {
42
+ Store.prototype.openInfoPanelAction = function () {
60
43
  const { store } = window
61
- postMessage({
62
- action: terminalActions.showInfoPanel,
63
- activeTabId: store.activeTabId
64
- })
65
- })
44
+ setTimeout(() => {
45
+ const term = refs.get('term-' + store.activeTabId)
46
+ term && term.handleShowInfo()
47
+ }, 300)
48
+ }
66
49
 
67
50
  Store.prototype.toggleAIConfig = function () {
68
51
  window.store.showAIConfig = !window.store.showAIConfig
@@ -108,35 +91,15 @@ export default Store => {
108
91
  window.store.showModal = modals.batchOps
109
92
  async function updateText () {
110
93
  const text = await window.fs.readFile(path)
111
- postMessage({
112
- action: commonActions.batchOp,
113
- batchOp: {
114
- func: 'setState',
115
- args: [
116
- {
117
- text
118
- }
119
- ]
120
- }
94
+ refsStatic.get('batch-op')?.setState({
95
+ text
121
96
  })
122
97
  }
123
98
  function queue () {
124
- postMessage({
125
- action: commonActions.batchOp,
126
- batchOp: {
127
- func: 'handleClick',
128
- args: []
129
- }
130
- })
99
+ refsStatic.get('batch-op')?.handleClick()
131
100
  }
132
101
  function run () {
133
- postMessage({
134
- action: commonActions.batchOp,
135
- batchOp: {
136
- func: 'handleExec',
137
- args: []
138
- }
139
- })
102
+ refsStatic.get('batch-op')?.handleExec()
140
103
  }
141
104
  try {
142
105
  setTimeout(updateText, 2000)
@@ -281,11 +244,20 @@ export default Store => {
281
244
  store.rightPanelTab = 'ai'
282
245
  }
283
246
 
247
+ Store.prototype.explainWithAi = function (txt) {
248
+ const { store } = window
249
+ store.handleOpenAIPanel()
250
+ setTimeout(() => {
251
+ refsStatic.get('AIChat')?.setPrompt(`explain terminal output: ${txt}`)
252
+ }, 500)
253
+ setTimeout(() => {
254
+ refsStatic.get('AIChat')?.handleSubmit()
255
+ }, 1200)
256
+ }
257
+
284
258
  Store.prototype.runCommandInTerminal = function (cmd) {
285
- postMessage({
286
- action: terminalActions.quickCommand,
287
- cmd,
288
- selectedTabIds: window.store.batchInputSelectedTabIds
259
+ window.store.batchInputSelectedTabIds.forEach(id => {
260
+ refs.get('term-' + id)?.runQuickCommand(cmd)
289
261
  })
290
262
  }
291
263
 
@@ -297,4 +269,14 @@ export default Store => {
297
269
  }
298
270
  window.store.aiChatHistory.splice(index, 1)
299
271
  }
272
+
273
+ Store.prototype.getLangName = function (
274
+ lang = window.store?.config.language || 'en_us'
275
+ ) {
276
+ return get(window.langMap, `[${lang}].name`)
277
+ }
278
+
279
+ Store.prototype.getLangNames = function () {
280
+ return window.et.langs.map(d => d.name)
281
+ }
300
282
  }
@@ -2,48 +2,18 @@
2
2
  * extend store
3
3
  */
4
4
 
5
- import postMessage from '../common/post-msg'
6
- import { commonActions } from '../common/constants'
5
+ import { refs } from '../components/common/ref'
7
6
 
8
7
  export default Store => {
9
- Store.prototype.initStoreEvents = function () {
10
- window.addEventListener('message', window.store.onStoreEvent)
11
- }
12
-
13
- Store.prototype.onStoreEvent = function (e) {
14
- const { store } = window
15
- const {
16
- action
17
- } = e.data || {}
18
- if (action !== commonActions.updateStore) {
19
- return false
20
- }
21
- const {
22
- func,
23
- prop,
24
- value,
25
- args = []
26
- } = e.data || {}
27
- if (func) {
28
- store[func](...args)
29
- } else if (prop) {
30
- store[prop] = value
31
- }
32
- }
33
-
34
8
  Store.prototype.focus = function () {
35
9
  window.focused = true
36
- postMessage({
37
- type: 'focus'
38
- })
10
+ refs.get('term-' + window.store.activeTabId)?.term?.focus()
39
11
  }
40
12
 
41
13
  Store.prototype.blur = function () {
42
14
  window.focused = false
43
15
  window.pre.runSync('windowMove', false)
44
- postMessage({
45
- type: 'blur'
46
- })
16
+ refs.get('term-' + window.store.activeTabId)?.term?.blur()
47
17
  }
48
18
 
49
19
  Store.prototype.onBlur = function () {
@@ -55,10 +25,7 @@ export default Store => {
55
25
  document.activeElement &&
56
26
  document.activeElement.select &&
57
27
  document.activeElement.select()
58
- postMessage({
59
- event: 'selectall',
60
- id: window.store.activeTabId
61
- })
28
+ refs.get('term-' + window.store.activeTabId)?.term?.selectAll()
62
29
  }
63
30
 
64
31
  Store.prototype.triggerResize = function () {
@@ -51,16 +51,14 @@ export default () => {
51
51
  activeTabId: '',
52
52
  history: ls.getItemJSON('history', []),
53
53
  sshConfigs: [],
54
- _bookmarks: '[]',
54
+ bookmarks: [],
55
55
  sidebarPanelTab: 'bookmarks',
56
- _profiles: '[]',
57
- _bookmarkGroups: JSON.stringify(
58
- getDefaultBookmarkGroups([])
59
- ),
56
+ profiles: [],
57
+ bookmarkGroups: getDefaultBookmarkGroups([]),
60
58
  _config: {},
61
- _terminalThemes: JSON.stringify([
59
+ terminalThemes: [
62
60
  buildDefaultThemes()
63
- ]),
61
+ ],
64
62
  itermThemes: exclude([]),
65
63
  currentBookmarkGroupId: defaultBookmarkGroupId,
66
64
  expandedKeys: ls.getItemJSON(expandedKeysLsKey, [
@@ -68,8 +66,8 @@ export default () => {
68
66
  ]),
69
67
  bookmarkSelectMode: false,
70
68
  checkedKeys: ls.getItemJSON(checkedKeysLsKey, []),
71
- _addressBookmarks: '[]',
72
- _addressBookmarksLocal: ls.getItem(localAddrBookmarkLsKey) || '[]',
69
+ addressBookmarks: [],
70
+ addressBookmarksLocal: ls.getItemJSON(localAddrBookmarkLsKey, []),
73
71
  openResolutionEdit: false,
74
72
  resolutions: ls.getItemJSON(resolutionsLsKey, []),
75
73
 
@@ -92,7 +90,7 @@ export default () => {
92
90
  sftpSortSetting: ls.getItemJSON(sftpDefaultSortSettingKey, {
93
91
  local: {
94
92
  prop: 'modifyTime',
95
- direction: 'asc'
93
+ direction: 'desc'
96
94
  },
97
95
  remote: {
98
96
  prop: 'modifyTime',
@@ -117,7 +115,6 @@ export default () => {
117
115
  _setting: '',
118
116
  settingItem: initSettingItem([], settingMap.bookmarks),
119
117
  settingTab: settingMap.bookmarks, // setting tab
120
- autofocustrigger: Date.now(),
121
118
  bookmarkId: undefined,
122
119
  showModal: 0,
123
120
 
@@ -142,7 +139,7 @@ export default () => {
142
139
  },
143
140
 
144
141
  // quick commands
145
- _quickCommands: '[]',
142
+ quickCommands: [],
146
143
  quickCommandId: '',
147
144
  openQuickCommandBar: false,
148
145
  pinnedQuickCommandBar: false,
@@ -3,11 +3,11 @@
3
3
  */
4
4
 
5
5
  import { find } from 'lodash-es'
6
+ import deepCopy from 'json-deep-copy'
6
7
  import {
7
8
  settingMap
8
9
  } from '../common/constants'
9
10
  import getInitItem from '../common/init-setting-item'
10
- import { update, remove, dbNames } from '../common/db'
11
11
 
12
12
  export default Store => {
13
13
  Store.prototype.addItem = function (item, type) {
@@ -16,22 +16,8 @@ export default Store => {
16
16
 
17
17
  Store.prototype.addItems = function (objs, type) {
18
18
  const { store } = window
19
- let items = store.getItems(type)
20
- items = [
21
- ...objs,
22
- ...items
23
- ]
24
- store.setItems(type, items)
25
- if (dbNames.includes(type)) {
26
- store.batchDbAdd(
27
- objs.map(obj => {
28
- return {
29
- db: type,
30
- obj
31
- }
32
- })
33
- )
34
- }
19
+ const items = store.getItems(type)
20
+ items.push(...objs)
35
21
  }
36
22
 
37
23
  Store.prototype.editItem = function (id, updates, type) {
@@ -42,31 +28,25 @@ export default Store => {
42
28
  return
43
29
  }
44
30
  Object.assign(item, updates)
45
- store.setItems(type, items)
46
- if (dbNames.includes(type)) {
47
- update(id, updates, type, false)
48
- }
49
31
  }
50
32
 
51
33
  Store.prototype.delItem = function ({ id }, type) {
52
34
  const { store } = window
53
- const items = store.getItems(type).filter(t => {
54
- return t.id !== id
55
- })
56
- store.setItems(type, items)
57
- if (dbNames.includes(type)) {
58
- remove(type, id)
35
+ const items = store.getItems(type)
36
+ const index = items.findIndex(t => t.id === id)
37
+ if (index < 0) {
38
+ return
59
39
  }
40
+ items.splice(index, 1)
60
41
  }
61
42
 
62
43
  Store.prototype.delItems = function (ids, type) {
63
44
  const { store } = window
64
- const items = store.getItems(type).filter(t => {
65
- return !ids.includes(t.id)
66
- })
67
- store.setItems(type, items)
68
- if (dbNames.includes(type)) {
69
- ids.map(id => remove(type, id))
45
+ const items = store.getItems(type)
46
+ for (let i = items.length - 1; i >= 0; i--) {
47
+ if (ids.includes(items[i].id)) {
48
+ items.splice(i, 1)
49
+ }
70
50
  }
71
51
  }
72
52
 
@@ -83,22 +63,37 @@ export default Store => {
83
63
  Store.prototype.getSidebarList = function (type) {
84
64
  const { store } = window
85
65
  if (type === settingMap.terminalThemes) {
86
- return [
66
+ return deepCopy([
87
67
  ...store.getTerminalThemes(),
88
68
  ...store.itermThemes
89
- ].sort(window.store.sortTheme)
69
+ ]).sort(window.store.sortTheme)
90
70
  }
91
- return store.getItems(type)
71
+ return deepCopy(store.getItems(type))
92
72
  }
93
73
 
94
74
  Store.prototype.getItems = function (type) {
95
75
  if (type === 'setting') {
96
76
  return window.store.setting
97
77
  }
98
- return JSON.parse(this['_' + type] || [])
78
+ return window.store[type]
99
79
  }
100
80
 
101
- Store.prototype.setItems = function (type, items) {
102
- this['_' + type] = JSON.stringify(items)
81
+ Store.prototype.setItems = function (type, arr) {
82
+ window.store[type] = arr
83
+ }
84
+
85
+ Store.prototype.adjustOrder = function (type, fromId, toId) {
86
+ const { store } = window
87
+ const items = store.getItems(type)
88
+ const fromIndex = items.findIndex(t => t.id === fromId)
89
+ let toIndex = items.findIndex(t => t.id === toId)
90
+ if (fromIndex < 0 || toIndex < 0 || fromIndex === toIndex) {
91
+ return
92
+ }
93
+ if (fromIndex < toIndex) {
94
+ toIndex = toIndex - 1
95
+ }
96
+ const [removed] = items.splice(fromIndex, 1)
97
+ items.splice(toIndex, 0, removed)
103
98
  }
104
99
  }
@@ -13,6 +13,7 @@ import runIdle from '../common/run-idle'
13
13
  import { initWsCommon } from '../common/fetch-from-server'
14
14
  import safeParse from '../common/parse-json-safe'
15
15
  import initWatch from './watch'
16
+ import { refsStatic } from '../components/common/ref'
16
17
 
17
18
  function getHost (argv, opts) {
18
19
  const arr = argv
@@ -185,11 +186,14 @@ export default (Store) => {
185
186
  await Promise.all(all)
186
187
  .then(arr => {
187
188
  for (const { name, data } of arr) {
188
- ext['_' + name] = data || '[]'
189
+ const dt = JSON.parse(data || '[]')
190
+ refsStatic.add('oldState-' + name, dt)
191
+ ext[name] = dt
189
192
  }
190
193
  })
191
194
  ext.lastDataUpdateTime = await getData('lastDataUpdateTime') || 0
192
195
  Object.assign(store, ext)
196
+ await store.fixBookmarkGroups()
193
197
 
194
198
  store.checkDefaultTheme()
195
199
  store.loadFontList()
@@ -5,20 +5,15 @@
5
5
  import {
6
6
  settingMap,
7
7
  qmSortByFrequencyKey,
8
- terminalActions,
9
8
  isWin
10
9
  } from '../common/constants'
11
10
  import delay from '../common/wait'
12
11
  import generate from '../common/uid'
13
- import postMessage from '../common/post-msg'
14
12
  import * as ls from '../common/safe-local-storage'
15
13
  import { debounce } from 'lodash-es'
14
+ import { refs } from '../components/common/ref'
16
15
 
17
16
  export default Store => {
18
- Store.prototype.setQuickCommands = function (list) {
19
- return window.store.setItems(settingMap.quickCommands, list)
20
- }
21
-
22
17
  Store.prototype.addQuickCommand = function (
23
18
  qm
24
19
  ) {
@@ -34,12 +29,7 @@ export default Store => {
34
29
  }
35
30
 
36
31
  Store.prototype.runQuickCommand = function (cmd, inputOnly = false) {
37
- postMessage({
38
- action: terminalActions.quickCommand,
39
- cmd,
40
- inputOnly,
41
- activeTabId: window.store.activeTabId
42
- })
32
+ refs.get('term-' + window.store.activeTabId)?.runQuickCommand(cmd, inputOnly)
43
33
  }
44
34
 
45
35
  Store.prototype.runQuickCommandItem = debounce(async (id) => {
@@ -2,16 +2,15 @@
2
2
  * sessions not proper closed related functions
3
3
  */
4
4
 
5
- import { terminalActions } from '../common/constants'
6
5
  import { debounce } from 'lodash-es'
7
- import postMsg from '../common/post-msg'
6
+ import { refs } from '../components/common/ref'
8
7
 
9
8
  export default Store => {
10
9
  Store.prototype.zoomTerminal = debounce(function (delta) {
11
- postMsg({
12
- action: terminalActions.zoom,
13
- zoomValue: delta > 0 ? 1 : -1,
14
- activeTabId: window.store.activeTabId
15
- })
10
+ const term = refs.get('term-' + window.store.activeTabId)
11
+ if (!term) {
12
+ return
13
+ }
14
+ term.zoom(delta > 0 ? 1 : -1)
16
15
  }, 500)
17
16
  }