vue-layout-gitcode 1.12.66 → 1.12.67

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.
@@ -252,19 +252,25 @@ const getBrowserStorage = () => {
252
252
  let localStorage$1;
253
253
  {
254
254
  const data = {};
255
+ const fallbackKeys = /* @__PURE__ */ new Set();
255
256
  localStorage$1 = {
256
257
  setItem(id, val) {
257
- var _a;
258
- data[id] = String(val);
258
+ const value = String(val);
259
+ data[id] = value;
260
+ fallbackKeys.add(id);
259
261
  try {
260
- (_a = getBrowserStorage()) == null ? void 0 : _a.setItem(id, String(val));
262
+ const storage = getBrowserStorage();
263
+ if (storage) {
264
+ storage.setItem(id, value);
265
+ fallbackKeys.delete(id);
266
+ }
261
267
  } catch {
262
268
  }
263
269
  },
264
270
  getItem(id) {
265
271
  try {
266
272
  const storage = getBrowserStorage();
267
- if (storage) {
273
+ if (storage && !fallbackKeys.has(id)) {
268
274
  return storage.getItem(id);
269
275
  }
270
276
  } catch {
@@ -274,6 +280,7 @@ let localStorage$1;
274
280
  removeItem(id) {
275
281
  var _a;
276
282
  delete data[id];
283
+ fallbackKeys.delete(id);
277
284
  try {
278
285
  (_a = getBrowserStorage()) == null ? void 0 : _a.removeItem(id);
279
286
  } catch {
@@ -286,6 +293,7 @@ let localStorage$1;
286
293
  } catch {
287
294
  }
288
295
  Object.keys(data).forEach((key) => delete data[key]);
296
+ fallbackKeys.clear();
289
297
  },
290
298
  get length() {
291
299
  try {
@@ -10206,7 +10214,7 @@ const _hoisted_5$l = { class: "float-tooltip" };
10206
10214
  const _hoisted_6$k = { class: "float-tooltip-content" };
10207
10215
  const _hoisted_7$h = { class: "float-tooltip" };
10208
10216
  const _hoisted_8$f = { class: "float-tooltip-content" };
10209
- const _hoisted_9$e = { class: "float-tooltip" };
10217
+ const _hoisted_9$d = { class: "float-tooltip" };
10210
10218
  const _hoisted_10$a = { class: "float-tooltip-content" };
10211
10219
  const _hoisted_11$8 = { class: "float-tooltip" };
10212
10220
  const _hoisted_12$8 = { class: "float-tooltip-content" };
@@ -10491,7 +10499,7 @@ const _sfc_main$U = /* @__PURE__ */ defineComponent({
10491
10499
  createElementVNode("path", { d: "M14.6182 12.3893H12.2961C12.0184 12.3893 11.7934 12.1643 11.7934 11.8865L11.7881 5.96621C11.7564 3.89551 10.0742 2.31523 8 2.30469C5.92578 2.31523 4.24355 3.89551 4.21016 5.96621L4.20664 11.1025C4.20664 11.1025 4.85527 13.342 6.40039 13.0818C6.51816 12.6898 6.93301 12.5422 7.2002 12.5422H8.82793C9.3834 12.5422 9.8334 12.9922 9.8334 13.5477V13.8623C9.8334 14.4178 9.3834 14.8678 8.82793 14.8678H7.33027C6.90488 14.8678 6.54277 14.6006 6.39512 14.2262C6.37051 14.2121 6.17012 14.2297 5.97324 14.1875C4.44922 13.6426 3.78125 12.3822 3.78125 12.3822C3.75488 12.3875 3.72852 12.391 3.70215 12.391H1.38184C1.1041 12.391 0.879102 12.166 0.879102 11.8883V6.73437C0.879102 6.45664 1.1041 6.23164 1.38184 6.23164H3.04121C3.04121 5.80625 3.03945 5.96445 3.03945 5.96445C3.09922 1.1498 7.91738 1.13398 7.91738 1.13398C7.95605 1.13223 8.0457 1.13223 8.08262 1.13398C8.08262 1.13398 12.9008 1.15156 12.9605 5.96445C12.9605 5.96445 12.9605 5.80449 12.9588 6.23164H14.6182C14.8959 6.23164 15.1209 6.45664 15.1209 6.73437V11.8865C15.1209 12.1643 14.8959 12.3893 14.6182 12.3893ZM3.14492 7.70469C3.14492 7.53418 3.05352 7.39531 2.94102 7.39531H2.0832C1.9707 7.39531 1.8793 7.53418 1.8793 7.70469V10.8775C1.8793 11.0498 1.9707 11.1869 2.0832 11.1869H2.94102C3.05352 11.1869 3.14492 11.048 3.14492 10.8775V7.70469ZM14.1207 7.70469C14.1207 7.53418 14.0293 7.39531 13.9168 7.39531H13.0607C12.9482 7.39531 12.8551 7.53418 12.8551 7.70469V10.8775C12.8551 11.0498 12.9482 11.1869 13.0607 11.1869H13.9168C14.0293 11.1869 14.1207 11.048 14.1207 10.8775V7.70469Z" })
10492
10500
  ])
10493
10501
  ], -1)),
10494
- createElementVNode("div", _hoisted_9$e, [
10502
+ createElementVNode("div", _hoisted_9$d, [
10495
10503
  createElementVNode("span", _hoisted_10$a, toDisplayString$1(unref(t2)("gitCodeLayout.home.userFeedback01")), 1),
10496
10504
  _cache[9] || (_cache[9] = createElementVNode("span", { class: "float-tooltip-arrow" }, null, -1))
10497
10505
  ])
@@ -14338,7 +14346,7 @@ const _hoisted_8$e = {
14338
14346
  alt: "mirrors-avatar",
14339
14347
  class: "header-custom-mirrors-img-tall"
14340
14348
  };
14341
- const _hoisted_9$d = { class: "g-repo-breadcrumb-container" };
14349
+ const _hoisted_9$c = { class: "g-repo-breadcrumb-container" };
14342
14350
  const _hoisted_10$9 = {
14343
14351
  key: 0,
14344
14352
  class: "header-custom-breadcrumb-row"
@@ -14646,7 +14654,7 @@ const _sfc_main$P = /* @__PURE__ */ defineComponent({
14646
14654
  }),
14647
14655
  _: 1
14648
14656
  }, 8, ["href"]),
14649
- createElementVNode("div", _hoisted_9$d, [
14657
+ createElementVNode("div", _hoisted_9$c, [
14650
14658
  !((_b2 = __props.repoProps) == null ? void 0 : _b2.isGhMirrors) ? (openBlock(), createElementBlock("div", {
14651
14659
  key: 0,
14652
14660
  ref_key: "breadcrumbRef",
@@ -14948,7 +14956,7 @@ const _hoisted_5$j = {
14948
14956
  const _hoisted_6$i = ["href", "onClick", "onKeydown"];
14949
14957
  const _hoisted_7$f = { class: "dashboard-create-menu__title-row" };
14950
14958
  const _hoisted_8$d = { class: "dashboard-create-menu__title" };
14951
- const _hoisted_9$c = {
14959
+ const _hoisted_9$b = {
14952
14960
  key: 0,
14953
14961
  class: "dashboard-create-menu__desc"
14954
14962
  };
@@ -15196,7 +15204,7 @@ const _sfc_main$M = /* @__PURE__ */ defineComponent({
15196
15204
  }, null, 8, ["name"]),
15197
15205
  createElementVNode("span", _hoisted_8$d, toDisplayString$1(item.label), 1)
15198
15206
  ]),
15199
- item.desc ? (openBlock(), createElementBlock("div", _hoisted_9$c, toDisplayString$1(item.desc), 1)) : createCommentVNode("", true)
15207
+ item.desc ? (openBlock(), createElementBlock("div", _hoisted_9$b, toDisplayString$1(item.desc), 1)) : createCommentVNode("", true)
15200
15208
  ], 42, _hoisted_6$i)
15201
15209
  ], 64);
15202
15210
  }), 128))
@@ -15355,7 +15363,7 @@ const _hoisted_5$i = { class: "message-item-info-content" };
15355
15363
  const _hoisted_6$h = { class: "message-item-body" };
15356
15364
  const _hoisted_7$e = ["title", "innerHTML"];
15357
15365
  const _hoisted_8$c = ["title"];
15358
- const _hoisted_9$b = { class: "message-item-info" };
15366
+ const _hoisted_9$a = { class: "message-item-info" };
15359
15367
  const _hoisted_10$8 = { class: "message-item-rightTx message-item-date" };
15360
15368
  const _sfc_main$J = /* @__PURE__ */ defineComponent({
15361
15369
  __name: "index",
@@ -15415,7 +15423,7 @@ const _sfc_main$J = /* @__PURE__ */ defineComponent({
15415
15423
  ]),
15416
15424
  _: 1
15417
15425
  }, 8, ["href", "class"]),
15418
- createElementVNode("div", _hoisted_9$b, [
15426
+ createElementVNode("div", _hoisted_9$a, [
15419
15427
  createVNode(GText, null, {
15420
15428
  default: withCtx(() => [
15421
15429
  createTextVNode(toDisplayString$1(__props.data.repo), 1)
@@ -15464,7 +15472,7 @@ const _hoisted_8$b = {
15464
15472
  key: 0,
15465
15473
  class: "g-number"
15466
15474
  };
15467
- const _hoisted_9$a = {
15475
+ const _hoisted_9$9 = {
15468
15476
  key: 0,
15469
15477
  class: "g-number"
15470
15478
  };
@@ -15833,7 +15841,7 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
15833
15841
  onClick: _cache[4] || (_cache[4] = ($event) => switchMentionSubTab("discussion"))
15834
15842
  }, [
15835
15843
  _cache[9] || (_cache[9] = createTextVNode(" 在线讨论 ", -1)),
15836
- mentionSubTabCount.value.discussion > 0 ? (openBlock(), createElementBlock("span", _hoisted_9$a, toDisplayString$1(mentionSubTabCount.value.discussion), 1)) : createCommentVNode("", true)
15844
+ mentionSubTabCount.value.discussion > 0 ? (openBlock(), createElementBlock("span", _hoisted_9$9, toDisplayString$1(mentionSubTabCount.value.discussion), 1)) : createCommentVNode("", true)
15837
15845
  ], 2)
15838
15846
  ])) : createCommentVNode("", true),
15839
15847
  listData.value.length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(listData.value, (item) => {
@@ -16182,9 +16190,8 @@ const _hoisted_5$f = {
16182
16190
  class: "g-account-switch-status"
16183
16191
  };
16184
16192
  const _hoisted_6$e = ["disabled", "aria-label", "title", "onClick"];
16185
- const _hoisted_7$b = { class: "g-account-switch-actions" };
16193
+ const _hoisted_7$b = ["disabled"];
16186
16194
  const _hoisted_8$9 = ["disabled"];
16187
- const _hoisted_9$9 = ["disabled"];
16188
16195
  const _sfc_main$D = /* @__PURE__ */ defineComponent({
16189
16196
  __name: "AccountSessionList",
16190
16197
  props: {
@@ -16236,7 +16243,9 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
16236
16243
  }, "×", 8, _hoisted_6$e)
16237
16244
  ]);
16238
16245
  }), 128)),
16239
- createElementVNode("div", _hoisted_7$b, [
16246
+ createElementVNode("div", {
16247
+ class: normalizeClass(["g-account-switch-actions", { "g-account-switch-actions--divided": otherAccounts.value.length }])
16248
+ }, [
16240
16249
  canAdd.value ? (openBlock(), createElementBlock("button", {
16241
16250
  key: 0,
16242
16251
  type: "button",
@@ -16244,23 +16253,12 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
16244
16253
  disabled: __props.busy,
16245
16254
  onClick: _cache[0] || (_cache[0] = ($event) => emit("add"))
16246
16255
  }, [
16247
- _cache[2] || (_cache[2] = createElementVNode("svg", {
16248
- width: "18",
16249
- height: "18",
16250
- viewBox: "0 0 24 24",
16251
- fill: "none",
16252
- "aria-hidden": "true"
16253
- }, [
16254
- createElementVNode("path", {
16255
- d: "M15 20v-2a5 5 0 0 0-10 0v2M10 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8m9-6v6m-3-3h6",
16256
- stroke: "currentColor",
16257
- "stroke-width": "1.7",
16258
- "stroke-linecap": "round",
16259
- "stroke-linejoin": "round"
16260
- })
16261
- ], -1)),
16256
+ createVNode(GIcon, {
16257
+ name: "gt-plane-users",
16258
+ size: "16px"
16259
+ }),
16262
16260
  createTextVNode(toDisplayString$1(unref(t2)("gitCodeLayout.header.accountAdd")), 1)
16263
- ], 8, _hoisted_8$9)) : createCommentVNode("", true),
16261
+ ], 8, _hoisted_7$b)) : createCommentVNode("", true),
16264
16262
  otherAccounts.value.length ? (openBlock(), createElementBlock("button", {
16265
16263
  key: 1,
16266
16264
  type: "button",
@@ -16268,126 +16266,481 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
16268
16266
  disabled: __props.busy,
16269
16267
  onClick: _cache[1] || (_cache[1] = ($event) => emit("logout"))
16270
16268
  }, [
16271
- _cache[3] || (_cache[3] = createElementVNode("svg", {
16272
- width: "18",
16273
- height: "18",
16274
- viewBox: "0 0 24 24",
16275
- fill: "none",
16276
- "aria-hidden": "true"
16277
- }, [
16278
- createElementVNode("path", {
16279
- d: "M9 4H4v16h5M13 8l4 4-4 4m-5-4h12",
16280
- stroke: "currentColor",
16281
- "stroke-width": "1.7",
16282
- "stroke-linecap": "round",
16283
- "stroke-linejoin": "round"
16284
- })
16285
- ], -1)),
16269
+ createVNode(GIcon, {
16270
+ name: "gt-default",
16271
+ size: "16px"
16272
+ }),
16286
16273
  createTextVNode(" " + toDisplayString$1(unref(t2)("gitCodeLayout.header.logout")), 1)
16287
- ], 8, _hoisted_9$9)) : createCommentVNode("", true)
16288
- ])
16274
+ ], 8, _hoisted_8$9)) : createCommentVNode("", true)
16275
+ ], 2)
16289
16276
  ]);
