update
This commit is contained in:
@@ -4,8 +4,15 @@ import { useI18n } from 'vue-i18n';
|
||||
import { useSessionStore } from './session.store'; // 导入会话 Store
|
||||
import type { EditorFileContent, SaveStatus } from '../types/sftp.types'; // 保持导入 SaveStatus
|
||||
|
||||
// --- 新类型定义 ---
|
||||
export interface EditorTab {
|
||||
// --- 类型定义 ---
|
||||
// 文件信息,用于打开文件操作
|
||||
export interface FileInfo {
|
||||
name: string;
|
||||
fullPath: string;
|
||||
}
|
||||
|
||||
// 编辑器标签页状态
|
||||
export interface FileTab {
|
||||
id: string; // 唯一标识符,例如 `${sessionId}:${filePath}`
|
||||
sessionId: string;
|
||||
filePath: string;
|
||||
@@ -20,8 +27,12 @@ export interface EditorTab {
|
||||
saveStatus: SaveStatus;
|
||||
saveError: string | null;
|
||||
isModified: boolean; // 内容是否已修改
|
||||
// 添加 sessionId 以便在共享模式下区分来源 (虽然此 store 主要用于共享模式)
|
||||
// 或者在独立模式下,此 store 可能不被使用或以不同方式使用
|
||||
// sessionId: string; // 暂时不加,因为 session.store 已处理独立模式
|
||||
}
|
||||
|
||||
|
||||
// 辅助函数:根据文件名获取语言 (保持不变)
|
||||
const getLanguageFromFilename = (filename: string): string => {
|
||||
const extension = filename.split('.').pop()?.toLowerCase();
|
||||
@@ -65,7 +76,7 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
const sessionStore = useSessionStore();
|
||||
|
||||
// --- 多标签状态 ---
|
||||
const tabs = ref(new Map<string, EditorTab>()); // 存储所有打开的标签页
|
||||
const tabs = ref(new Map<string, FileTab>()); // 存储所有打开的标签页 (使用 FileTab)
|
||||
const activeTabId = ref<string | null>(null); // 当前激活的标签页 ID
|
||||
// const editorVisibleState = ref<'visible' | 'minimized' | 'closed'>('closed'); // 移除,面板可见性由布局控制
|
||||
const popupTrigger = ref(0); // 新增:用于触发弹窗显示的信号
|
||||
@@ -81,7 +92,8 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
get: () => activeTab.value?.content ?? '',
|
||||
set: (value) => {
|
||||
if (activeTab.value) {
|
||||
updateContent(value); // 调用 action 更新内容和修改状态
|
||||
// 调用新的 updateFileContent action,并传递 tabId
|
||||
updateFileContent(activeTab.value.id, value);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -100,8 +112,10 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
|
||||
// 打开或切换到文件标签页
|
||||
const openFile = async (targetFilePath: string, sessionId: string) => {
|
||||
// 在共享模式下,我们仍然需要 sessionId 来构建唯一的 tabId
|
||||
// 并与 SFTP 管理器关联
|
||||
const tabId = `${sessionId}:${targetFilePath}`;
|
||||
console.log(`[文件编辑器 Store] 尝试打开文件: ${targetFilePath} (会话: ${sessionId}, Tab ID: ${tabId})`);
|
||||
console.log(`[文件编辑器 Store - 共享模式] 尝试打开文件: ${targetFilePath} (会话: ${sessionId}, Tab ID: ${tabId})`);
|
||||
|
||||
// 移除确保编辑器可见的逻辑
|
||||
// if (editorVisibleState.value === 'closed') {
|
||||
@@ -118,7 +132,7 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
}
|
||||
|
||||
// 创建新标签页
|
||||
const newTab: EditorTab = {
|
||||
const newTab: FileTab = {
|
||||
id: tabId,
|
||||
sessionId: sessionId,
|
||||
filePath: targetFilePath,
|
||||
@@ -133,6 +147,7 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
saveStatus: 'idle',
|
||||
saveError: null,
|
||||
isModified: false,
|
||||
// sessionId: sessionId, // 记录来源会话
|
||||
};
|
||||
tabs.value.set(tabId, newTab);
|
||||
setActiveTab(tabId); // 激活新标签页
|
||||
@@ -343,20 +358,24 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 更新当前激活标签页的内容 (由 v-model 调用)
|
||||
const updateContent = (newContent: string) => {
|
||||
if (activeTab.value && !activeTab.value.isLoading) {
|
||||
activeTab.value.content = newContent;
|
||||
// 更新指定标签页的内容 (由 FileEditorContainer 的 v-model 触发)
|
||||
const updateFileContent = (tabId: string, newContent: string) => {
|
||||
const tab = tabs.value.get(tabId);
|
||||
if (tab && !tab.isLoading) {
|
||||
tab.content = newContent;
|
||||
// 检查是否修改
|
||||
activeTab.value.isModified = activeTab.value.content !== activeTab.value.originalContent;
|
||||
tab.isModified = tab.content !== tab.originalContent;
|
||||
// 当用户编辑时,重置保存状态
|
||||
if (activeTab.value.saveStatus === 'success' || activeTab.value.saveStatus === 'error') {
|
||||
activeTab.value.saveStatus = 'idle';
|
||||
activeTab.value.saveError = null;
|
||||
if (tab.saveStatus === 'success' || tab.saveStatus === 'error') {
|
||||
tab.saveStatus = 'idle';
|
||||
tab.saveError = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 移除旧的 updateContent,因为它只更新活动标签页
|
||||
// const updateContent = (newContent: string) => { ... };
|
||||
|
||||
// 监听会话关闭事件,移除相关标签页
|
||||
watch(() => sessionStore.sessions, (newSessions, oldSessions) => {
|
||||
const closedSessionIds = new Set<string>();
|
||||
@@ -412,7 +431,7 @@ export const useFileEditorStore = defineStore('fileEditor', () => {
|
||||
closeTab,
|
||||
closeAllTabs,
|
||||
setActiveTab,
|
||||
updateContent, // 暴露给 v-model 使用
|
||||
updateFileContent, // 暴露新的更新方法
|
||||
// setEditorVisibility, // 移除
|
||||
};
|
||||
});
|
||||
|
||||
@@ -2,6 +2,8 @@ import { ref, computed, shallowRef, type Ref } from 'vue'; // 导入 shallowRef
|
||||
import { defineStore } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useConnectionsStore, type ConnectionInfo } from './connections.store';
|
||||
// 导入文件编辑器相关的类型
|
||||
import type { FileTab, FileInfo } from './fileEditor.store'; // 导入 FileTab 和 FileInfo
|
||||
|
||||
// 导入管理器工厂函数 (用于创建实例)
|
||||
// 导入 WsConnectionStatus 类型
|
||||
@@ -15,6 +17,39 @@ function generateSessionId(): string {
|
||||
return Date.now().toString(36) + Math.random().toString(36).substring(2);
|
||||
}
|
||||
|
||||
// 辅助函数:根据文件名获取语言 (从 fileEditor.store 迁移过来)
|
||||
const getLanguageFromFilename = (filename: string): string => {
|
||||
const extension = filename.split('.').pop()?.toLowerCase();
|
||||
switch (extension) {
|
||||
case 'js': return 'javascript';
|
||||
case 'ts': return 'typescript';
|
||||
case 'json': return 'json';
|
||||
case 'html': return 'html';
|
||||
case 'css': return 'css';
|
||||
case 'scss': return 'scss';
|
||||
case 'less': return 'less';
|
||||
case 'py': return 'python';
|
||||
case 'java': return 'java';
|
||||
case 'c': return 'c';
|
||||
case 'cpp': return 'cpp';
|
||||
case 'cs': return 'csharp';
|
||||
case 'go': return 'go';
|
||||
case 'php': return 'php';
|
||||
case 'rb': return 'ruby';
|
||||
case 'rs': return 'rust';
|
||||
case 'sql': return 'sql';
|
||||
case 'sh': return 'shell';
|
||||
case 'yaml': case 'yml': return 'yaml';
|
||||
case 'md': return 'markdown';
|
||||
case 'xml': return 'xml';
|
||||
case 'ini': return 'ini';
|
||||
case 'bat': return 'bat';
|
||||
case 'dockerfile': return 'dockerfile';
|
||||
default: return 'plaintext';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --- 类型定义 (导出以便其他模块使用) ---
|
||||
export type WsManagerInstance = ReturnType<typeof createWebSocketConnectionManager>;
|
||||
export type SftpManagerInstance = ReturnType<typeof createSftpActionsManager>;
|
||||
@@ -29,7 +64,10 @@ export interface SessionState {
|
||||
sftpManager: SftpManagerInstance;
|
||||
terminalManager: SshTerminalInstance;
|
||||
statusMonitorManager: StatusMonitorInstance;
|
||||
currentSftpPath: Ref<string>; // SFTP 当前路径 (可能需要保留在此处或移至 SftpManager 内部)
|
||||
currentSftpPath: Ref<string>; // SFTP 当前路径
|
||||
// --- 新增:独立编辑器状态 ---
|
||||
editorTabs: Ref<FileTab[]>; // 编辑器标签页列表
|
||||
activeEditorTabId: Ref<string | null>; // 当前活动的编辑器标签页 ID
|
||||
}
|
||||
|
||||
// 为标签栏定义包含状态的类型
|
||||
@@ -129,6 +167,9 @@ export const useSessionStore = defineStore('session', () => {
|
||||
terminalManager: terminalManager,
|
||||
statusMonitorManager: statusMonitorManager,
|
||||
currentSftpPath: currentSftpPath,
|
||||
// --- 初始化编辑器状态 ---
|
||||
editorTabs: ref([]), // 初始化为空数组
|
||||
activeEditorTabId: ref(null), // 初始化为 null
|
||||
};
|
||||
|
||||
// 3. 添加到 Map 并激活 (需要创建 Map 的新实例以触发 shallowRef 更新)
|
||||
@@ -161,6 +202,88 @@ export const useSessionStore = defineStore('session', () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新指定会话中编辑器标签页的内容
|
||||
*/
|
||||
const updateFileContentInSession = (sessionId: string, tabId: string, newContent: string) => {
|
||||
const session = sessions.value.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[SessionStore] 尝试在不存在的会话 ${sessionId} 中更新标签页 ${tabId} 内容`);
|
||||
return;
|
||||
}
|
||||
const tab = session.editorTabs.value.find(t => t.id === tabId);
|
||||
if (tab && !tab.isLoading) {
|
||||
tab.content = newContent;
|
||||
// 检查是否修改
|
||||
tab.isModified = tab.content !== tab.originalContent;
|
||||
// 当用户编辑时,重置保存状态
|
||||
if (tab.saveStatus === 'success' || tab.saveStatus === 'error') {
|
||||
tab.saveStatus = 'idle';
|
||||
tab.saveError = null;
|
||||
}
|
||||
} else if (tab) {
|
||||
console.warn(`[SessionStore] 尝试更新正在加载的标签页 ${tabId} 的内容`);
|
||||
} else {
|
||||
console.warn(`[SessionStore] 尝试更新会话 ${sessionId} 中不存在的标签页 ${tabId} 的内容`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存指定会话中的编辑器标签页
|
||||
*/
|
||||
const saveFileInSession = async (sessionId: string, tabId: string) => {
|
||||
const session = sessions.value.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[SessionStore] 尝试在不存在的会话 ${sessionId} 中保存标签页 ${tabId}`);
|
||||
return;
|
||||
}
|
||||
const tab = session.editorTabs.value.find(t => t.id === tabId);
|
||||
if (!tab) {
|
||||
console.warn(`[SessionStore] 尝试保存在会话 ${sessionId} 中不存在的标签页 ${tabId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tab.isSaving || tab.isLoading || tab.loadingError || !tab.isModified) {
|
||||
console.warn(`[SessionStore] 保存条件不满足 for ${tab.filePath} (会话 ${sessionId}),无法保存。`, { tab });
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查会话连接状态
|
||||
if (!session.wsManager.isConnected.value || !session.wsManager.isSftpReady.value) {
|
||||
console.error(`[SessionStore] 保存失败:会话 ${sessionId} 无效或未连接/SFTP 未就绪。`);
|
||||
tab.saveStatus = 'error';
|
||||
tab.saveError = t('fileManager.errors.sessionInvalidOrNotReady');
|
||||
setTimeout(() => { if (tab.saveStatus === 'error') { tab.saveStatus = 'idle'; tab.saveError = null; } }, 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
const sftpManager = session.sftpManager;
|
||||
console.log(`[SessionStore] 开始保存文件: ${tab.filePath} (会话 ${sessionId}, Tab ID: ${tab.id})`);
|
||||
tab.isSaving = true;
|
||||
tab.saveStatus = 'saving';
|
||||
tab.saveError = null;
|
||||
|
||||
const contentToSave = tab.content;
|
||||
|
||||
try {
|
||||
await sftpManager.writeFile(tab.filePath, contentToSave);
|
||||
console.log(`[SessionStore] 文件 ${tab.filePath} (会话 ${sessionId}) 保存成功。`);
|
||||
tab.isSaving = false;
|
||||
tab.saveStatus = 'success';
|
||||
tab.saveError = null;
|
||||
tab.originalContent = contentToSave; // 更新原始内容
|
||||
tab.isModified = false; // 重置修改状态
|
||||
setTimeout(() => { if (tab.saveStatus === 'success') { tab.saveStatus = 'idle'; } }, 2000);
|
||||
} catch (err: any) {
|
||||
console.error(`[SessionStore] 保存文件 ${tab.filePath} (会话 ${sessionId}) 失败:`, err);
|
||||
tab.isSaving = false;
|
||||
tab.saveStatus = 'error';
|
||||
tab.saveError = `${t('fileManager.errors.saveFailed')}: ${err.message || err}`;
|
||||
setTimeout(() => { if (tab.saveStatus === 'error') { tab.saveStatus = 'idle'; tab.saveError = null; } }, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 关闭指定 ID 的会话标签页
|
||||
*/
|
||||
@@ -181,6 +304,7 @@ export const useSessionStore = defineStore('session', () => {
|
||||
console.log(`[SessionStore] 已为会话 ${sessionId} 调用 terminalManager.cleanup()`);
|
||||
sessionToClose.statusMonitorManager.cleanup();
|
||||
console.log(`[SessionStore] 已为会话 ${sessionId} 调用 statusMonitorManager.cleanup()`);
|
||||
// TODO: 清理编辑器相关资源?例如提示保存未保存的文件
|
||||
|
||||
// 2. 从 Map 中移除会话 (需要创建 Map 的新实例以触发 shallowRef 更新)
|
||||
const newSessionsMap = new Map(sessions.value);
|
||||
@@ -261,6 +385,162 @@ export const useSessionStore = defineStore('session', () => {
|
||||
activeSessionId.value = null;
|
||||
};
|
||||
|
||||
// --- 新增:编辑器相关 Actions ---
|
||||
|
||||
/**
|
||||
* 在指定会话中打开文件
|
||||
*/
|
||||
const openFileInSession = (sessionId: string, fileInfo: FileInfo) => {
|
||||
const session = sessions.value.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[SessionStore] 尝试在不存在的会话 ${sessionId} 中打开文件`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查标签页是否已存在 (使用 filePath)
|
||||
const existingTab = session.editorTabs.value.find(tab => tab.filePath === fileInfo.fullPath);
|
||||
if (existingTab) {
|
||||
// 如果标签页已存在,则激活它
|
||||
session.activeEditorTabId.value = existingTab.id;
|
||||
console.log(`[SessionStore] 会话 ${sessionId} 中已存在文件 ${fileInfo.fullPath} 的标签页,已激活: ${existingTab.id}`);
|
||||
} else {
|
||||
// 创建新标签页
|
||||
const newTab: FileTab = {
|
||||
id: generateSessionId(), // 复用会话 ID 生成逻辑创建唯一标签页 ID
|
||||
filename: fileInfo.name, // 使用 filename 匹配 FileTab 接口
|
||||
filePath: fileInfo.fullPath, // 使用 filePath 匹配 FileTab 接口
|
||||
// content, originalContent, language, encoding 将在 FileEditorContainer 或 fileEditor.store 中处理
|
||||
content: '', // 初始内容为空
|
||||
originalContent: '', // 初始原始内容为空
|
||||
language: 'plaintext', // 初始语言,稍后会根据文件名更新
|
||||
encoding: 'utf8', // 默认编码
|
||||
isModified: false, // 使用 isModified 匹配 FileTab 接口
|
||||
isLoading: false, // 初始化为 boolean
|
||||
loadingError: null, // 使用 loadingError 匹配 FileTab 接口
|
||||
// --- 编辑器状态相关 ---
|
||||
isSaving: false,
|
||||
saveStatus: 'idle',
|
||||
saveError: null,
|
||||
// --- 关联会话 ID ---
|
||||
sessionId: sessionId, // 记录此标签页属于哪个会话
|
||||
};
|
||||
// session.editorTabs.value.push(newTab); // 移除重复的 push
|
||||
session.editorTabs.value.push(newTab);
|
||||
session.activeEditorTabId.value = newTab.id;
|
||||
console.log(`[SessionStore] 已在会话 ${sessionId} 中为文件 ${fileInfo.fullPath} 创建新标签页: ${newTab.id}`);
|
||||
|
||||
// --- 新增:异步加载文件内容 ---
|
||||
const loadContent = async () => {
|
||||
const tabToLoad = session.editorTabs.value.find(t => t.id === newTab.id);
|
||||
if (!tabToLoad) return; // Tab might have been closed quickly
|
||||
|
||||
tabToLoad.isLoading = true;
|
||||
tabToLoad.loadingError = null;
|
||||
|
||||
try {
|
||||
const sftpManager = session.sftpManager; // 获取当前会话的 sftpManager
|
||||
const fileData = await sftpManager.readFile(fileInfo.fullPath);
|
||||
console.log(`[SessionStore ${sessionId}] 文件 ${fileInfo.fullPath} 读取成功。编码: ${fileData.encoding}`);
|
||||
|
||||
let decodedContent = '';
|
||||
let finalEncoding: 'utf8' | 'base64' = 'utf8';
|
||||
|
||||
if (fileData.encoding === 'base64') {
|
||||
finalEncoding = 'base64';
|
||||
try {
|
||||
const binaryString = atob(fileData.content);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
decodedContent = decoder.decode(bytes);
|
||||
} catch (decodeError) {
|
||||
console.error(`[SessionStore ${sessionId}] Base64 解码错误 for ${fileInfo.fullPath}:`, decodeError);
|
||||
tabToLoad.loadingError = t('fileManager.errors.fileDecodeError');
|
||||
decodedContent = `// ${tabToLoad.loadingError}\n// Original Base64 content:\n${fileData.content}`;
|
||||
}
|
||||
} else {
|
||||
finalEncoding = 'utf8';
|
||||
decodedContent = fileData.content;
|
||||
if (decodedContent.includes('\uFFFD')) {
|
||||
console.warn(`[SessionStore ${sessionId}] 文件 ${fileInfo.fullPath} 内容可能包含无效字符。`);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新标签页状态
|
||||
tabToLoad.content = decodedContent;
|
||||
tabToLoad.originalContent = decodedContent;
|
||||
tabToLoad.encoding = finalEncoding;
|
||||
tabToLoad.language = getLanguageFromFilename(fileInfo.name); // 根据文件名设置语言
|
||||
tabToLoad.isModified = false;
|
||||
|
||||
} catch (err: any) {
|
||||
console.error(`[SessionStore ${sessionId}] 读取文件 ${fileInfo.fullPath} 失败:`, err);
|
||||
tabToLoad.loadingError = `${t('fileManager.errors.readFileFailed')}: ${err.message || err}`;
|
||||
tabToLoad.content = `// ${tabToLoad.loadingError}`;
|
||||
} finally {
|
||||
tabToLoad.isLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
loadContent(); // 启动内容加载
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭指定会话中的编辑器标签页
|
||||
*/
|
||||
const closeEditorTabInSession = (sessionId: string, tabId: string) => {
|
||||
const session = sessions.value.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[SessionStore] 尝试在不存在的会话 ${sessionId} 中关闭标签页 ${tabId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const tabIndex = session.editorTabs.value.findIndex(tab => tab.id === tabId);
|
||||
if (tabIndex === -1) {
|
||||
console.warn(`[SessionStore] 尝试关闭会话 ${sessionId} 中不存在的标签页 ID: ${tabId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 检查 isDirty 状态,提示保存?
|
||||
|
||||
session.editorTabs.value.splice(tabIndex, 1);
|
||||
console.log(`[SessionStore] 已从会话 ${sessionId} 中移除标签页: ${tabId}`);
|
||||
|
||||
// 如果关闭的是当前活动标签页,则切换到前一个或 null
|
||||
if (session.activeEditorTabId.value === tabId) {
|
||||
const remainingTabs = session.editorTabs.value;
|
||||
const nextActiveTabId = remainingTabs.length > 0
|
||||
? remainingTabs[Math.max(0, tabIndex - 1)].id // 尝试激活前一个,或第一个
|
||||
: null;
|
||||
session.activeEditorTabId.value = nextActiveTabId;
|
||||
console.log(`[SessionStore] 会话 ${sessionId} 关闭活动标签页后,切换到: ${nextActiveTabId}`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 激活指定会话中的编辑器标签页
|
||||
*/
|
||||
const setActiveEditorTabInSession = (sessionId: string, tabId: string) => {
|
||||
const session = sessions.value.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[SessionStore] 尝试在不存在的会话 ${sessionId} 中激活标签页 ${tabId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (session.editorTabs.value.some(tab => tab.id === tabId)) {
|
||||
if (session.activeEditorTabId.value !== tabId) {
|
||||
session.activeEditorTabId.value = tabId;
|
||||
console.log(`[SessionStore] 已在会话 ${sessionId} 中激活标签页: ${tabId}`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[SessionStore] 尝试激活会话 ${sessionId} 中不存在的标签页 ID: ${tabId}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
// State
|
||||
sessions,
|
||||
@@ -276,5 +556,11 @@ export const useSessionStore = defineStore('session', () => {
|
||||
handleConnectRequest,
|
||||
handleOpenNewSession,
|
||||
cleanupAllSessions,
|
||||
// --- 新增:导出编辑器相关 Actions ---
|
||||
openFileInSession,
|
||||
closeEditorTabInSession,
|
||||
setActiveEditorTabInSession,
|
||||
updateFileContentInSession, // 导出更新内容 Action
|
||||
saveFileInSession, // 导出保存文件 Action
|
||||
};
|
||||
});
|
||||
|
||||
@@ -9,9 +9,10 @@ interface SettingsState {
|
||||
ipWhitelist: string;
|
||||
maxLoginAttempts: string;
|
||||
loginBanDuration: string;
|
||||
showPopupFileEditor: string; // 新增设置项,存储为 'true' 或 'false'
|
||||
showPopupFileEditor: string; // 弹窗编辑器设置
|
||||
shareFileEditorTabs?: string; // 新增:共享编辑器标签页设置 ('true'/'false')
|
||||
// Add other settings keys here as needed
|
||||
[key: string]: string; // Allow other string settings
|
||||
[key: string]: string | undefined; // Allow other string settings, make value optional
|
||||
}
|
||||
|
||||
export const useSettingsStore = defineStore('settings', () => {
|
||||
@@ -44,6 +45,11 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
console.log('[SettingsStore] Setting default for showPopupFileEditor: true');
|
||||
settings.value.showPopupFileEditor = 'true'; // 默认为 true
|
||||
}
|
||||
// 共享编辑器标签页设置
|
||||
if (settings.value.shareFileEditorTabs === undefined) {
|
||||
console.log('[SettingsStore] Setting default for shareFileEditorTabs: true');
|
||||
settings.value.shareFileEditorTabs = 'true'; // 默认为 true (共享)
|
||||
}
|
||||
|
||||
// --- 语言设置 ---
|
||||
// Determine and apply language
|
||||
@@ -131,15 +137,25 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
// Getter for the popup editor setting, returning boolean
|
||||
const showPopupFileEditorBoolean = computed(() => {
|
||||
// 默认为 true,除非明确设置为 'false'
|
||||
return settings.value.showPopupFileEditor !== 'false';
|
||||
// 默认为 true (共享),除非明确设置为 'false'
|
||||
// 默认为 true (共享),除非明确设置为 'false'
|
||||
return settings.value.shareFileEditorTabs !== 'false';
|
||||
});
|
||||
|
||||
// Getter for sharing setting, returning boolean
|
||||
const shareFileEditorTabsBoolean = computed(() => {
|
||||
// 默认为 true (共享),除非明确设置为 'false'
|
||||
return settings.value.shareFileEditorTabs !== 'false';
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
settings,
|
||||
isLoading,
|
||||
error,
|
||||
language, // Expose language getter
|
||||
showPopupFileEditorBoolean, // Expose boolean getter for popup editor setting
|
||||
shareFileEditorTabsBoolean: shareFileEditorTabsBoolean, // Expose boolean getter for sharing setting
|
||||
loadInitialSettings,
|
||||
updateSetting,
|
||||
updateMultipleSettings,
|
||||
|
||||
Reference in New Issue
Block a user