vue-layout-gitcode 1.12.68 → 1.12.70

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.
@@ -2088,8 +2088,8 @@ function createDOMPurify() {
2088
2088
  };
2089
2089
  function _executeHooks(hooks2, currentNode, data) {
2090
2090
  if (hooks2.length === 0) return;
2091
- arrayForEach(hooks2, (hook) => {
2092
- hook.call(DOMPurify, currentNode, data, CONFIG);
2091
+ arrayForEach(hooks2, (hook2) => {
2092
+ hook2.call(DOMPurify, currentNode, data, CONFIG);
2093
2093
  });
2094
2094
  }
2095
2095
  const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
@@ -4972,8 +4972,8 @@ function createMessageContext(options = {}) {
4972
4972
  return ctx;
4973
4973
  }
4974
4974
  let devtools = null;
4975
- function setDevToolsHook(hook) {
4976
- devtools = hook;
4975
+ function setDevToolsHook(hook2) {
4976
+ devtools = hook2;
4977
4977
  }
4978
4978
  function initI18nDevTools(i18n2, version, meta) {
4979
4979
  devtools && devtools.emit("i18n:init", {
@@ -4987,8 +4987,8 @@ const translateDevTools = /* @__PURE__ */ createDevToolsHook(
4987
4987
  "function:translate"
4988
4988
  /* IntlifyDevToolsHooks.FunctionTranslate */
4989
4989
  );
4990
- function createDevToolsHook(hook) {
4991
- return (payloads) => devtools && devtools.emit(hook, payloads);
4990
+ function createDevToolsHook(hook2) {
4991
+ return (payloads) => devtools && devtools.emit(hook2, payloads);
4992
4992
  }
4993
4993
  const code$1$1 = CompileWarnCodes.__EXTEND_POINT__;
4994
4994
  const inc$1$1 = incrementer(code$1$1);
@@ -6108,12 +6108,12 @@ function now() {
6108
6108
  return isPerformanceSupported() ? perf.now() : Date.now();
6109
6109
  }
6110
6110
  class ApiProxy {
6111
- constructor(plugin, hook) {
6111
+ constructor(plugin, hook2) {
6112
6112
  this.target = null;
6113
6113
  this.targetQueue = [];
6114
6114
  this.onQueue = [];
6115
6115
  this.plugin = plugin;
6116
- this.hook = hook;
6116
+ this.hook = hook2;
6117
6117
  const defaultSettings = {};
6118
6118
  if (plugin.settings) {
6119
6119
  for (const id in plugin.settings) {
@@ -6144,8 +6144,8 @@ class ApiProxy {
6144
6144
  return now();
6145
6145
  }
6146
6146
  };
6147
- if (hook) {
6148
- hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
6147
+ if (hook2) {
6148
+ hook2.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
6149
6149
  if (pluginId === this.plugin.id) {
6150
6150
  this.fallbacks.setSettings(value);
6151
6151
  }
@@ -6208,12 +6208,12 @@ class ApiProxy {
6208
6208
  function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
6209
6209
  const descriptor = pluginDescriptor;
6210
6210
  const target = getTarget();
6211
- const hook = getDevtoolsGlobalHook();
6211
+ const hook2 = getDevtoolsGlobalHook();
6212
6212
  const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
6213
- if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
6214
- hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
6213
+ if (hook2 && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
6214
+ hook2.emit(HOOK_SETUP, pluginDescriptor, setupFn);
6215
6215
  } else {
6216
- const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
6216
+ const proxy = enableProxy ? new ApiProxy(descriptor, hook2) : null;
6217
6217
  const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
6218
6218
  list.push({
6219
6219
  pluginDescriptor: descriptor,
@@ -10581,6 +10581,23 @@ const _export_sfc = (sfc, props) => {
10581
10581
  return target;
10582
10582
  };
10583
10583
  const ToolsFloat = /* @__PURE__ */ _export_sfc(_sfc_main$U, [["__scopeId", "data-v-vue-layout-gitcode"]]);
10584
+ let hook = null;
10585
+ let inflight$1 = null;
10586
+ function setLoginSuccessHook(next) {
10587
+ hook = next;
10588
+ inflight$1 = null;
10589
+ }
10590
+ function hasLoginSuccessHook() {
10591
+ return hook !== null;
10592
+ }
10593
+ function awaitLoginSuccessHook(user) {
10594
+ if (!hook) return Promise.resolve();
10595
+ if (!inflight$1) {
10596
+ const run = hook;
10597
+ inflight$1 = Promise.resolve().then(() => run(user)).then(() => void 0, () => void 0);
10598
+ }
10599
+ return inflight$1;
10600
+ }
10584
10601
  var repoTypeEnum = /* @__PURE__ */ ((repoTypeEnum2) => {
10585
10602
  repoTypeEnum2["NORMAL"] = "0";
10586
10603
  repoTypeEnum2["MODEL"] = "1";
@@ -14909,56 +14926,422 @@ const _sfc_main$N = /* @__PURE__ */ defineComponent({
14909
14926
  }
14910
14927
  });
14911
14928
  const ClaimPower = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-vue-layout-gitcode"]]);
14912
- const DEFAULT_APPLICATION_HOST = "https://gitcode.com";
14913
- function normalizeApplicationHost(host) {
14914
- return (host || DEFAULT_APPLICATION_HOST).replace(/\/+$/, "");
14929
+ const SHORTCUT_STORAGE_KEY = "atomgit.character-shortcuts";
14930
+ const SHORTCUT_SEQUENCE_TIMEOUT = 1500;
14931
+ const SHORTCUT_GROUPS = ["site", "repo", "code", "editor", "list", "detail"];
14932
+ const BUILTIN_SHORTCUTS = [
14933
+ { id: "site.search", keys: "/", group: "site", labelKey: "shortcut.site.search" },
14934
+ { id: "site.searchLetter", keys: "s", group: "site", labelKey: "shortcut.site.search" },
14935
+ { id: "site.help", keys: "?", group: "site", labelKey: "shortcut.site.help" },
14936
+ { id: "site.notifications", keys: "g n", group: "site", labelKey: "shortcut.site.notifications" },
14937
+ { id: "site.commands", keys: "mod+k", group: "site", labelKey: "shortcut.site.commands" },
14938
+ { id: "site.escape", keys: "escape", group: "site", labelKey: "shortcut.dialog.close" }
14939
+ ];
14940
+ const isMacPlatform = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform);
14941
+ const parseShortcut = (keys, isMac = isMacPlatform()) => {
14942
+ if (!keys.trim()) {
14943
+ throw new Error("Shortcut keys must not be empty");
14944
+ }
14945
+ return keys.trim().split(/\s+/).map((token) => {
14946
+ const parts = token.toLowerCase().split("+");
14947
+ let key = parts.pop();
14948
+ if (key === "esc") {
14949
+ key = "escape";
14950
+ }
14951
+ if (key === "space") {
14952
+ key = " ";
14953
+ }
14954
+ const modifiers = new Set(parts);
14955
+ if (!key || parts.some((part) => !["ctrl", "meta", "alt", "shift", "mod"].includes(part)) || modifiers.size !== parts.length) {
14956
+ throw new Error(`Invalid shortcut: ${keys}`);
14957
+ }
14958
+ if (key.length !== 1 && !["escape", "enter", "tab", "backspace", "delete", "arrowup", "arrowdown", "arrowleft", "arrowright", "home", "end", "pageup", "pagedown"].includes(key)) {
14959
+ throw new Error(`Unsupported shortcut key: ${key}`);
14960
+ }
14961
+ return {
14962
+ key,
14963
+ ctrl: modifiers.has("ctrl") || modifiers.has("mod") && !isMac,
14964
+ meta: modifiers.has("meta") || modifiers.has("mod") && isMac,
14965
+ alt: modifiers.has("alt"),
14966
+ shift: modifiers.has("shift")
14967
+ };
14968
+ });
14969
+ };
14970
+ const matchesStroke = (event, stroke) => {
14971
+ const key = event.key.length === 1 && !stroke.shift ? event.key : event.key.toLowerCase();
14972
+ return key === stroke.key && event.ctrlKey === stroke.ctrl && event.metaKey === stroke.meta && event.altKey === stroke.alt && (stroke.key === "?" || event.shiftKey === stroke.shift);
14973
+ };
14974
+ const isCharacterShortcut = (strokes) => strokes.every((stroke) => stroke.key.length === 1 && !stroke.ctrl && !stroke.meta && !stroke.alt);
14975
+ const normalizeShortcut = (keys, isMac) => parseShortcut(keys, isMac).map((stroke) => JSON.stringify({ ...stroke, shift: stroke.key === "?" ? false : stroke.shift }));
14976
+ const config = shallowRef({ actions: [] });
14977
+ const shortcutConfig = readonly(config);
14978
+ const shortcutRevision = shallowRef(0);
14979
+ function setShortcutConfig(next) {
14980
+ if (typeof window === "undefined") {
14981
+ return;
14982
+ }
14983
+ const actions = [...BUILTIN_SHORTCUTS, ...next.actions];
14984
+ try {
14985
+ for (const isMac of [false, true]) {
14986
+ const normalized = actions.map((action) => normalizeShortcut(action.keys, isMac));
14987
+ for (let i = 0; i < actions.length; i++) {
14988
+ for (let j = i + 1; j < actions.length; j++) {
14989
+ const a = normalized[i];
14990
+ const b = normalized[j];
14991
+ const prefix = a.slice(0, Math.min(a.length, b.length)).every((key, index2) => key === b[index2]);
14992
+ if (actions[i].id === actions[j].id || prefix) {
14993
+ throw new Error(`Shortcut conflict: ${actions[i].id} (${actions[i].keys}) / ${actions[j].id} (${actions[j].keys})`);
14994
+ }
14995
+ }
14996
+ }
14997
+ }
14998
+ } catch (error) {
14999
+ console.error(error);
15000
+ return;
15001
+ }
15002
+ config.value = { actions: next.actions.map((action) => ({ ...action })), isBlocked: next.isBlocked };
15003
+ shortcutRevision.value++;
14915
15004
  }
14916
- function getRoutePart(href, baseUrl) {
15005
+ function useShortcutConfig() {
15006
+ return readonly({
15007
+ get actions() {
15008
+ return config.value.actions;
15009
+ },
15010
+ get isBlocked() {
15011
+ return config.value.isBlocked;
15012
+ }
15013
+ });
15014
+ }
15015
+ const isEditableTarget = (target) => {
15016
+ if (!target || typeof Element === "undefined" || !(target instanceof Element)) {
15017
+ return false;
15018
+ }
15019
+ 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"]'));
15020
+ };
15021
+ const isComposingEvent = (event) => event.isComposing || event.keyCode === 229;
15022
+ const shouldIgnoreShortcut = (event) => event.defaultPrevented || event.repeat || isComposingEvent(event) || event.composedPath().some(isEditableTarget) || isEditableTarget(event.target) || typeof document !== "undefined" && isEditableTarget(document.activeElement);
15023
+ let current = null;
15024
+ const enabled = ref(true);
15025
+ const characterShortcutsEnabled = readonly(enabled);
15026
+ const parsePreference = (raw) => {
14917
15027
  try {
14918
- const url = new URL(href || "/", `${baseUrl}/`);
14919
- return `${url.pathname || "/"}${url.search}${url.hash}`;
15028
+ const record = JSON.parse(raw || "null");
15029
+ if (record && (record.value === "on" || record.value === "off") && Number.isSafeInteger(record.updatedAt) && record.updatedAt >= 0) {
15030
+ return { value: record.value, updatedAt: record.updatedAt };
15031
+ }
14920
15032
  } catch {
14921
- const value = href.trim();
14922
- return value.startsWith("/") ? value : `/${value}`;
14923
15033
  }
15034
+ return null;
15035
+ };
15036
+ const newestPreference = (records) => records.reduce((latest, record) => {
15037
+ if (!record) {
15038
+ return latest;
15039
+ }
15040
+ if (!latest || record.updatedAt > latest.updatedAt || record.updatedAt === latest.updatedAt && record.value === "off") {
15041
+ return record;
15042
+ }
15043
+ return latest;
15044
+ }, null);
15045
+ function refreshShortcutPreference() {
15046
+ if (typeof window === "undefined") {
15047
+ return;
15048
+ }
15049
+ let cookie = null;
15050
+ try {
15051
+ cookie = parsePreference(api.get(SHORTCUT_STORAGE_KEY));
15052
+ } catch {
15053
+ }
15054
+ current = newestPreference([current, cookie, parsePreference(localStorage$2.getItem(SHORTCUT_STORAGE_KEY))]);
15055
+ enabled.value = (current == null ? void 0 : current.value) !== "off";
14924
15056
  }
14925
- function toApplicationUrl(applicationHost, href) {
14926
- const host = normalizeApplicationHost(applicationHost);
14927
- return `${host}${getRoutePart(href, host)}`;
14928
- }
14929
- function toApplicationRoute(applicationHost, href) {
15057
+ function setCharacterShortcutsEnabled(value) {
15058
+ if (typeof window === "undefined") {
15059
+ return;
15060
+ }
15061
+ refreshShortcutPreference();
15062
+ current = { value: value ? "on" : "off", updatedAt: Math.max(Date.now(), ((current == null ? void 0 : current.updatedAt) ?? -1) + 1) };
15063
+ enabled.value = value;
15064
+ const serialized = JSON.stringify(current);
15065
+ localStorage$2.setItem(SHORTCUT_STORAGE_KEY, serialized);
14930
15066
  try {
14931
- const url = new URL(toApplicationUrl(applicationHost, href));
14932
- return `${url.pathname || "/"}${url.search}${url.hash}`;
15067
+ const domain = COOKIE_DOMAIN().replace(/^\./, "");
15068
+ const hostname = window.location.hostname;
15069
+ const shared = hostname === domain || hostname.endsWith(`.${domain}`);
15070
+ api.set(SHORTCUT_STORAGE_KEY, serialized, {
15071
+ expires: 365,
15072
+ path: "/",
15073
+ sameSite: "Lax",
15074
+ secure: window.location.protocol === "https:",
15075
+ ...shared ? { domain: `.${domain}` } : {}
15076
+ });
15077
+ if (api.get(SHORTCUT_STORAGE_KEY) !== serialized) {
15078
+ return;
15079
+ }
14933
15080
  } catch {
14934
- return null;
14935
15081
  }
14936
15082
  }
14937
- const HEADER_CREATE_MENU_PATHS = [
14938
- "/create?position=nav_top",
14939
- "/create/migrate?type=3",
14940
- "/models/create",
14941
- "/datasets/create",
14942
- "/space/create",
14943
- "/collections/create",
14944
- "/org/create"
14945
- ];
14946
- const HEADER_CREATE_ENTERPRISE_PATH = "/enterprises/new";
14947
- const _hoisted_1$F = { class: "g-header-create dashboard-create-menu" };
14948
- const _hoisted_2$w = ["title", "aria-label", "aria-expanded"];
14949
- const _hoisted_3$v = { class: "dashboard-create-menu__trigger-text" };
14950
- const _hoisted_4$o = ["aria-label"];
14951
- const _hoisted_5$j = {
14952
- key: 0,
14953
- class: "dashboard-create-menu__divider",
14954
- role: "separator"
15083
+ const providers = shallowRef([]);
15084
+ const searches = shallowRef([]);
15085
+ const notices = shallowRef([]);
15086
+ const blockers = shallowRef([]);
15087
+ const isBlocked = () => {
15088
+ var _a, _b;
15089
+ return Boolean(((_b = (_a = shortcutConfig.value).isBlocked) == null ? void 0 : _b.call(_a)) || blockers.value.some((blocked) => blocked()));
14955
15090
  };
14956
- const _hoisted_6$i = ["href", "onClick", "onKeydown"];
14957
- const _hoisted_7$f = { class: "dashboard-create-menu__title-row" };
14958
- const _hoisted_8$d = { class: "dashboard-create-menu__title" };
14959
- const _hoisted_9$b = {
14960
- key: 0,
14961
- class: "dashboard-create-menu__desc"
15091
+ const dialog = ref(null);
15092
+ const shortcutDialog = readonly(dialog);
15093
+ const hasShortcutProvider = computed(() => providers.value.length > 0);
15094
+ let returnFocus = null;
15095
+ let pending = [];
15096
+ let timer;
15097
+ let detach;
15098
+ function resetShortcutSequence() {
15099
+ pending = [];
15100
+ clearTimeout(timer);
15101
+ timer = void 0;
15102
+ }
15103
+ function openShortcutHelp() {
15104
+ openDialog("help");
15105
+ }
15106
+ function openShortcutCommands() {
15107
+ openDialog("commands");
15108
+ }
15109
+ function openDialog(mode) {
15110
+ if (!hasShortcutProvider.value || typeof document === "undefined" || isBlocked()) {
15111
+ return;
15112
+ }
15113
+ if (!dialog.value) {
15114
+ returnFocus = document.activeElement;
15115
+ }
15116
+ resetShortcutSequence();
15117
+ dialog.value = mode;
15118
+ }
15119
+ function closeShortcutDialog(restoreFocus = true) {
15120
+ dialog.value = null;
15121
+ const previous = returnFocus;
15122
+ returnFocus = null;
15123
+ if (restoreFocus && typeof document !== "undefined") {
15124
+ void nextTick(() => {
15125
+ const target = (previous == null ? void 0 : previous.isConnected) ? previous : document.querySelector("[data-shortcut-help]");
15126
+ target == null ? void 0 : target.focus();
15127
+ });
15128
+ }
15129
+ }
15130
+ const activeTarget = (targets) => [...targets].reverse().find((target) => target.when());
15131
+ const builtinActions = computed(() => BUILTIN_SHORTCUTS.filter((item) => item.id !== "site.escape").map((item) => {
15132
+ if (item.id === "site.search" || item.id === "site.searchLetter") {
15133
+ return { ...item, when: () => Boolean(activeTarget(searches.value)), run: () => {
15134
+ var _a;
15135
+ return (_a = activeTarget(searches.value)) == null ? void 0 : _a.run();
15136
+ } };
15137
+ }
15138
+ if (item.id === "site.notifications") {
15139
+ return { ...item, when: () => Boolean(activeTarget(notices.value)), run: () => {
15140
+ var _a;
15141
+ return (_a = activeTarget(notices.value)) == null ? void 0 : _a.run();
15142
+ } };
15143
+ }
15144
+ return { ...item, run: item.id === "site.help" ? openShortcutHelp : openShortcutCommands };
15145
+ }));
15146
+ const getAvailableShortcutActions = () => {
15147
+ if (!hasShortcutProvider.value) {
15148
+ return builtinActions.value.filter((action) => action.id === "site.search" && (!action.when || action.when()));
15149
+ }
15150
+ return [...builtinActions.value, ...shortcutConfig.value.actions].filter((action) => !action.when || action.when());
15151
+ };
15152
+ const selectionRevision = ref(0);
15153
+ const onSelectionChange = () => {
15154
+ selectionRevision.value += 1;
15155
+ };
15156
+ const availableShortcutActions = computed(() => {
15157
+ void selectionRevision.value;
15158
+ return getAvailableShortcutActions();
15159
+ });
15160
+ function executeShortcutAction(action) {
15161
+ if (isBlocked() || !getAvailableShortcutActions().some((item) => item.id === action.id) || action.when && !action.when()) {
15162
+ return;
15163
+ }
15164
+ closeShortcutDialog(false);
15165
+ void nextTick(() => {
15166
+ const current2 = getAvailableShortcutActions().find((item) => item.id === action.id);
15167
+ if (!isBlocked() && current2) {
15168
+ current2.run();
15169
+ }
15170
+ });
15171
+ }
15172
+ function onKeydown(event) {
15173
+ if (shouldIgnoreShortcut(event)) {
15174
+ resetShortcutSequence();
15175
+ return;
15176
+ }
15177
+ if (dialog.value || isBlocked()) {
15178
+ resetShortcutSequence();
15179
+ return;
15180
+ }
15181
+ if (event.key === "Escape") {
15182
+ if (pending.length) {
15183
+ event.preventDefault();
15184
+ resetShortcutSequence();
15185
+ }
15186
+ return;
15187
+ }
15188
+ const candidates = getAvailableShortcutActions().map((action) => ({ action, strokes: parseShortcut(action.keys) })).filter(({ strokes }) => characterShortcutsEnabled.value || !isCharacterShortcut(strokes));
15189
+ const matches = candidates.filter(({ strokes }) => strokes.length > pending.length && pending.every((key, index2) => key === JSON.stringify(strokes[index2])) && matchesStroke(event, strokes[pending.length]));
15190
+ const complete = matches.find(({ strokes }) => strokes.length === pending.length + 1);
15191
+ if (complete) {
15192
+ resetShortcutSequence();
15193
+ if (!complete.action.when || complete.action.when()) {
15194
+ event.preventDefault();
15195
+ complete.action.run();
15196
+ }
15197
+ } else if (matches.length) {
15198
+ pending.push(JSON.stringify(matches[0].strokes[pending.length]));
15199
+ clearTimeout(timer);
15200
+ timer = setTimeout(resetShortcutSequence, SHORTCUT_SEQUENCE_TIMEOUT);
15201
+ } else {
15202
+ resetShortcutSequence();
15203
+ }
15204
+ }
15205
+ function syncListener() {
15206
+ if (typeof document === "undefined") {
15207
+ return;
15208
+ }
15209
+ const needed = providers.value.length + searches.value.length > 0;
15210
+ if (!needed) {
15211
+ detach == null ? void 0 : detach();
15212
+ detach = void 0;
15213
+ resetShortcutSequence();
15214
+ return;
15215
+ }
15216
+ if (detach) {
15217
+ return;
15218
+ }
15219
+ refreshShortcutPreference();
15220
+ const onFocus = (event) => {
15221
+ if (isEditableTarget(event.target)) {
15222
+ resetShortcutSequence();
15223
+ }
15224
+ };
15225
+ document.addEventListener("keydown", onKeydown);
15226
+ document.addEventListener("focusin", onFocus);
15227
+ document.addEventListener("compositionstart", resetShortcutSequence);
15228
+ document.addEventListener("selectionchange", onSelectionChange);
15229
+ window.addEventListener("blur", resetShortcutSequence);
15230
+ window.addEventListener("focus", refreshShortcutPreference);
15231
+ const scope = effectScope(true);
15232
+ scope.run(() => {
15233
+ watch(shortcutRevision, resetShortcutSequence, { flush: "sync" });
15234
+ watch(characterShortcutsEnabled, resetShortcutSequence, { flush: "sync" });
15235
+ watch(isBlocked, resetShortcutSequence, { flush: "sync" });
15236
+ });
15237
+ detach = () => {
15238
+ document.removeEventListener("keydown", onKeydown);
15239
+ document.removeEventListener("focusin", onFocus);
15240
+ document.removeEventListener("compositionstart", resetShortcutSequence);
15241
+ document.removeEventListener("selectionchange", onSelectionChange);
15242
+ window.removeEventListener("blur", resetShortcutSequence);
15243
+ window.removeEventListener("focus", refreshShortcutPreference);
15244
+ scope.stop();
15245
+ };
15246
+ }
15247
+ function registerShortcutProvider() {
15248
+ const id = Symbol("shortcut-provider");
15249
+ providers.value = [...providers.value, id];
15250
+ syncListener();
15251
+ return {
15252
+ isOwner: computed(() => providers.value[0] === id),
15253
+ dispose: () => {
15254
+ providers.value = providers.value.filter((item) => item !== id);
15255
+ if (!providers.value.length) {
15256
+ closeShortcutDialog();
15257
+ resetShortcutSequence();
15258
+ }
15259
+ syncListener();
15260
+ }
15261
+ };
15262
+ }
15263
+ function registerTarget(target, collection) {
15264
+ collection.value = [...collection.value, target];
15265
+ syncListener();
15266
+ return () => {
15267
+ collection.value = collection.value.filter((item) => item !== target);
15268
+ syncListener();
15269
+ };
15270
+ }
15271
+ const registerShortcutSearch = (target) => registerTarget(target, searches);
15272
+ const registerShortcutNotice = (target) => registerTarget(target, notices);
15273
+ function useShortcutSearch(target) {
15274
+ let dispose;
15275
+ onMounted(() => {
15276
+ dispose = registerShortcutSearch(target);
15277
+ });
15278
+ onUnmounted(() => dispose == null ? void 0 : dispose());
15279
+ }
15280
+ function useShortcutNotice(target) {
15281
+ let dispose;
15282
+ onMounted(() => {
15283
+ dispose = registerShortcutNotice(target);
15284
+ });
15285
+ onUnmounted(() => dispose == null ? void 0 : dispose());
15286
+ }
15287
+ function useShortcutBlocker(blocked) {
15288
+ onMounted(() => {
15289
+ blockers.value = [...blockers.value, blocked];
15290
+ });
15291
+ onUnmounted(() => {
15292
+ blockers.value = blockers.value.filter((item) => item !== blocked);
15293
+ });
15294
+ }
15295
+ const DEFAULT_APPLICATION_HOST = "https://gitcode.com";
15296
+ function normalizeApplicationHost(host) {
15297
+ return (host || DEFAULT_APPLICATION_HOST).replace(/\/+$/, "");
15298
+ }
15299
+ function getRoutePart(href, baseUrl) {
15300
+ try {
15301
+ const url = new URL(href || "/", `${baseUrl}/`);
15302
+ return `${url.pathname || "/"}${url.search}${url.hash}`;
15303
+ } catch {
15304
+ const value = href.trim();
15305
+ return value.startsWith("/") ? value : `/${value}`;
15306
+ }
15307
+ }
15308
+ function toApplicationUrl(applicationHost, href) {
15309
+ const host = normalizeApplicationHost(applicationHost);
15310
+ return `${host}${getRoutePart(href, host)}`;
15311
+ }
15312
+ function toApplicationRoute(applicationHost, href) {
15313
+ try {
15314
+ const url = new URL(toApplicationUrl(applicationHost, href));
15315
+ return `${url.pathname || "/"}${url.search}${url.hash}`;
15316
+ } catch {
15317
+ return null;
15318
+ }
15319
+ }
15320
+ const HEADER_CREATE_MENU_PATHS = [
15321
+ "/create?position=nav_top",
15322
+ "/create/migrate?type=3",
15323
+ "/models/create",
15324
+ "/datasets/create",
15325
+ "/space/create",
15326
+ "/collections/create",
15327
+ "/org/create"
15328
+ ];
15329
+ const HEADER_CREATE_ENTERPRISE_PATH = "/enterprises/new";
15330
+ const _hoisted_1$F = { class: "g-header-create dashboard-create-menu" };
15331
+ const _hoisted_2$w = ["title", "aria-label", "aria-expanded"];
15332
+ const _hoisted_3$v = { class: "dashboard-create-menu__trigger-text" };
15333
+ const _hoisted_4$o = ["aria-label"];
15334
+ const _hoisted_5$j = {
15335
+ key: 0,
15336
+ class: "dashboard-create-menu__divider",
15337
+ role: "separator"
15338
+ };
15339
+ const _hoisted_6$i = ["href", "onClick", "onKeydown"];
15340
+ const _hoisted_7$f = { class: "dashboard-create-menu__title-row" };
15341
+ const _hoisted_8$d = { class: "dashboard-create-menu__title" };
15342
+ const _hoisted_9$b = {
15343
+ key: 0,
15344
+ class: "dashboard-create-menu__desc"
14962
15345
  };
14963
15346
  const menuId = "gitcode-header-create-menu";
14964
15347
  const _sfc_main$M = /* @__PURE__ */ defineComponent({
@@ -14985,6 +15368,7 @@ const _sfc_main$M = /* @__PURE__ */ defineComponent({
14985
15368
  const triggerRef = ref(null);
14986
15369
  const menuRef = ref(null);
14987
15370
  const menuOpen = ref(false);
15371
+ useShortcutBlocker(() => menuOpen.value);
14988
15372
  const defaultMenuItems = computed(() => {
14989
15373
  const [repoPath, importPath, modelPath, datasetPath, spacePath, collectionPath, orgPath] = HEADER_CREATE_MENU_PATHS;
14990
15374
  return [
@@ -16158,492 +16542,126 @@ const _sfc_main$E = /* @__PURE__ */ defineComponent({
16158
16542
  createElementVNode("img", {
16159
16543
  class: "level-avatar",
16160
16544
  src: levelInfo.value.avatar,
16161
- alt: ""
16162
- }, null, 8, _hoisted_3$r),
16163
- createElementVNode("div", _hoisted_4$l, [
16164
- createElementVNode("div", null, toDisplayString$1(levelInfo.value.name), 1),
16165
- createElementVNode("div", _hoisted_5$g, [
16166
- createElementVNode("img", {
16167
- src: levelInfo.value.level,
16168
- alt: ""
16169
- }, null, 8, _hoisted_6$f)
16170
- ])
16171
- ])
16172
- ]),
16173
- createElementVNode("div", _hoisted_7$c, [
16174
- createElementVNode("div", _hoisted_8$a, toDisplayString$1(unref(t2)("gitCodeLayout.userSetting.tips.getPoints")), 1)
16175
- ])
16176
- ], 2);
16177
- };
16178
- }
16179
- });
16180
- const UserLevel = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-vue-layout-gitcode"]]);
16181
- const _hoisted_1$y = { class: "g-account-switch-menu" };
16182
- const _hoisted_2$r = {
16183
- key: 0,
16184
- class: "g-account-switch-title"
16185
- };
16186
- const _hoisted_3$q = ["disabled", "onClick"];
16187
- const _hoisted_4$k = ["title"];
16188
- const _hoisted_5$f = {
16189
- key: 0,
16190
- class: "g-account-switch-status"
16191
- };
16192
- const _hoisted_6$e = ["disabled", "aria-label", "title", "onClick"];
16193
- const _hoisted_7$b = ["disabled"];
16194
- const _hoisted_8$9 = ["disabled"];
16195
- const _sfc_main$D = /* @__PURE__ */ defineComponent({
16196
- __name: "AccountSessionList",
16197
- props: {
16198
- items: { default: () => [] },
16199
- activeRef: { default: null },
16200
- max: { default: 5 },
16201
- busy: { type: Boolean, default: false }
16202
- },
16203
- emits: ["switch", "add", "reauthorize", "remove", "logout"],
16204
- setup(__props, { emit: __emit }) {
16205
- const props = __props;
16206
- const emit = __emit;
16207
- const { t: t2 } = i18n.global;
16208
- const otherAccounts = computed(() => props.items.filter((item) => item.ref !== props.activeRef && !item.active));
16209
- const canAdd = computed(() => props.items.length < props.max);
16210
- return (_ctx, _cache) => {
16211
- return openBlock(), createElementBlock("div", _hoisted_1$y, [
16212
- otherAccounts.value.length ? (openBlock(), createElementBlock("div", _hoisted_2$r, toDisplayString$1(unref(t2)("gitCodeLayout.header.accountSwitchTitle")), 1)) : createCommentVNode("", true),
16213
- (openBlock(true), createElementBlock(Fragment, null, renderList(otherAccounts.value, (item) => {
16214
- return openBlock(), createElementBlock("div", {
16215
- key: item.ref,
16216
- class: "g-account-switch-row"
16217
- }, [
16218
- createElementVNode("button", {
16219
- class: "g-account-switch-member",
16220
- type: "button",
16221
- disabled: __props.busy,
16222
- onClick: ($event) => item.status === "need_reauth" ? emit("reauthorize", item.ref) : emit("switch", item.ref)
16223
- }, [
16224
- createVNode(_sfc_main$R, {
16225
- name: item.nickname || item.username,
16226
- src: item.avatarUrl || "",
16227
- width: 28,
16228
- height: 28
16229
- }, null, 8, ["name", "src"]),
16230
- createElementVNode("span", {
16231
- class: "g-account-switch-name",
16232
- title: item.username
16233
- }, toDisplayString$1(item.username), 9, _hoisted_4$k),
16234
- item.status === "need_reauth" ? (openBlock(), createElementBlock("span", _hoisted_5$f, toDisplayString$1(unref(t2)("gitCodeLayout.header.accountNeedReauth")), 1)) : createCommentVNode("", true)
16235
- ], 8, _hoisted_3$q),
16236
- createElementVNode("button", {
16237
- class: "g-account-switch-remove",
16238
- type: "button",
16239
- disabled: __props.busy,
16240
- "aria-label": `${unref(t2)("gitCodeLayout.header.accountRemove")} ${item.username}`,
16241
- title: unref(t2)("gitCodeLayout.header.accountRemove"),
16242
- onClick: ($event) => emit("remove", item.ref)
16243
- }, "×", 8, _hoisted_6$e)
16244
- ]);
16245
- }), 128)),
16246
- createElementVNode("div", {
16247
- class: normalizeClass(["g-account-switch-actions", { "g-account-switch-actions--divided": otherAccounts.value.length }])
16248
- }, [
16249
- canAdd.value ? (openBlock(), createElementBlock("button", {
16250
- key: 0,
16251
- type: "button",
16252
- class: "g-account-switch-action",
16253
- disabled: __props.busy,
16254
- onClick: _cache[0] || (_cache[0] = ($event) => emit("add"))
16255
- }, [
16256
- createVNode(GIcon, {
16257
- name: "gt-plane-users",
16258
- size: "16px"
16259
- }),
16260
- createTextVNode(toDisplayString$1(unref(t2)("gitCodeLayout.header.accountAdd")), 1)
16261
- ], 8, _hoisted_7$b)) : createCommentVNode("", true),
16262
- otherAccounts.value.length ? (openBlock(), createElementBlock("button", {
16263
- key: 1,
16264
- type: "button",
16265
- class: "g-account-switch-action",
16266
- disabled: __props.busy,
16267
- onClick: _cache[1] || (_cache[1] = ($event) => emit("logout"))
16268
- }, [
16269
- createVNode(GIcon, {
16270
- name: "gt-default",
16271
- size: "16px"
16272
- }),
16273
- createTextVNode(" " + toDisplayString$1(unref(t2)("gitCodeLayout.header.logout")), 1)
16274
- ], 8, _hoisted_8$9)) : createCommentVNode("", true)
16275
- ], 2)
16276
- ]);
16277
- };
16278
- }
16279
- });
16280
- const AccountSessionList = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-vue-layout-gitcode"]]);
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")
16319
- };
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})`);
16346
- }
16347
- }
16348
- }
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}` } : {}
16428
- });
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()));
16545
+ alt: ""
16546
+ }, null, 8, _hoisted_3$r),
16547
+ createElementVNode("div", _hoisted_4$l, [
16548
+ createElementVNode("div", null, toDisplayString$1(levelInfo.value.name), 1),
16549
+ createElementVNode("div", _hoisted_5$g, [
16550
+ createElementVNode("img", {
16551
+ src: levelInfo.value.level,
16552
+ alt: ""
16553
+ }, null, 8, _hoisted_6$f)
16554
+ ])
16555
+ ])
16556
+ ]),
16557
+ createElementVNode("div", _hoisted_7$c, [
16558
+ createElementVNode("div", _hoisted_8$a, toDisplayString$1(unref(t2)("gitCodeLayout.userSetting.tips.getPoints")), 1)
16559
+ ])
16560
+ ], 2);
16561
+ };
16501
16562
  }
16502
- return [...builtinActions.value, ...shortcutConfig.value.actions].filter((action) => !action.when || action.when());
16563
+ });
16564
+ const UserLevel = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-vue-layout-gitcode"]]);
16565
+ const _hoisted_1$y = { class: "g-account-switch-menu" };
16566
+ const _hoisted_2$r = {
16567
+ key: 0,
16568
+ class: "g-account-switch-title"
16503
16569
  };
16504
- const selectionRevision = ref(0);
16505
- const onSelectionChange = () => {
16506
- selectionRevision.value += 1;
16570
+ const _hoisted_3$q = ["disabled", "onClick"];
16571
+ const _hoisted_4$k = ["title"];
16572
+ const _hoisted_5$f = {
16573
+ key: 0,
16574
+ class: "g-account-switch-status"
16507
16575
  };
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;
16576
+ const _hoisted_6$e = ["disabled", "aria-label", "title", "onClick"];
16577
+ const _hoisted_7$b = ["disabled"];
16578
+ const _hoisted_8$9 = ["disabled"];
16579
+ const _sfc_main$D = /* @__PURE__ */ defineComponent({
16580
+ __name: "AccountSessionList",
16581
+ props: {
16582
+ items: { default: () => [] },
16583
+ activeRef: { default: null },
16584
+ max: { default: 5 },
16585
+ busy: { type: Boolean, default: false }
16586
+ },
16587
+ emits: ["switch", "add", "reauthorize", "remove", "logout"],
16588
+ setup(__props, { emit: __emit }) {
16589
+ const props = __props;
16590
+ const emit = __emit;
16591
+ const { t: t2 } = i18n.global;
16592
+ const otherAccounts = computed(() => props.items.filter((item) => item.ref !== props.activeRef && !item.active));
16593
+ const canAdd = computed(() => props.items.length < props.max);
16594
+ return (_ctx, _cache) => {
16595
+ return openBlock(), createElementBlock("div", _hoisted_1$y, [
16596
+ otherAccounts.value.length ? (openBlock(), createElementBlock("div", _hoisted_2$r, toDisplayString$1(unref(t2)("gitCodeLayout.header.accountSwitchTitle")), 1)) : createCommentVNode("", true),
16597
+ (openBlock(true), createElementBlock(Fragment, null, renderList(otherAccounts.value, (item) => {
16598
+ return openBlock(), createElementBlock("div", {
16599
+ key: item.ref,
16600
+ class: "g-account-switch-row"
16601
+ }, [
16602
+ createElementVNode("button", {
16603
+ class: "g-account-switch-member",
16604
+ type: "button",
16605
+ disabled: __props.busy,
16606
+ onClick: ($event) => item.status === "need_reauth" ? emit("reauthorize", item.ref) : emit("switch", item.ref)
16607
+ }, [
16608
+ createVNode(_sfc_main$R, {
16609
+ name: item.nickname || item.username,
16610
+ src: item.avatarUrl || "",
16611
+ width: 28,
16612
+ height: 28
16613
+ }, null, 8, ["name", "src"]),
16614
+ createElementVNode("span", {
16615
+ class: "g-account-switch-name",
16616
+ title: item.nickname || item.username
16617
+ }, toDisplayString$1(item.nickname || item.username), 9, _hoisted_4$k),
16618
+ item.status === "need_reauth" ? (openBlock(), createElementBlock("span", _hoisted_5$f, toDisplayString$1(unref(t2)("gitCodeLayout.header.accountNeedReauth")), 1)) : createCommentVNode("", true)
16619
+ ], 8, _hoisted_3$q),
16620
+ createElementVNode("button", {
16621
+ class: "g-account-switch-remove",
16622
+ type: "button",
16623
+ disabled: __props.busy,
16624
+ "aria-label": `${unref(t2)("gitCodeLayout.header.accountRemove")} ${item.nickname || item.username}`,
16625
+ title: unref(t2)("gitCodeLayout.header.accountRemove"),
16626
+ onClick: ($event) => emit("remove", item.ref)
16627
+ }, "×", 8, _hoisted_6$e)
16628
+ ]);
16629
+ }), 128)),
16630
+ createElementVNode("div", {
16631
+ class: normalizeClass(["g-account-switch-actions", { "g-account-switch-actions--divided": otherAccounts.value.length }])
16632
+ }, [
16633
+ canAdd.value ? (openBlock(), createElementBlock("button", {
16634
+ key: 0,
16635
+ type: "button",
16636
+ class: "g-account-switch-action",
16637
+ disabled: __props.busy,
16638
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("add"))
16639
+ }, [
16640
+ createVNode(GIcon, {
16641
+ name: "gt-plane-users",
16642
+ size: "16px"
16643
+ }),
16644
+ createTextVNode(toDisplayString$1(unref(t2)("gitCodeLayout.header.accountAdd")), 1)
16645
+ ], 8, _hoisted_7$b)) : createCommentVNode("", true),
16646
+ otherAccounts.value.length ? (openBlock(), createElementBlock("button", {
16647
+ key: 1,
16648
+ type: "button",
16649
+ class: "g-account-switch-action",
16650
+ disabled: __props.busy,
16651
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("logout"))
16652
+ }, [
16653
+ createVNode(GIcon, {
16654
+ name: "gt-default",
16655
+ size: "16px"
16656
+ }),
16657
+ createTextVNode(" " + toDisplayString$1(unref(t2)("gitCodeLayout.header.logout")), 1)
16658
+ ], 8, _hoisted_8$9)) : createCommentVNode("", true)
16659
+ ], 2)
16660
+ ]);
16661
+ };
16570
16662
  }
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
- }
16663
+ });
16664
+ const AccountSessionList = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-vue-layout-gitcode"]]);
16647
16665
  const _hoisted_1$x = { class: "g-user-drawer-account-heading" };
16648
16666
  const _hoisted_2$q = { class: "g-user-drawer-info-list" };
16649
16667
  const _hoisted_3$p = { class: "g-user-drawer-info-list__name-wrap" };
@@ -17869,12 +17887,12 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
17869
17887
  setup(__props) {
17870
17888
  const layoutConfig2 = useLayoutConfig();
17871
17889
  const { t: $t } = i18n.global;
17872
- const ProjectSearch = defineAsyncComponent(() => import("./ProjectSearch-D4RbOLXG.js"));
17873
- const UserSearch = defineAsyncComponent(() => import("./UserSearch-CWat7_4C.js"));
17874
- const GloabarSearch = defineAsyncComponent(() => import("./GloabarSearch-Cng9q4kT.js"));
17875
- const SearchHistoryList = defineAsyncComponent(() => import("./SearchHistoryList-DhO5xZhZ.js"));
17876
- const SearchScopeList = defineAsyncComponent(() => import("./SearchScopeList-_c_QObw9.js"));
17877
- const SearchRecommed = defineAsyncComponent(() => import("./SearchRecommed-BuS3kfJi.js"));
17890
+ const ProjectSearch = defineAsyncComponent(() => import("./ProjectSearch-RSdaTDOF.js"));
17891
+ const UserSearch = defineAsyncComponent(() => import("./UserSearch-D3SVaI-D.js"));
17892
+ const GloabarSearch = defineAsyncComponent(() => import("./GloabarSearch-D_ThdbkB.js"));
17893
+ const SearchHistoryList = defineAsyncComponent(() => import("./SearchHistoryList-hhmomkL4.js"));
17894
+ const SearchScopeList = defineAsyncComponent(() => import("./SearchScopeList-BnGtfIrt.js"));
17895
+ const SearchRecommed = defineAsyncComponent(() => import("./SearchRecommed-BrpZoy5Y.js"));
17878
17896
  const props = __props;
17879
17897
  const repoInfo = inject("repoInfo", computed(() => void 0));
17880
17898
  const orgInfo = inject("orgInfo", computed(() => void 0));
@@ -18342,9 +18360,11 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
18342
18360
  const index2 = (_a = searchHotWords.value) == null ? void 0 : _a.findIndex((item) => item.content === searchStr.value);
18343
18361
  activeSearchKey.value = index2 === -1 ? 0 : index2;
18344
18362
  document.addEventListener("keydown", function(event) {
18363
+ var _a2;
18345
18364
  if (event.key === "Escape") {
18346
18365
  isFocus.value = false;
18347
18366
  searchDropDownVisible.value = false;
18367
+ (_a2 = inputRef.value) == null ? void 0 : _a2.blur();
18348
18368
  }
18349
18369
  });
18350
18370
  });
@@ -19236,7 +19256,7 @@ const vElementExposure = {
19236
19256
  beforeUnmount() {
19237
19257
  }
19238
19258
  };
19239
- const NoticeModal = defineAsyncComponent(() => import("./notice-bcah4Y8T.js"));
19259
+ const NoticeModal = defineAsyncComponent(() => import("./notice-BwsNVOvS.js"));
19240
19260
  function clearNotice() {
19241
19261
  if (localStorage$2.getItem("validator_email")) {
19242
19262
  localStorage$2.removeItem("validator_email");
@@ -19679,7 +19699,7 @@ const _sfc_main$v = /* @__PURE__ */ defineComponent({
19679
19699
  login(newOptions, props.loginSuccess);
19680
19700
  });
19681
19701
  addEventListener("updateUserInfo", (options) => {
19682
- props.loginSuccess(options);
19702
+ if (!hasLoginSuccessHook()) props.loginSuccess(options);
19683
19703
  });
19684
19704
  addEventListener("notice", toNotice);
19685
19705
  addEventListener("resetPwdDirectlySuccess", () => {
@@ -21297,7 +21317,7 @@ const _sfc_main$p = /* @__PURE__ */ defineComponent({
21297
21317
  login(newOptions, props.loginSuccess);
21298
21318
  });
21299
21319
  addEventListener("updateUserInfo", (options) => {
21300
- props.loginSuccess(options);
21320
+ if (!hasLoginSuccessHook()) props.loginSuccess(options);
21301
21321
  });
21302
21322
  addEventListener("notice", toNotice);
21303
21323
  addEventListener("resetPwdDirectlySuccess", () => {
@@ -21716,9 +21736,9 @@ const _sfc_main$o = /* @__PURE__ */ defineComponent({
21716
21736
  const layoutConfig2 = useLayoutConfig();
21717
21737
  const { t: t2 } = i18n.global;
21718
21738
  const route = useRoute();
21719
- const MenuItem = defineAsyncComponent(() => import("./MenuItem-B-UAWoEo.js"));
21720
- const ProjectMenuListV2 = defineAsyncComponent(() => import("./ProjectMenuListV2-D9l7n3Gb.js"));
21721
- const ProjectMenuList = defineAsyncComponent(() => import("./ProjectMenuList-Bvu5TTWx.js"));
21739
+ const MenuItem = defineAsyncComponent(() => import("./MenuItem-QiWFY_Zh.js"));
21740
+ const ProjectMenuListV2 = defineAsyncComponent(() => import("./ProjectMenuListV2-BhWUeCZP.js"));
21741
+ const ProjectMenuList = defineAsyncComponent(() => import("./ProjectMenuList-DpHN4VaD.js"));
21722
21742
  const props = __props;
21723
21743
  const useReport2 = inject("useReport");
21724
21744
  const userInfo = inject("userInfo");
@@ -24147,6 +24167,7 @@ async function successResolve(params, API, isRegister = false) {
24147
24167
  }
24148
24168
  saveLastLoginType(loginMethod);
24149
24169
  removeLoginTriggerSourceCookie();
24170
+ await awaitLoginSuccessHook(transformUserInfo);
24150
24171
  if (type === AuthTypeEnum.PHONE_AND_PASSWORD) {
24151
24172
  const { unMount, isMounted } = usePopup();
24152
24173
  if (isMounted()) {
@@ -28256,7 +28277,7 @@ const _SlidCaptchaManager = class _SlidCaptchaManager {
28256
28277
  __publicField(_SlidCaptchaManager, "instance");
28257
28278
  let SlidCaptchaManager = _SlidCaptchaManager;
28258
28279
  const slidCaptchaManager = SlidCaptchaManager.getInstance();
28259
- const SlidCaptcha = defineAsyncComponent(() => import("./index-F3eMI-sw.js"));
28280
+ const SlidCaptcha = defineAsyncComponent(() => import("./index-BGR7KtjO.js"));
28260
28281
  const useSlidCaptcha = () => {
28261
28282
  const { mount, unMount, isMounted } = usePopup("slid-captcha-popup");
28262
28283
  const open = (config2) => {
@@ -28286,7 +28307,7 @@ const useSlidCaptcha = () => {
28286
28307
  close
28287
28308
  };
28288
28309
  };
28289
- const YunpianCaptcha = defineAsyncComponent(() => import("./index-DNfhml9y.js"));
28310
+ const YunpianCaptcha = defineAsyncComponent(() => import("./index-BH8xKrlb.js"));
28290
28311
  const useYunpianCaptcha = () => {
28291
28312
  const { mount, unMount } = usePopup("yunpian-captcha-popup");
28292
28313
  const open = (config2) => {
@@ -31016,6 +31037,7 @@ function useLogin(request, globalStore) {
31016
31037
  }
31017
31038
  } else {
31018
31039
  closeModal();
31040
+ setLoginSuccessHook(loginSuccess ?? null);
31019
31041
  (route == null ? void 0 : route.name) !== "oauth" && mount(LoginModal, {
31020
31042
  route,
31021
31043
  request,
@@ -31033,7 +31055,7 @@ function useLogin(request, globalStore) {
31033
31055
  unMount();
31034
31056
  const { username, email } = conf;
31035
31057
  console.log("conf", conf);
31036
- loginSuccess && loginSuccess(conf);
31058
+ await awaitLoginSuccessHook(conf);
31037
31059
  Message.success(successMsg);
31038
31060
  if (`${username}@gitcode.com` === email) {
31039
31061
  localStorage$2.setItem("validator_email", "invalid");
@@ -31175,7 +31197,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
31175
31197
  login({ ...options || {}, childComponents: { ...slots } }, props.loginSuccess);
31176
31198
  });
31177
31199
  addEventListener("updateUserInfo", (options) => {
31178
- props.loginSuccess(options);
31200
+ if (!hasLoginSuccessHook()) props.loginSuccess(options);
31179
31201
  });
31180
31202
  addEventListener("notice", toNotice);
31181
31203
  window.addEventListener("message", (event) => {