16290
16277
  };
16291
16278
  }
16292
16279
  });
16293
16280
  const AccountSessionList = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-vue-layout-gitcode"]]);
16294
- const _hoisted_1$x = { class: "g-user-drawer-account-heading" };
16295
- const _hoisted_2$q = { class: "g-user-drawer-info-list" };
16296
- const _hoisted_3$p = { class: "g-user-drawer-info-list__name-wrap" };
16297
- const _hoisted_4$j = ["title"];
16298
- const _hoisted_5$e = ["title"];
16299
- const _hoisted_6$d = ["onKeydown"];
16300
- const _hoisted_7$a = ["aria-label", "aria-expanded", "disabled"];
16301
- const _hoisted_8$8 = ["aria-label"];
16302
- const _hoisted_9$8 = {
16303
- key: 0,
16304
- class: "g-user-drawer-lang-row"
16305
- };
16306
- const _sfc_main$C = /* @__PURE__ */ defineComponent({
16307
- __name: "UserAvatarMenu",
16308
- props: {
16309
- isChatBot: { type: Boolean },
16310
- accountInfo: {},
16311
- loginOutFinish: { type: Function },
16312
- inAIHub: { type: Boolean },
16313
- independence: { type: Boolean },
16314
- userMenus: {},
16315
- inEnterpriseHeader: { type: Boolean },
16316
- accountSessionSupported: { type: Boolean },
16317
- menuVisible: { type: Boolean },
16318
- accountSessionLogout: { type: Function },
16319
- accountSessions: {},
16320
- accountSessionActiveRef: {},
16321
- accountSessionMax: {},
16322
- accountSessionBusy: { type: Boolean }
16323
- },
16324
- emits: ["link-click", "account-switch", "account-add", "account-reauthorize", "account-remove"],
16325
- setup(__props, { emit: __emit }) {
16326
- var _a;
16327
- const layoutConfig2 = useLayoutConfig();
16328
- const API = headRequest(inject("request"));
16329
- const repoInfo = inject("repoInfo");
16330
- const orgInfo = inject("orgInfo");
16331
- const userInfo = inject("userInfo");
16332
- const { t: t2 } = i18n.global;
16333
- const props = __props;
16334
- const emit = __emit;
16335
- const router2 = useRouter();
16336
- const route = useRoute();
16337
- const haveVisited = ref(false);
16338
- const menuContainerRef = ref(null);
16339
- const clearSurveyDelayStatus = () => {
16340
- const surveyDelay = localStorage$2.getItem(HARMONY_VISITED_DATE);
16341
- if (surveyDelay === "true") {
16342
- localStorage$2.removeItem(HARMONY_VISITED_DATE);
16343
- }
16344
- localStorage$2.removeItem(HARMONY_SURVEY_DELAY);
16281
+ const SHORTCUT_STORAGE_KEY = "atomgit.character-shortcuts";
16282
+ const SHORTCUT_SEQUENCE_TIMEOUT = 1500;
16283
+ const SHORTCUT_GROUPS = ["site", "repo", "code", "editor", "list", "detail"];
16284
+ const BUILTIN_SHORTCUTS = [
16285
+ { id: "site.search", keys: "/", group: "site", labelKey: "shortcut.site.search" },
16286
+ { id: "site.searchLetter", keys: "s", group: "site", labelKey: "shortcut.site.search" },
16287
+ { id: "site.help", keys: "?", group: "site", labelKey: "shortcut.site.help" },
16288
+ { id: "site.notifications", keys: "g n", group: "site", labelKey: "shortcut.site.notifications" },
16289
+ { id: "site.commands", keys: "mod+k", group: "site", labelKey: "shortcut.site.commands" },
16290
+ { id: "site.escape", keys: "escape", group: "site", labelKey: "shortcut.dialog.close" }
16291
+ ];
16292
+ const isMacPlatform = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform);
16293
+ const parseShortcut = (keys, isMac = isMacPlatform()) => {
16294
+ if (!keys.trim()) {
16295
+ throw new Error("Shortcut keys must not be empty");
16296
+ }
16297
+ return keys.trim().split(/\s+/).map((token) => {
16298
+ const parts = token.toLowerCase().split("+");
16299
+ let key = parts.pop();
16300
+ if (key === "esc") {
16301
+ key = "escape";
16302
+ }
16303
+ if (key === "space") {
16304
+ key = " ";
16305
+ }
16306
+ const modifiers = new Set(parts);
16307
+ if (!key || parts.some((part) => !["ctrl", "meta", "alt", "shift", "mod"].includes(part)) || modifiers.size !== parts.length) {
16308
+ throw new Error(`Invalid shortcut: ${keys}`);
16309
+ }
16310
+ if (key.length !== 1 && !["escape", "enter", "tab", "backspace", "delete", "arrowup", "arrowdown", "arrowleft", "arrowright", "home", "end", "pageup", "pagedown"].includes(key)) {
16311
+ throw new Error(`Unsupported shortcut key: ${key}`);
16312
+ }
16313
+ return {
16314
+ key,
16315
+ ctrl: modifiers.has("ctrl") || modifiers.has("mod") && !isMac,
16316
+ meta: modifiers.has("meta") || modifiers.has("mod") && isMac,
16317
+ alt: modifiers.has("alt"),
16318
+ shift: modifiers.has("shift")
16345
16319
  };
16346
- const handleLogout = async () => {
16347
- var _a2, _b, _c;
16348
- if (props.accountSessionSupported) {
16349
- if (!props.accountSessionBusy) await ((_a2 = props.accountSessionLogout) == null ? void 0 : _a2.call(props));
16350
- return;
16351
- }
16352
- const res = await API.toLogout();
16353
- clearSurveyDelayStatus();
16354
- if (!res.error) {
16355
- props.loginOutFinish && props.loginOutFinish();
16356
- if (((_b = route.meta) == null ? void 0 : _b.needLogin) || ((_c = route.meta) == null ? void 0 : _c.type) === "repo" && (repoInfo == null ? void 0 : repoInfo.value.visibility) === "private" || (orgInfo == null ? void 0 : orgInfo.value.visibility) === "private") {
16357
- router2.push("/");
16358
- } else {
16359
- const $route = Object.assign({}, route);
16360
- delete $route.query.isLogin;
16361
- if (typeof window !== "undefined" && window.location) {
16362
- window.location.href = router2.resolve($route).href;
16320
+ });
16321
+ };
16322
+ const matchesStroke = (event, stroke) => {
16323
+ const key = event.key.length === 1 && !stroke.shift ? event.key : event.key.toLowerCase();
16324
+ return key === stroke.key && event.ctrlKey === stroke.ctrl && event.metaKey === stroke.meta && event.altKey === stroke.alt && (stroke.key === "?" || event.shiftKey === stroke.shift);
16325
+ };
16326
+ const isCharacterShortcut = (strokes) => strokes.every((stroke) => stroke.key.length === 1 && !stroke.ctrl && !stroke.meta && !stroke.alt);
16327
+ const normalizeShortcut = (keys, isMac) => parseShortcut(keys, isMac).map((stroke) => JSON.stringify({ ...stroke, shift: stroke.key === "?" ? false : stroke.shift }));
16328
+ const config = shallowRef({ actions: [] });
16329
+ const shortcutConfig = readonly(config);
16330
+ const shortcutRevision = shallowRef(0);
16331
+ function setShortcutConfig(next) {
16332
+ if (typeof window === "undefined") {
16333
+ return;
16334
+ }
16335
+ const actions = [...BUILTIN_SHORTCUTS, ...next.actions];
16336
+ try {
16337
+ for (const isMac of [false, true]) {
16338
+ const normalized = actions.map((action) => normalizeShortcut(action.keys, isMac));
16339
+ for (let i = 0; i < actions.length; i++) {
16340
+ for (let j = i + 1; j < actions.length; j++) {
16341
+ const a = normalized[i];
16342
+ const b = normalized[j];
16343
+ const prefix = a.slice(0, Math.min(a.length, b.length)).every((key, index2) => key === b[index2]);
16344
+ if (actions[i].id === actions[j].id || prefix) {
16345
+ throw new Error(`Shortcut conflict: ${actions[i].id} (${actions[i].keys}) / ${actions[j].id} (${actions[j].keys})`);
16363
16346
  }
16364
16347
  }
16365
- } else {
16366
- props.loginOutFinish && props.loginOutFinish();
16367
16348
  }
16368
- };
16369
- const DEFAULT_ROUTER_PARAMS = Object.freeze({
16370
- name: "",
16371
- params: {
16372
- namespace: props.accountInfo.username
16373
- },
16374
- query: {}
16349
+ }
16350
+ } catch (error) {
16351
+ console.error(error);
16352
+ return;
16353
+ }
16354
+ config.value = { actions: next.actions.map((action) => ({ ...action })), isBlocked: next.isBlocked };
16355
+ shortcutRevision.value++;
16356
+ }
16357
+ function useShortcutConfig() {
16358
+ return readonly({
16359
+ get actions() {
16360
+ return config.value.actions;
16361
+ },
16362
+ get isBlocked() {
16363
+ return config.value.isBlocked;
16364
+ }
16365
+ });
16366
+ }
16367
+ const isEditableTarget = (target) => {
16368
+ if (!target || typeof Element === "undefined" || !(target instanceof Element)) {
16369
+ return false;
16370
+ }
16371
+ return Boolean(target.closest("input, textarea, select, .CodeMirror-focused, .cm-editor.cm-focused")) || target.isContentEditable === true || Boolean(target.closest('[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]'));
16372
+ };
16373
+ const isComposingEvent = (event) => event.isComposing || event.keyCode === 229;
16374
+ const shouldIgnoreShortcut = (event) => event.defaultPrevented || event.repeat || isComposingEvent(event) || event.composedPath().some(isEditableTarget) || isEditableTarget(event.target) || typeof document !== "undefined" && isEditableTarget(document.activeElement);
16375
+ let current = null;
16376
+ const enabled = ref(true);
16377
+ const characterShortcutsEnabled = readonly(enabled);
16378
+ const parsePreference = (raw) => {
16379
+ try {
16380
+ const record = JSON.parse(raw || "null");
16381
+ if (record && (record.value === "on" || record.value === "off") && Number.isSafeInteger(record.updatedAt) && record.updatedAt >= 0) {
16382
+ return { value: record.value, updatedAt: record.updatedAt };
16383
+ }
16384
+ } catch {
16385
+ }
16386
+ return null;
16387
+ };
16388
+ const newestPreference = (records) => records.reduce((latest, record) => {
16389
+ if (!record) {
16390
+ return latest;
16391
+ }
16392
+ if (!latest || record.updatedAt > latest.updatedAt || record.updatedAt === latest.updatedAt && record.value === "off") {
16393
+ return record;
16394
+ }
16395
+ return latest;
16396
+ }, null);
16397
+ function refreshShortcutPreference() {
16398
+ if (typeof window === "undefined") {
16399
+ return;
16400
+ }
16401
+ let cookie = null;
16402
+ try {
16403
+ cookie = parsePreference(api.get(SHORTCUT_STORAGE_KEY));
16404
+ } catch {
16405
+ }
16406
+ current = newestPreference([current, cookie, parsePreference(localStorage$2.getItem(SHORTCUT_STORAGE_KEY))]);
16407
+ enabled.value = (current == null ? void 0 : current.value) !== "off";
16408
+ }
16409
+ function setCharacterShortcutsEnabled(value) {
16410
+ if (typeof window === "undefined") {
16411
+ return;
16412
+ }
16413
+ refreshShortcutPreference();
16414
+ current = { value: value ? "on" : "off", updatedAt: Math.max(Date.now(), ((current == null ? void 0 : current.updatedAt) ?? -1) + 1) };
16415
+ enabled.value = value;
16416
+ const serialized = JSON.stringify(current);
16417
+ localStorage$2.setItem(SHORTCUT_STORAGE_KEY, serialized);
16418
+ try {
16419
+ const domain = COOKIE_DOMAIN().replace(/^\./, "");
16420
+ const hostname = window.location.hostname;
16421
+ const shared = hostname === domain || hostname.endsWith(`.${domain}`);
16422
+ api.set(SHORTCUT_STORAGE_KEY, serialized, {
16423
+ expires: 365,
16424
+ path: "/",
16425
+ sameSite: "Lax",
16426
+ secure: window.location.protocol === "https:",
16427
+ ...shared ? { domain: `.${domain}` } : {}
16375
16428
  });
16376
- const getRouterLink = (params) => {
16377
- if (typeof params === "string") {
16378
- return {
16379
- ...DEFAULT_ROUTER_PARAMS,
16380
- name: params
16381
- };
16382
- }
16383
- return {
16384
- ...DEFAULT_ROUTER_PARAMS,
16385
- ...params
16386
- };
16387
- };
16388
- const menuDataFormat = (data) => {
16389
- data.forEach((item) => {
16390
- if (Array.isArray(item)) {
16429
+ if (api.get(SHORTCUT_STORAGE_KEY) !== serialized) {
16430
+ return;
16431
+ }
16432
+ } catch {
16433
+ }
16434
+ }
16435
+ const providers = shallowRef([]);
16436
+ const searches = shallowRef([]);
16437
+ const notices = shallowRef([]);
16438
+ const blockers = shallowRef([]);
16439
+ const isBlocked = () => {
16440
+ var _a, _b;
16441
+ return Boolean(((_b = (_a = shortcutConfig.value).isBlocked) == null ? void 0 : _b.call(_a)) || blockers.value.some((blocked) => blocked()));
16442
+ };
16443
+ const dialog = ref(null);
16444
+ const shortcutDialog = readonly(dialog);
16445
+ const hasShortcutProvider = computed(() => providers.value.length > 0);
16446
+ let returnFocus = null;
16447
+ let pending = [];
16448
+ let timer;
16449
+ let detach;
16450
+ function resetShortcutSequence() {
16451
+ pending = [];
16452
+ clearTimeout(timer);
16453
+ timer = void 0;
16454
+ }
16455
+ function openShortcutHelp() {
16456
+ openDialog("help");
16457
+ }
16458
+ function openShortcutCommands() {
16459
+ openDialog("commands");
16460
+ }
16461
+ function openDialog(mode) {
16462
+ if (!hasShortcutProvider.value || typeof document === "undefined" || isBlocked()) {
16463
+ return;
16464
+ }
16465
+ if (!dialog.value) {
16466
+ returnFocus = document.activeElement;
16467
+ }
16468
+ resetShortcutSequence();
16469
+ dialog.value = mode;
16470
+ }
16471
+ function closeShortcutDialog(restoreFocus = true) {
16472
+ dialog.value = null;
16473
+ const previous = returnFocus;
16474
+ returnFocus = null;
16475
+ if (restoreFocus && typeof document !== "undefined") {
16476
+ void nextTick(() => {
16477
+ const target = (previous == null ? void 0 : previous.isConnected) ? previous : document.querySelector("[data-shortcut-help]");
16478
+ target == null ? void 0 : target.focus();
16479
+ });
16480
+ }
16481
+ }
16482
+ const activeTarget = (targets) => [...targets].reverse().find((target) => target.when());
16483
+ const builtinActions = computed(() => BUILTIN_SHORTCUTS.filter((item) => item.id !== "site.escape").map((item) => {
16484
+ if (item.id === "site.search" || item.id === "site.searchLetter") {
16485
+ return { ...item, when: () => Boolean(activeTarget(searches.value)), run: () => {
16486
+ var _a;
16487
+ return (_a = activeTarget(searches.value)) == null ? void 0 : _a.run();
16488
+ } };
16489
+ }
16490
+ if (item.id === "site.notifications") {
16491
+ return { ...item, when: () => Boolean(activeTarget(notices.value)), run: () => {
16492
+ var _a;
16493
+ return (_a = activeTarget(notices.value)) == null ? void 0 : _a.run();
16494
+ } };
16495
+ }
16496
+ return { ...item, run: item.id === "site.help" ? openShortcutHelp : openShortcutCommands };
16497
+ }));
16498
+ const getAvailableShortcutActions = () => {
16499
+ if (!hasShortcutProvider.value) {
16500
+ return builtinActions.value.filter((action) => action.id === "site.search" && (!action.when || action.when()));
16501
+ }
16502
+ return [...builtinActions.value, ...shortcutConfig.value.actions].filter((action) => !action.when || action.when());
16503
+ };
16504
+ const selectionRevision = ref(0);
16505
+ const onSelectionChange = () => {
16506
+ selectionRevision.value += 1;
16507
+ };
16508
+ const availableShortcutActions = computed(() => {
16509
+ void selectionRevision.value;
16510
+ return getAvailableShortcutActions();
16511
+ });
16512
+ function executeShortcutAction(action) {
16513
+ if (isBlocked() || !getAvailableShortcutActions().some((item) => item.id === action.id) || action.when && !action.when()) {
16514
+ return;
16515
+ }
16516
+ closeShortcutDialog(false);
16517
+ void nextTick(() => {
16518
+ const current2 = getAvailableShortcutActions().find((item) => item.id === action.id);
16519
+ if (!isBlocked() && current2) {
16520
+ current2.run();
16521
+ }
16522
+ });
16523
+ }
16524
+ function onKeydown(event) {
16525
+ if (shouldIgnoreShortcut(event)) {
16526
+ resetShortcutSequence();
16527
+ return;
16528
+ }
16529
+ if (dialog.value || isBlocked()) {
16530
+ resetShortcutSequence();
16531
+ return;
16532
+ }
16533
+ if (event.key === "Escape") {
16534
+ if (pending.length) {
16535
+ event.preventDefault();
16536
+ resetShortcutSequence();
16537
+ }
16538
+ return;
16539
+ }
16540
+ const candidates = getAvailableShortcutActions().map((action) => ({ action, strokes: parseShortcut(action.keys) })).filter(({ strokes }) => characterShortcutsEnabled.value || !isCharacterShortcut(strokes));
16541
+ const matches = candidates.filter(({ strokes }) => strokes.length > pending.length && pending.every((key, index2) => key === JSON.stringify(strokes[index2])) && matchesStroke(event, strokes[pending.length]));
16542
+ const complete = matches.find(({ strokes }) => strokes.length === pending.length + 1);
16543
+ if (complete) {
16544
+ resetShortcutSequence();
16545
+ if (!complete.action.when || complete.action.when()) {
16546
+ event.preventDefault();
16547
+ complete.action.run();
16548
+ }
16549
+ } else if (matches.length) {
16550
+ pending.push(JSON.stringify(matches[0].strokes[pending.length]));
16551
+ clearTimeout(timer);
16552
+ timer = setTimeout(resetShortcutSequence, SHORTCUT_SEQUENCE_TIMEOUT);
16553
+ } else {
16554
+ resetShortcutSequence();
16555
+ }
16556
+ }
16557
+ function syncListener() {
16558
+ if (typeof document === "undefined") {
16559
+ return;
16560
+ }
16561
+ const needed = providers.value.length + searches.value.length > 0;
16562
+ if (!needed) {
16563
+ detach == null ? void 0 : detach();
16564
+ detach = void 0;
16565
+ resetShortcutSequence();
16566
+ return;
16567
+ }
16568
+ if (detach) {
16569
+ return;
16570
+ }
16571
+ refreshShortcutPreference();
16572
+ const onFocus = (event) => {
16573
+ if (isEditableTarget(event.target)) {
16574
+ resetShortcutSequence();
16575
+ }
16576
+ };
16577
+ document.addEventListener("keydown", onKeydown);
16578
+ document.addEventListener("focusin", onFocus);
16579
+ document.addEventListener("compositionstart", resetShortcutSequence);
16580
+ document.addEventListener("selectionchange", onSelectionChange);
16581
+ window.addEventListener("blur", resetShortcutSequence);
16582
+ window.addEventListener("focus", refreshShortcutPreference);
16583
+ const scope = effectScope(true);
16584
+ scope.run(() => {
16585
+ watch(shortcutRevision, resetShortcutSequence, { flush: "sync" });
16586
+ watch(characterShortcutsEnabled, resetShortcutSequence, { flush: "sync" });
16587
+ watch(isBlocked, resetShortcutSequence, { flush: "sync" });
16588
+ });
16589
+ detach = () => {
16590
+ document.removeEventListener("keydown", onKeydown);
16591
+ document.removeEventListener("focusin", onFocus);
16592
+ document.removeEventListener("compositionstart", resetShortcutSequence);
16593
+ document.removeEventListener("selectionchange", onSelectionChange);
16594
+ window.removeEventListener("blur", resetShortcutSequence);
16595
+ window.removeEventListener("focus", refreshShortcutPreference);
16596
+ scope.stop();
16597
+ };
16598
+ }
16599
+ function registerShortcutProvider() {
16600
+ const id = Symbol("shortcut-provider");
16601
+ providers.value = [...providers.value, id];
16602
+ syncListener();
16603
+ return {
16604
+ isOwner: computed(() => providers.value[0] === id),
16605
+ dispose: () => {
16606
+ providers.value = providers.value.filter((item) => item !== id);
16607
+ if (!providers.value.length) {
16608
+ closeShortcutDialog();
16609
+ resetShortcutSequence();
16610
+ }
16611
+ syncListener();
16612
+ }
16613
+ };
16614
+ }
16615
+ function registerTarget(target, collection) {
16616
+ collection.value = [...collection.value, target];
16617
+ syncListener();
16618
+ return () => {
16619
+ collection.value = collection.value.filter((item) => item !== target);
16620
+ syncListener();
16621
+ };
16622
+ }
16623
+ const registerShortcutSearch = (target) => registerTarget(target, searches);
16624
+ const registerShortcutNotice = (target) => registerTarget(target, notices);
16625
+ function useShortcutSearch(target) {
16626
+ let dispose;
16627
+ onMounted(() => {
16628
+ dispose = registerShortcutSearch(target);
16629
+ });
16630
+ onUnmounted(() => dispose == null ? void 0 : dispose());
16631
+ }
16632
+ function useShortcutNotice(target) {
16633
+ let dispose;
16634
+ onMounted(() => {
16635
+ dispose = registerShortcutNotice(target);
16636
+ });
16637
+ onUnmounted(() => dispose == null ? void 0 : dispose());
16638
+ }
16639
+ function useShortcutBlocker(blocked) {
16640
+ onMounted(() => {
16641
+ blockers.value = [...blockers.value, blocked];
16642
+ });
16643
+ onUnmounted(() => {
16644
+ blockers.value = blockers.value.filter((item) => item !== blocked);
16645
+ });
16646
+ }
16647
+ const _hoisted_1$x = { class: "g-user-drawer-account-heading" };
16648
+ const _hoisted_2$q = { class: "g-user-drawer-info-list" };
16649
+ const _hoisted_3$p = { class: "g-user-drawer-info-list__name-wrap" };
16650
+ const _hoisted_4$j = ["title"];
16651
+ const _hoisted_5$e = ["title"];
16652
+ const _hoisted_6$d = ["onKeydown"];
16653
+ const _hoisted_7$a = ["aria-label", "aria-expanded", "disabled"];
16654
+ const _hoisted_8$8 = ["aria-label"];
16655
+ const _hoisted_9$8 = {
16656
+ key: 0,
16657
+ class: "g-user-drawer-lang-row"
16658
+ };
16659
+ const _sfc_main$C = /* @__PURE__ */ defineComponent({
16660
+ __name: "UserAvatarMenu",
16661
+ props: {
16662
+ isChatBot: { type: Boolean },
16663
+ accountInfo: {},
16664
+ loginOutFinish: { type: Function },
16665
+ inAIHub: { type: Boolean },
16666
+ independence: { type: Boolean },
16667
+ userMenus: {},
16668
+ inEnterpriseHeader: { type: Boolean },
16669
+ accountSessionSupported: { type: Boolean },
16670
+ menuVisible: { type: Boolean },
16671
+ accountSessionLogout: { type: Function },
16672
+ accountSessions: {},
16673
+ accountSessionActiveRef: {},
16674
+ accountSessionMax: {},
16675
+ accountSessionBusy: { type: Boolean }
16676
+ },
16677
+ emits: ["link-click", "account-switch", "account-add", "account-reauthorize", "account-remove"],
16678
+ setup(__props, { emit: __emit }) {
16679
+ var _a;
16680
+ const layoutConfig2 = useLayoutConfig();
16681
+ const API = headRequest(inject("request"));
16682
+ const repoInfo = inject("repoInfo");
16683
+ const orgInfo = inject("orgInfo");
16684
+ const userInfo = inject("userInfo");
16685
+ const { t: t2 } = i18n.global;
16686
+ const props = __props;
16687
+ const emit = __emit;
16688
+ const router2 = useRouter();
16689
+ const route = useRoute();
16690
+ const haveVisited = ref(false);
16691
+ const menuContainerRef = ref(null);
16692
+ const clearSurveyDelayStatus = () => {
16693
+ const surveyDelay = localStorage$2.getItem(HARMONY_VISITED_DATE);
16694
+ if (surveyDelay === "true") {
16695
+ localStorage$2.removeItem(HARMONY_VISITED_DATE);
16696
+ }
16697
+ localStorage$2.removeItem(HARMONY_SURVEY_DELAY);
16698
+ };
16699
+ const handleLogout = async () => {
16700
+ var _a2, _b, _c;
16701
+ if (props.accountSessionSupported) {
16702
+ if (!props.accountSessionBusy) await ((_a2 = props.accountSessionLogout) == null ? void 0 : _a2.call(props));
16703
+ return;
16704
+ }
16705
+ const res = await API.toLogout();
16706
+ clearSurveyDelayStatus();
16707
+ if (!res.error) {
16708
+ props.loginOutFinish && props.loginOutFinish();
16709
+ if (((_b = route.meta) == null ? void 0 : _b.needLogin) || ((_c = route.meta) == null ? void 0 : _c.type) === "repo" && (repoInfo == null ? void 0 : repoInfo.value.visibility) === "private" || (orgInfo == null ? void 0 : orgInfo.value.visibility) === "private") {
16710
+ router2.push("/");
16711
+ } else {
16712
+ const $route = Object.assign({}, route);
16713
+ delete $route.query.isLogin;
16714
+ if (typeof window !== "undefined" && window.location) {
16715
+ window.location.href = router2.resolve($route).href;
16716
+ }
16717
+ }
16718
+ } else {
16719
+ props.loginOutFinish && props.loginOutFinish();
16720
+ }
16721
+ };
16722
+ const DEFAULT_ROUTER_PARAMS = Object.freeze({
16723
+ name: "",
16724
+ params: {
16725
+ namespace: props.accountInfo.username
16726
+ },
16727
+ query: {}
16728
+ });
16729
+ const getRouterLink = (params) => {
16730
+ if (typeof params === "string") {
16731
+ return {
16732
+ ...DEFAULT_ROUTER_PARAMS,
16733
+ name: params
16734
+ };
16735
+ }
16736
+ return {
16737
+ ...DEFAULT_ROUTER_PARAMS,
16738
+ ...params
16739
+ };
16740
+ };
16741
+ const menuDataFormat = (data) => {
16742
+ data.forEach((item) => {
16743
+ if (Array.isArray(item)) {
16391
16744
  item.forEach((item2) => {
16392
16745
  if (item2.to) {
16393
16746
  item2.to = getRouterLink(item2.to);
@@ -16468,6 +16821,7 @@ const _sfc_main$C = /* @__PURE__ */ defineComponent({
16468
16821
  );
16469
16822
  const accountMenuId = `toolbar-account-switcher-${(_a = getCurrentInstance()) == null ? void 0 : _a.uid}`;
16470
16823
  const accountMenuOpen = ref(false);
16824
+ useShortcutBlocker(() => accountMenuOpen.value);
16471
16825
  const accountSwitcherRef = ref(null);
16472
16826
  const accountSwitchButton = ref(null);
16473
16827
  const accountMenuPanel = ref(null);
@@ -17012,436 +17366,70 @@ var EVENT_NAME = /* @__PURE__ */ ((EVENT_NAME2) => {
17012
17366
  EVENT_NAME2["FOURZEROFOUR"] = "404页面精选项目进入";
17013
17367
  EVENT_NAME2["OPEN_LOGIN"] = "打开登录页面";
17014
17368
  return EVENT_NAME2;
17015
- })(EVENT_NAME || {});
17016
- function _frEventTrack(eventName, type = "custom") {
17017
- var _a;
17018
- try {
17019
- (_a = window.FURION) == null ? void 0 : _a.log(type, eventName);
17020
- } catch (err) {
17021
- }
17022
- }
17023
- const isSearchHistoryEntry = (value) => {
17024
- return typeof value === "object" && value !== null && !Array.isArray(value);
17025
- };
17026
- const normalizeSearchHistoryEntry = (value) => {
17027
- if (typeof value === "string") {
17028
- return { q: value, type: "repo" };
17029
- }
17030
- if (!isSearchHistoryEntry(value)) {
17031
- return { q: "", type: "repo" };
17032
- }
17033
- return { ...value, type: value.type || "repo" };
17034
- };
17035
- const sameSearchHistory = (left, right) => {
17036
- const leftEntry = normalizeSearchHistoryEntry(left);
17037
- return leftEntry.q === right.q && leftEntry.type === right.type && leftEntry.scope === right.scope && leftEntry.repo === right.repo && leftEntry.org === right.org && leftEntry.user === right.user && leftEntry.namespace === right.namespace;
17038
- };
17039
- const upsertSearchHistory = (current2, data, limit = 10) => {
17040
- const next = current2.filter((item) => Boolean(normalizeSearchHistoryEntry(item).q));
17041
- const normalizedData = { ...data, type: data.type || "repo" };
17042
- const existingIndex = next.findIndex((item) => sameSearchHistory(item, normalizedData));
17043
- if (existingIndex === -1) {
17044
- next.unshift({ ...normalizedData, count: normalizedData.count || 1 });
17045
- } else {
17046
- const existing = normalizeSearchHistoryEntry(next[existingIndex]);
17047
- existing.count = (existing.count || 1) + 1;
17048
- next.splice(existingIndex, 1);
17049
- next.unshift(existing);
17050
- }
17051
- return next.slice(0, limit);
17052
- };
17053
- const setlocalVistHistory = (data, localType) => {
17054
- const storeName = localType;
17055
- const localData = localStorage$2.getItem(storeName);
17056
- let cur = [];
17057
- if (localData) {
17058
- try {
17059
- const parsed = JSON.parse(localData);
17060
- cur = Array.isArray(parsed) ? parsed : [];
17061
- if (localType) {
17062
- if (data.q) {
17063
- cur = upsertSearchHistory(cur, data);
17064
- } else {
17065
- cur = cur.filter((ele) => Boolean(normalizeSearchHistoryEntry(ele).q));
17066
- }
17067
- }
17068
- } catch (e) {
17069
- console.error(e);
17070
- }
17071
- } else {
17072
- cur = data.q ? [{ ...data, type: data.type || "repo", count: 1 }] : [];
17073
- }
17074
- const storageCount = 10;
17075
- cur.splice(storageCount);
17076
- localStorage$2.setItem(storeName, JSON.stringify(cur));
17077
- return cur;
17078
- };
17079
- const SHORTCUT_STORAGE_KEY = "atomgit.character-shortcuts";
17080
- const SHORTCUT_SEQUENCE_TIMEOUT = 1500;
17081
- const SHORTCUT_GROUPS = ["site", "repo", "code", "editor", "list", "detail"];
17082
- const BUILTIN_SHORTCUTS = [
17083
- { id: "site.search", keys: "/", group: "site", labelKey: "shortcut.site.search" },
17084
- { id: "site.searchLetter", keys: "s", group: "site", labelKey: "shortcut.site.search" },
17085
- { id: "site.help", keys: "?", group: "site", labelKey: "shortcut.site.help" },
17086
- { id: "site.notifications", keys: "g n", group: "site", labelKey: "shortcut.site.notifications" },
17087
- { id: "site.commands", keys: "mod+k", group: "site", labelKey: "shortcut.site.commands" },
17088
- { id: "site.escape", keys: "escape", group: "site", labelKey: "shortcut.dialog.close" }
17089
- ];
17090
- const isMacPlatform = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform);
17091
- const parseShortcut = (keys, isMac = isMacPlatform()) => {
17092
- if (!keys.trim()) {
17093
- throw new Error("Shortcut keys must not be empty");
17094
- }
17095
- return keys.trim().split(/\s+/).map((token) => {
17096
- const parts = token.toLowerCase().split("+");
17097
- let key = parts.pop();
17098
- if (key === "esc") {
17099
- key = "escape";
17100
- }
17101
- if (key === "space") {
17102
- key = " ";
17103
- }
17104
- const modifiers = new Set(parts);
17105
- if (!key || parts.some((part) => !["ctrl", "meta", "alt", "shift", "mod"].includes(part)) || modifiers.size !== parts.length) {
17106
- throw new Error(`Invalid shortcut: ${keys}`);
17107
- }
17108
- if (key.length !== 1 && !["escape", "enter", "tab", "backspace", "delete", "arrowup", "arrowdown", "arrowleft", "arrowright", "home", "end", "pageup", "pagedown"].includes(key)) {
17109
- throw new Error(`Unsupported shortcut key: ${key}`);
17110
- }
17111
- return {
17112
- key,
17113
- ctrl: modifiers.has("ctrl") || modifiers.has("mod") && !isMac,
17114
- meta: modifiers.has("meta") || modifiers.has("mod") && isMac,
17115
- alt: modifiers.has("alt"),
17116
- shift: modifiers.has("shift")
17117
- };
17118
- });
17119
- };
17120
- const matchesStroke = (event, stroke) => {
17121
- const key = event.key.length === 1 && !stroke.shift ? event.key : event.key.toLowerCase();
17122
- return key === stroke.key && event.ctrlKey === stroke.ctrl && event.metaKey === stroke.meta && event.altKey === stroke.alt && (stroke.key === "?" || event.shiftKey === stroke.shift);
17123
- };
17124
- const isCharacterShortcut = (strokes) => strokes.every((stroke) => stroke.key.length === 1 && !stroke.ctrl && !stroke.meta && !stroke.alt);
17125
- const normalizeShortcut = (keys, isMac) => parseShortcut(keys, isMac).map((stroke) => JSON.stringify({ ...stroke, shift: stroke.key === "?" ? false : stroke.shift }));
17126
- const config = shallowRef({ actions: [] });
17127
- const shortcutConfig = readonly(config);
17128
- const shortcutRevision = shallowRef(0);
17129
- function setShortcutConfig(next) {
17130
- if (typeof window === "undefined") {
17131
- return;
17132
- }
17133
- const actions = [...BUILTIN_SHORTCUTS, ...next.actions];
17134
- try {
17135
- for (const isMac of [false, true]) {
17136
- const normalized = actions.map((action) => normalizeShortcut(action.keys, isMac));
17137
- for (let i = 0; i < actions.length; i++) {
17138
- for (let j = i + 1; j < actions.length; j++) {
17139
- const a = normalized[i];
17140
- const b = normalized[j];
17141
- const prefix = a.slice(0, Math.min(a.length, b.length)).every((key, index2) => key === b[index2]);
17142
- if (actions[i].id === actions[j].id || prefix) {
17143
- throw new Error(`Shortcut conflict: ${actions[i].id} (${actions[i].keys}) / ${actions[j].id} (${actions[j].keys})`);
17144
- }
17145
- }
17146
- }
17147
- }
17148
- } catch (error) {
17149
- console.error(error);
17150
- return;
17151
- }
17152
- config.value = { actions: next.actions.map((action) => ({ ...action })), isBlocked: next.isBlocked };
17153
- shortcutRevision.value++;
17154
- }
17155
- function useShortcutConfig() {
17156
- return readonly({
17157
- get actions() {
17158
- return config.value.actions;
17159
- },
17160
- get isBlocked() {
17161
- return config.value.isBlocked;
17162
- }
17163
- });
17164
- }
17165
- const isEditableTarget = (target) => {
17166
- if (!target || typeof Element === "undefined" || !(target instanceof Element)) {
17167
- return false;
17168
- }
17169
- return Boolean(target.closest("input, textarea, select, .CodeMirror-focused, .cm-editor.cm-focused")) || target.isContentEditable === true || Boolean(target.closest('[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]'));
17170
- };
17171
- const isComposingEvent = (event) => event.isComposing || event.keyCode === 229;
17172
- const shouldIgnoreShortcut = (event) => event.defaultPrevented || event.repeat || isComposingEvent(event) || event.composedPath().some(isEditableTarget) || isEditableTarget(event.target) || typeof document !== "undefined" && isEditableTarget(document.activeElement);
17173
- let current = null;
17174
- const enabled = ref(true);
17175
- const characterShortcutsEnabled = readonly(enabled);
17176
- const parsePreference = (raw) => {
17177
- try {
17178
- const record = JSON.parse(raw || "null");
17179
- if (record && (record.value === "on" || record.value === "off") && Number.isSafeInteger(record.updatedAt) && record.updatedAt >= 0) {
17180
- return { value: record.value, updatedAt: record.updatedAt };
17181
- }
17182
- } catch {
17183
- }
17184
- return null;
17185
- };
17186
- const newestPreference = (records) => records.reduce((latest, record) => {
17187
- if (!record) {
17188
- return latest;
17189
- }
17190
- if (!latest || record.updatedAt > latest.updatedAt || record.updatedAt === latest.updatedAt && record.value === "off") {
17191
- return record;
17192
- }
17193
- return latest;
17194
- }, null);
17195
- function refreshShortcutPreference() {
17196
- if (typeof window === "undefined") {
17197
- return;
17198
- }
17199
- let cookie = null;
17200
- try {
17201
- cookie = parsePreference(api.get(SHORTCUT_STORAGE_KEY));
17202
- } catch {
17203
- }
17204
- current = newestPreference([current, cookie, parsePreference(localStorage$2.getItem(SHORTCUT_STORAGE_KEY))]);
17205
- enabled.value = (current == null ? void 0 : current.value) !== "off";
17206
- }
17207
- function setCharacterShortcutsEnabled(value) {
17208
- if (typeof window === "undefined") {
17209
- return;
17210
- }
17211
- refreshShortcutPreference();
17212
- current = { value: value ? "on" : "off", updatedAt: Math.max(Date.now(), ((current == null ? void 0 : current.updatedAt) ?? -1) + 1) };
17213
- enabled.value = value;
17214
- const serialized = JSON.stringify(current);
17215
- localStorage$2.setItem(SHORTCUT_STORAGE_KEY, serialized);
17216
- try {
17217
- const domain = COOKIE_DOMAIN().replace(/^\./, "");
17218
- const hostname = window.location.hostname;
17219
- const shared = hostname === domain || hostname.endsWith(`.${domain}`);
17220
- api.set(SHORTCUT_STORAGE_KEY, serialized, {
17221
- expires: 365,
17222
- path: "/",
17223
- sameSite: "Lax",
17224
- secure: window.location.protocol === "https:",
17225
- ...shared ? { domain: `.${domain}` } : {}
17226
- });
17227
- if (api.get(SHORTCUT_STORAGE_KEY) !== serialized) {
17228
- return;
17229
- }
17230
- } catch {
17369
+ })(EVENT_NAME || {});
17370
+ function _frEventTrack(eventName, type = "custom") {
17371
+ var _a;
17372
+ try {
17373
+ (_a = window.FURION) == null ? void 0 : _a.log(type, eventName);
17374
+ } catch (err) {
17231
17375
  }
17232
17376
  }
17233
- const providers = shallowRef([]);
17234
- const searches = shallowRef([]);
17235
- const notices = shallowRef([]);
17236
- const blockers = shallowRef([]);
17237
- const isBlocked = () => {
17238
- var _a, _b;
17239
- return Boolean(((_b = (_a = shortcutConfig.value).isBlocked) == null ? void 0 : _b.call(_a)) || blockers.value.some((blocked) => blocked()));
17377
+ const isSearchHistoryEntry = (value) => {
17378
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17240
17379
  };
17241
- const dialog = ref(null);
17242
- const shortcutDialog = readonly(dialog);
17243
- const hasShortcutProvider = computed(() => providers.value.length > 0);
17244
- let returnFocus = null;
17245
- let pending = [];
17246
- let timer;
17247
- let detach;
17248
- function resetShortcutSequence() {
17249
- pending = [];
17250
- clearTimeout(timer);
17251
- timer = void 0;
17252
- }
17253
- function openShortcutHelp() {
17254
- openDialog("help");
17255
- }
17256
- function openShortcutCommands() {
17257
- openDialog("commands");
17258
- }
17259
- function openDialog(mode) {
17260
- if (!hasShortcutProvider.value || typeof document === "undefined" || isBlocked()) {
17261
- return;
17262
- }
17263
- if (!dialog.value) {
17264
- returnFocus = document.activeElement;
17265
- }
17266
- resetShortcutSequence();
17267
- dialog.value = mode;
17268
- }
17269
- function closeShortcutDialog(restoreFocus = true) {
17270
- dialog.value = null;
17271
- const previous = returnFocus;
17272
- returnFocus = null;
17273
- if (restoreFocus && typeof document !== "undefined") {
17274
- void nextTick(() => {
17275
- const target = (previous == null ? void 0 : previous.isConnected) ? previous : document.querySelector("[data-shortcut-help]");
17276
- target == null ? void 0 : target.focus();
17277
- });
17278
- }
17279
- }
17280
- const activeTarget = (targets) => [...targets].reverse().find((target) => target.when());
17281
- const builtinActions = computed(() => BUILTIN_SHORTCUTS.filter((item) => item.id !== "site.escape").map((item) => {
17282
- if (item.id === "site.search" || item.id === "site.searchLetter") {
17283
- return { ...item, when: () => Boolean(activeTarget(searches.value)), run: () => {
17284
- var _a;
17285
- return (_a = activeTarget(searches.value)) == null ? void 0 : _a.run();
17286
- } };
17287
- }
17288
- if (item.id === "site.notifications") {
17289
- return { ...item, when: () => Boolean(activeTarget(notices.value)), run: () => {
17290
- var _a;
17291
- return (_a = activeTarget(notices.value)) == null ? void 0 : _a.run();
17292
- } };
17380
+ const normalizeSearchHistoryEntry = (value) => {
17381
+ if (typeof value === "string") {
17382
+ return { q: value, type: "repo" };
17293
17383
  }
17294
- return { ...item, run: item.id === "site.help" ? openShortcutHelp : openShortcutCommands };
17295
- }));
17296
- const getAvailableShortcutActions = () => {
17297
- if (!hasShortcutProvider.value) {
17298
- return builtinActions.value.filter((action) => action.id === "site.search" && (!action.when || action.when()));
17384
+ if (!isSearchHistoryEntry(value)) {
17385
+ return { q: "", type: "repo" };
17299
17386
  }
17300
- return [...builtinActions.value, ...shortcutConfig.value.actions].filter((action) => !action.when || action.when());
17387
+ return { ...value, type: value.type || "repo" };
17301
17388
  };
17302
- const selectionRevision = ref(0);
17303
- const onSelectionChange = () => {
17304
- selectionRevision.value += 1;
17389
+ const sameSearchHistory = (left, right) => {
17390
+ const leftEntry = normalizeSearchHistoryEntry(left);
17391
+ return leftEntry.q === right.q && leftEntry.type === right.type && leftEntry.scope === right.scope && leftEntry.repo === right.repo && leftEntry.org === right.org && leftEntry.user === right.user && leftEntry.namespace === right.namespace;
17305
17392
  };
17306
- const availableShortcutActions = computed(() => {
17307
- void selectionRevision.value;
17308
- return getAvailableShortcutActions();
17309
- });
17310
- function executeShortcutAction(action) {
17311
- if (isBlocked() || !getAvailableShortcutActions().some((item) => item.id === action.id) || action.when && !action.when()) {
17312
- return;
17313
- }
17314
- closeShortcutDialog(false);
17315
- void nextTick(() => {
17316
- const current2 = getAvailableShortcutActions().find((item) => item.id === action.id);
17317
- if (!isBlocked() && current2) {
17318
- current2.run();
17319
- }
17320
- });
17321
- }
17322
- function onKeydown(event) {
17323
- if (shouldIgnoreShortcut(event)) {
17324
- resetShortcutSequence();
17325
- return;
17326
- }
17327
- if (dialog.value || isBlocked()) {
17328
- resetShortcutSequence();
17329
- return;
17330
- }
17331
- if (event.key === "Escape") {
17332
- if (pending.length) {
17333
- event.preventDefault();
17334
- resetShortcutSequence();
17335
- }
17336
- return;
17337
- }
17338
- const candidates = getAvailableShortcutActions().map((action) => ({ action, strokes: parseShortcut(action.keys) })).filter(({ strokes }) => characterShortcutsEnabled.value || !isCharacterShortcut(strokes));
17339
- const matches = candidates.filter(({ strokes }) => strokes.length > pending.length && pending.every((key, index2) => key === JSON.stringify(strokes[index2])) && matchesStroke(event, strokes[pending.length]));
17340
- const complete = matches.find(({ strokes }) => strokes.length === pending.length + 1);
17341
- if (complete) {
17342
- resetShortcutSequence();
17343
- if (!complete.action.when || complete.action.when()) {
17344
- event.preventDefault();
17345
- complete.action.run();
17346
- }
17347
- } else if (matches.length) {
17348
- pending.push(JSON.stringify(matches[0].strokes[pending.length]));
17349
- clearTimeout(timer);
17350
- timer = setTimeout(resetShortcutSequence, SHORTCUT_SEQUENCE_TIMEOUT);
17393
+ const upsertSearchHistory = (current2, data, limit = 10) => {
17394
+ const next = current2.filter((item) => Boolean(normalizeSearchHistoryEntry(item).q));
17395
+ const normalizedData = { ...data, type: data.type || "repo" };
17396
+ const existingIndex = next.findIndex((item) => sameSearchHistory(item, normalizedData));
17397
+ if (existingIndex === -1) {
17398
+ next.unshift({ ...normalizedData, count: normalizedData.count || 1 });
17351
17399
  } else {
17352
- resetShortcutSequence();
17353
- }
17354
- }
17355
- function syncListener() {
17356
- if (typeof document === "undefined") {
17357
- return;
17358
- }
17359
- const needed = providers.value.length + searches.value.length > 0;
17360
- if (!needed) {
17361
- detach == null ? void 0 : detach();
17362
- detach = void 0;
17363
- resetShortcutSequence();
17364
- return;
17365
- }
17366
- if (detach) {
17367
- return;
17400
+ const existing = normalizeSearchHistoryEntry(next[existingIndex]);
17401
+ existing.count = (existing.count || 1) + 1;
17402
+ next.splice(existingIndex, 1);
17403
+ next.unshift(existing);
17368
17404
  }
17369
- refreshShortcutPreference();
17370
- const onFocus = (event) => {
17371
- if (isEditableTarget(event.target)) {
17372
- resetShortcutSequence();
17373
- }
17374
- };
17375
- document.addEventListener("keydown", onKeydown);
17376
- document.addEventListener("focusin", onFocus);
17377
- document.addEventListener("compositionstart", resetShortcutSequence);
17378
- document.addEventListener("selectionchange", onSelectionChange);
17379
- window.addEventListener("blur", resetShortcutSequence);
17380
- window.addEventListener("focus", refreshShortcutPreference);
17381
- const scope = effectScope(true);
17382
- scope.run(() => {
17383
- watch(shortcutRevision, resetShortcutSequence, { flush: "sync" });
17384
- watch(characterShortcutsEnabled, resetShortcutSequence, { flush: "sync" });
17385
- watch(isBlocked, resetShortcutSequence, { flush: "sync" });
17386
- });
17387
- detach = () => {
17388
- document.removeEventListener("keydown", onKeydown);
17389
- document.removeEventListener("focusin", onFocus);
17390
- document.removeEventListener("compositionstart", resetShortcutSequence);
17391
- document.removeEventListener("selectionchange", onSelectionChange);
17392
- window.removeEventListener("blur", resetShortcutSequence);
17393
- window.removeEventListener("focus", refreshShortcutPreference);
17394
- scope.stop();
17395
- };
17396
- }
17397
- function registerShortcutProvider() {
17398
- const id = Symbol("shortcut-provider");
17399
- providers.value = [...providers.value, id];
17400
- syncListener();
17401
- return {
17402
- isOwner: computed(() => providers.value[0] === id),
17403
- dispose: () => {
17404
- providers.value = providers.value.filter((item) => item !== id);
17405
- if (!providers.value.length) {
17406
- closeShortcutDialog();
17407
- resetShortcutSequence();
17405
+ return next.slice(0, limit);
17406
+ };
17407
+ const setlocalVistHistory = (data, localType) => {
17408
+ const storeName = localType;
17409
+ const localData = localStorage$2.getItem(storeName);
17410
+ let cur = [];
17411
+ if (localData) {
17412
+ try {
17413
+ const parsed = JSON.parse(localData);
17414
+ cur = Array.isArray(parsed) ? parsed : [];
17415
+ if (localType) {
17416
+ if (data.q) {
17417
+ cur = upsertSearchHistory(cur, data);
17418
+ } else {
17419
+ cur = cur.filter((ele) => Boolean(normalizeSearchHistoryEntry(ele).q));
17420
+ }
17408
17421
  }
17409
- syncListener();
17422
+ } catch (e) {
17423
+ console.error(e);
17410
17424
  }
17411
- };
17412
- }
17413
- function registerTarget(target, collection) {
17414
- collection.value = [...collection.value, target];
17415
- syncListener();
17416
- return () => {
17417
- collection.value = collection.value.filter((item) => item !== target);
17418
- syncListener();
17419
- };
17420
- }
17421
- const registerShortcutSearch = (target) => registerTarget(target, searches);
17422
- const registerShortcutNotice = (target) => registerTarget(target, notices);
17423
- function useShortcutSearch(target) {
17424
- let dispose;
17425
- onMounted(() => {
17426
- dispose = registerShortcutSearch(target);
17427
- });
17428
- onUnmounted(() => dispose == null ? void 0 : dispose());
17429
- }
17430
- function useShortcutNotice(target) {
17431
- let dispose;
17432
- onMounted(() => {
17433
- dispose = registerShortcutNotice(target);
17434
- });
17435
- onUnmounted(() => dispose == null ? void 0 : dispose());
17436
- }
17437
- function useShortcutBlocker(blocked) {
17438
- onMounted(() => {
17439
- blockers.value = [...blockers.value, blocked];
17440
- });
17441
- onUnmounted(() => {
17442
- blockers.value = blockers.value.filter((item) => item !== blocked);
17443
- });
17444
- }
17425
+ } else {
17426
+ cur = data.q ? [{ ...data, type: data.type || "repo", count: 1 }] : [];
17427
+ }
17428
+ const storageCount = 10;
17429
+ cur.splice(storageCount);
17430
+ localStorage$2.setItem(storeName, JSON.stringify(cur));
17431
+ return cur;
17432
+ };
17445
17433
  const KEY_ALIAS = {
17446
17434
  repo: "repo",
17447
17435
  user: "user",
@@ -17881,12 +17869,12 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
17881
17869
  setup(__props) {
17882
17870
  const layoutConfig2 = useLayoutConfig();
17883
17871
  const { t: $t } = i18n.global;
17884
- const ProjectSearch = defineAsyncComponent(() => import("./ProjectSearch-B4IZWWec.js"));
17885
- const UserSearch = defineAsyncComponent(() => import("./UserSearch-Jno2-hDh.js"));
17886
- const GloabarSearch = defineAsyncComponent(() => import("./GloabarSearch-CefMwW5N.js"));
17887
- const SearchHistoryList = defineAsyncComponent(() => import("./SearchHistoryList-BWFi4Y0g.js"));
17888
- const SearchScopeList = defineAsyncComponent(() => import("./SearchScopeList-BI_Gt1qi.js"));
17889
- const SearchRecommed = defineAsyncComponent(() => import("./SearchRecommed-eDW-NOQQ.js"));
17872
+ const ProjectSearch = defineAsyncComponent(() => import("./ProjectSearch-CwxvyjLk.js"));
17873
+ const UserSearch = defineAsyncComponent(() => import("./UserSearch-Do0T56gf.js"));
17874
+ const GloabarSearch = defineAsyncComponent(() => import("./GloabarSearch-Dty9RV_o.js"));
17875
+ const SearchHistoryList = defineAsyncComponent(() => import("./SearchHistoryList-UKbYAe00.js"));
17876
+ const SearchScopeList = defineAsyncComponent(() => import("./SearchScopeList-DWLaZ4qm.js"));
17877
+ const SearchRecommed = defineAsyncComponent(() => import("./SearchRecommed-C-lCDHYL.js"));
17890
17878
  const props = __props;
17891
17879
  const repoInfo = inject("repoInfo", computed(() => void 0));
17892
17880
  const orgInfo = inject("orgInfo", computed(() => void 0));
@@ -19248,7 +19236,7 @@ const vElementExposure = {
19248
19236
  beforeUnmount() {
19249
19237
  }
19250
19238
  };
19251
- const NoticeModal = defineAsyncComponent(() => import("./notice-nJYs9BEu.js"));
19239
+ const NoticeModal = defineAsyncComponent(() => import("./notice-Cs9Tl869.js"));
19252
19240
  function clearNotice() {
19253
19241
  if (localStorage$2.getItem("validator_email")) {
19254
19242
  localStorage$2.removeItem("validator_email");
@@ -21728,9 +21716,9 @@ const _sfc_main$o = /* @__PURE__ */ defineComponent({
21728
21716
  const layoutConfig2 = useLayoutConfig();
21729
21717
  const { t: t2 } = i18n.global;
21730
21718
  const route = useRoute();
21731
- const MenuItem = defineAsyncComponent(() => import("./MenuItem-zJXVH_ZY.js"));
21732
- const ProjectMenuListV2 = defineAsyncComponent(() => import("./ProjectMenuListV2-H2VmzVSh.js"));
21733
- const ProjectMenuList = defineAsyncComponent(() => import("./ProjectMenuList-CDYlv4eo.js"));
21719
+ const MenuItem = defineAsyncComponent(() => import("./MenuItem-4Snoi1Jr.js"));
21720
+ const ProjectMenuListV2 = defineAsyncComponent(() => import("./ProjectMenuListV2-Bd8GGUTU.js"));
21721
+ const ProjectMenuList = defineAsyncComponent(() => import("./ProjectMenuList-Bw_8xPQ7.js"));
21734
21722
  const props = __props;
21735
21723
  const useReport2 = inject("useReport");
21736
21724
  const userInfo = inject("userInfo");
@@ -28268,7 +28256,7 @@ const _SlidCaptchaManager = class _SlidCaptchaManager {
28268
28256
  __publicField(_SlidCaptchaManager, "instance");
28269
28257
  let SlidCaptchaManager = _SlidCaptchaManager;
28270
28258
  const slidCaptchaManager = SlidCaptchaManager.getInstance();
28271
- const SlidCaptcha = defineAsyncComponent(() => import("./index-Bhjr8DTm.js"));
28259
+ const SlidCaptcha = defineAsyncComponent(() => import("./index-CUnbDxxi.js"));
28272
28260
  const useSlidCaptcha = () => {
28273
28261
  const { mount, unMount, isMounted } = usePopup("slid-captcha-popup");
28274
28262
  const open = (config2) => {
@@ -28298,7 +28286,7 @@ const useSlidCaptcha = () => {
28298
28286
  close
28299
28287
  };
28300
28288
  };
28301
- const YunpianCaptcha = defineAsyncComponent(() => import("./index-D0ueLDg1.js"));
28289
+ const YunpianCaptcha = defineAsyncComponent(() => import("./index-Dy5IHa2n.js"));
28302
28290
  const useYunpianCaptcha = () => {
28303
28291
  const { mount, unMount } = usePopup("yunpian-captcha-popup");
28304
28292
  const open = (config2) => {
@@ -31326,7 +31314,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
31326
31314
  };
31327
31315
  const focusInitial = () => {
31328
31316
  var _a;
31329
- (_a = filterInput.value ?? focusable()[0] ?? panel.value) == null ? void 0 : _a.focus();
31317
+ (_a = filterInput.value ?? panel.value) == null ? void 0 : _a.focus();
31330
31318
  };
31331
31319
  const onPreferenceChange = (event) => setCharacterShortcutsEnabled(event.target.checked);
31332
31320
  const onKeydown2 = (event) => {