完成启动项目功能、排查一些灵异问题

This commit is contained in:
2026-03-29 00:26:49 +08:00
parent cabb2f65da
commit 6002ac1418
17 changed files with 222 additions and 78 deletions

View File

@@ -6,7 +6,13 @@ import { loadJsonFile } from 'load-json-file'
import { XMLParser } from 'fast-xml-parser' import { XMLParser } from 'fast-xml-parser'
import { VSCodeGlobalStorageJson } from '@my-type/vscode-globalstorage-json' import { VSCodeGlobalStorageJson } from '@my-type/vscode-globalstorage-json'
import { JetBrainsIdeOptionsRecentProjects } from '@my-type/jetbrains-ide-options-recentProjects' import { JetBrainsIdeOptionsRecentProjects } from '@my-type/jetbrains-ide-options-recentProjects'
import { JetBrainsIDEDisplayNameEnum, JetBrainsProductCode, toProductCode } from '@my-type/jetbrains-state-tools' import {
JetBrainsIDEDisplayNameEnum,
JetBrainsProductCode,
toProductCode
} from '@my-type/jetbrains-state-tools'
import { checkIDEsResultDto, IDECode } from '@my-type/settings'
import { spawn } from 'node:child_process'
const xmlParser = new XMLParser({ ignoreAttributes: false }) const xmlParser = new XMLParser({ ignoreAttributes: false })
@@ -24,6 +30,7 @@ const JETBRAINS_IDES_DATA_PATH = path.join(os.homedir(), 'AppData/Roaming/JetBra
* 从 VSCode 的 GlobalStorage 中读取所有打开过的工作区,整理后返回。 * 从 VSCode 的 GlobalStorage 中读取所有打开过的工作区,整理后返回。
*/ */
export async function getVscodeProjects(): Promise<IdeProjectsDto> { export async function getVscodeProjects(): Promise<IdeProjectsDto> {
console.log('查找 VSCode 项目中')
const result: IdeProjectsDto = [] const result: IdeProjectsDto = []
const data: VSCodeGlobalStorageJson = await loadJsonFile(VSCODE_GLOBALSTORAGE_PATH) const data: VSCodeGlobalStorageJson = await loadJsonFile(VSCODE_GLOBALSTORAGE_PATH)
for (const workspace of Object.entries(data.profileAssociations.workspaces)) { for (const workspace of Object.entries(data.profileAssociations.workspaces)) {
@@ -42,6 +49,7 @@ export async function getVscodeProjects(): Promise<IdeProjectsDto> {
} }
export async function getJetBrainsProjects(): Promise<IdeProjectsDto> { export async function getJetBrainsProjects(): Promise<IdeProjectsDto> {
console.log('查找 JetBrains IDEs 项目中')
const result: IdeProjectsDto = [] const result: IdeProjectsDto = []
// 意外的是JetBrains Toolbox 并不会自己保存 JetBrains IDEs 打开过的项目的历史记录,哪怕是在 Toolbox 中打开的。 // 意外的是JetBrains Toolbox 并不会自己保存 JetBrains IDEs 打开过的项目的历史记录,哪怕是在 Toolbox 中打开的。
// 据 AI 总结,工具箱的项目列表系读取已安装的所有 JetBrains IDE 的项目历史,并综合列出的。 // 据 AI 总结,工具箱的项目列表系读取已安装的所有 JetBrains IDE 的项目历史,并综合列出的。
@@ -109,3 +117,41 @@ export async function getProjects(): Promise<IdeProjectsDto> {
const result: IdeProjectsDto = [] const result: IdeProjectsDto = []
return result return result
} }
/**
* 使用指定 IDE 打开指定项目
* @param ide IDE 代码
* @param path 项目路径
*/
export function openProject(ide: IDECode, path: string): boolean {
if (global.installedIDEs === null) return false
// 考虑到安全性问题,这里限制 IDE 代码,只有提供合法的 IDE 代码才能执行命令打开项目。
for (const ideInfo of Object.values(global.installedIDEs as checkIDEsResultDto)) {
if (ideInfo !== null) {
if (ide === ideInfo.code) {
try {
const params: string[] = []
// 如果是使用 VSCode 打开远程项目WSL
if (ide === 'VSC' && path.startsWith('vscode-remote://')) {
// 拼接正确命令
params.push('--folder-uri', path)
}
// TODO 处理更多边界情况
else {
params.push(path)
}
// 避免阻塞当前进程
console.log(`打开项目:尝试执行:${ideInfo.command} ${params.join(' ')}`)
spawn(ideInfo.command, params, { detached: true, stdio: 'ignore', shell: true })
return true
} catch (error) {
console.error(`使用 IDE ${ide} 打开 ${path} 时出现错误。`)
console.error(error)
return false
}
}
}
}
console.log(`打开项目:提供的 IDE 代号不合法:${ide} ${path}`)
return false
}

View File

@@ -2,7 +2,8 @@ import type {
checkIDEResultDto, checkIDEResultDto,
checkIDEsResultDto, checkIDEsResultDto,
checkIDEsVersionDto, checkIDEsVersionDto,
checkIDEVersionDto checkIDEVersionDto,
IDECode
} from '@my-type/settings' } from '@my-type/settings'
import { execSync } from 'node:child_process' import { execSync } from 'node:child_process'
import { BrowserWindow, screen, shell, Tray } from 'electron' import { BrowserWindow, screen, shell, Tray } from 'electron'
@@ -31,11 +32,7 @@ const JETBRAINS_TOOLBOX_STATE_JSON_PATH = path.join(
* @param command IDE 的命令行别名,例如 `code`。 * @param command IDE 的命令行别名,例如 `code`。
* @param code JetBrains IDE的产品代号对于其他 IDE 为空字符串 * @param code JetBrains IDE的产品代号对于其他 IDE 为空字符串
*/ */
function checkIDE( function checkIDE(display: string, command: string, code: IDECode): checkIDEResultDto | null {
display: string,
command: string,
code: JetBrainsProductCode | '' = ''
): checkIDEResultDto | null {
try { try {
const paths = execSync(`where.exe ${command}`).toString().split('\n').slice(0, -1) const paths = execSync(`where.exe ${command}`).toString().split('\n').slice(0, -1)
return { code, display: display, command: command, paths: paths } return { code, display: display, command: command, paths: paths }
@@ -45,7 +42,7 @@ function checkIDE(
} }
/** /**
* 检查 JerBrains IDEs 是否安装可用。 * 检查 JetBrains IDEs 是否安装可用。
*/ */
async function checkJetBrainsIDEs(): Promise<checkIDEsResultDto> { async function checkJetBrainsIDEs(): Promise<checkIDEsResultDto> {
// 构建数据结构的辅助函数 // 构建数据结构的辅助函数
@@ -58,11 +55,11 @@ async function checkJetBrainsIDEs(): Promise<checkIDEsResultDto> {
} }
} }
const result: checkIDEsResultDto = { const result: checkIDEsResultDto = {
pycharm: _('pycharm', 'PY'), PY: _('pycharm', 'PY'),
clion: _('clion', 'CL'), CL: _('clion', 'CL'),
webstorm: _('webstorm', 'WS'), WS: _('webstorm', 'WS'),
phpstorm: _('phpstorm', 'PS'), PS: _('phpstorm', 'PS'),
idea: _('idea', 'IU') IU: _('idea', 'IU')
} }
// 优先从 JBTState.json 查找 // 优先从 JBTState.json 查找
if (settingsManager._settings?.codeLaunchpadIDESearchPolicy.includes('JBTState.json')) { if (settingsManager._settings?.codeLaunchpadIDESearchPolicy.includes('JBTState.json')) {
@@ -115,7 +112,7 @@ export async function getIDEs(): Promise<checkIDEsResultDto> {
export async function checkIDEs(): Promise<checkIDEsResultDto> { export async function checkIDEs(): Promise<checkIDEsResultDto> {
console.log('在系统中查找已安装的 IDE ...') console.log('在系统中查找已安装的 IDE ...')
const vscodeIDEs = { const vscodeIDEs = {
vscode: checkIDE('Visual Studio Code', 'code') VSC: checkIDE('Visual Studio Code', 'code', 'VSC')
} }
global.installedIDEs = { ...vscodeIDEs, ...(await checkJetBrainsIDEs()) } global.installedIDEs = { ...vscodeIDEs, ...(await checkJetBrainsIDEs()) }
return global.installedIDEs return global.installedIDEs
@@ -135,7 +132,7 @@ async function checkVSCodeVersion(): Promise<checkIDEVersionDto> {
console.error('获取 VSCode 版本列表时出现错误。错误提供如下。') console.error('获取 VSCode 版本列表时出现错误。错误提供如下。')
console.error(error) console.error(error)
} }
return { code: '', install, latest, display: 'Visual Studio Code' } return { code: 'VSC', install, latest, display: 'Visual Studio Code' }
} }
/** /**
@@ -152,11 +149,11 @@ export async function checkJetBrainsIDEsVersion(): Promise<checkIDEsVersionDto>
} }
} }
const result: checkIDEsVersionDto = { const result: checkIDEsVersionDto = {
pycharm: _('pycharm', 'PY'), PY: _('pycharm', 'PY'),
clion: _('clion', 'CL'), CL: _('clion', 'CL'),
webstorm: _('webstorm', 'WS'), WS: _('webstorm', 'WS'),
phpstorm: _('phpstorm', 'PS'), PS: _('phpstorm', 'PS'),
idea: _('idea', 'IU') IU: _('idea', 'IU')
} }
// 尝试从 JBTState.json 获取已安装的 JetBrains IDEs 的版本 // 尝试从 JBTState.json 获取已安装的 JetBrains IDEs 的版本
@@ -227,8 +224,8 @@ export async function checkIDEsVersion(): Promise<checkIDEsVersionDto> {
let result: checkIDEsVersionDto = {} let result: checkIDEsVersionDto = {}
for (const ide in await getIDEs()) { for (const ide in await getIDEs()) {
switch (ide) { switch (ide) {
case 'vscode': case 'VSC':
result['vscode'] = await checkVSCodeVersion() result['VSC'] = await checkVSCodeVersion()
break break
} }
} }

View File

@@ -11,7 +11,7 @@ import {
} from './code-launchpad/ide-versions-check' } from './code-launchpad/ide-versions-check'
import { fanToolsIcon } from './resources' import { fanToolsIcon } from './resources'
import path from 'path' import path from 'path'
import { getJetBrainsProjects, getVscodeProjects } from './code-launchpad/ide-projects' import { getJetBrainsProjects, getVscodeProjects, openProject } from './code-launchpad/ide-projects'
let mainWindow: BrowserWindow | null = null let mainWindow: BrowserWindow | null = null
// @ts-ignore 保存引用,禁用报错 // @ts-ignore 保存引用,禁用报错
@@ -131,6 +131,9 @@ app.whenReady().then(async () => {
ipcMain.handle('codeLaunchpad:checkIDEsVersion', checkIDEsVersion) ipcMain.handle('codeLaunchpad:checkIDEsVersion', checkIDEsVersion)
ipcMain.handle('codeLaunchpad:getVSCodeProjects', getVscodeProjects) ipcMain.handle('codeLaunchpad:getVSCodeProjects', getVscodeProjects)
ipcMain.handle('codeLaunchpad:getJetBrainsProjects', getJetBrainsProjects) ipcMain.handle('codeLaunchpad:getJetBrainsProjects', getJetBrainsProjects)
ipcMain.handle('codeLaunchpad:openProject', (_, ide: string, path: string) => {
return openProject(ide, path)
})
await checkIDEs() await checkIDEs()
await checkIDEsVersion() await checkIDEsVersion()

View File

@@ -12,6 +12,7 @@ import PyCharmIcon from '@renderer/assets/PyCharm_icon.svg?component'
import WebStormIcon from '@renderer/assets/WebStorm_icon.svg?component' import WebStormIcon from '@renderer/assets/WebStorm_icon.svg?component'
import { FunctionalComponent } from 'vue' import { FunctionalComponent } from 'vue'
import { IDECode } from '@my-type/settings'
function _( function _(
icon: FunctionalComponent, icon: FunctionalComponent,
@@ -20,11 +21,11 @@ function _(
return { icon, description } return { icon, description }
} }
export const ideIcons = { export const ideIcons: Record<IDECode, { icon: FunctionalComponent; description: string }> = {
vscode: _(VSCodeIcon, '全能的代码编辑器'), VSC: _(VSCodeIcon, '全能的代码编辑器'),
clion: _(CLionIcon, '强大的 C 和 C++ IDE'), CL: _(CLionIcon, '强大的 C 和 C++ IDE'),
idea: _(IDEAIcon, '强大的 Java IDE'), IU: _(IDEAIcon, '强大的 Java IDE'),
phpstorm: _(PhpStormIcon, '强大的 PHP IDE'), PS: _(PhpStormIcon, '强大的 PHP IDE'),
pycharm: _(PyCharmIcon, '强大的 Python IDE'), PY: _(PyCharmIcon, '强大的 Python IDE'),
webstorm: _(WebStormIcon, '强大的 Web IDE') WS: _(WebStormIcon, '强大的 Web IDE')
} }

View File

@@ -18,22 +18,24 @@ export interface settingsDto {
codeLaunchpadIDESearchPolicy: ideSearchPolicy[] codeLaunchpadIDESearchPolicy: ideSearchPolicy[]
} }
export type IDECode = JetBrainsProductCode | 'VSC'
export interface checkIDEResultDto { export interface checkIDEResultDto {
// 仅针对 JetBrains 系列 IDEs 的产品代码,对于其他 IDE 统一为空字符串 // 仅针对 JetBrains 系列 IDEs 的产品代码,对于其他 IDE 统一为空字符串
code: JetBrainsProductCode | '' code: IDECode
display: string display: string
command: string command: string
paths: string[] paths: string[]
} }
export type checkIDEsResultDto = Record<string, checkIDEResultDto | null> export type checkIDEsResultDto = Partial<Record<IDECode, checkIDEResultDto | null>>
export interface checkIDEVersionDto { export interface checkIDEVersionDto {
// 仅针对 JetBrains 系列 IDEs 的产品代码,对于其他 IDE 统一为空字符串 // 仅针对 JetBrains 系列 IDEs 的产品代码,对于其他 IDE 统一为空字符串
code: JetBrainsProductCode | '' code: IDECode
display: string display: string
install: string install: string
latest: string latest: string
} }
export type checkIDEsVersionDto = Record<string, checkIDEVersionDto | null> export type checkIDEsVersionDto = Partial<Record<IDECode, checkIDEVersionDto | null>>

View File

@@ -21,6 +21,7 @@ declare global {
_checkIDEsVersion: () => Promise<checkIDEsVersionDto> _checkIDEsVersion: () => Promise<checkIDEsVersionDto>
_getVSCodeProjects: () => Promise<IdeProjectsDto> _getVSCodeProjects: () => Promise<IdeProjectsDto>
_getJetBrainsProjects: () => Promise<IdeProjectsDto> _getJetBrainsProjects: () => Promise<IdeProjectsDto>
_openProject: (ide: string, path: string) => Promise<boolean>
} }
} }
} }

View File

@@ -17,7 +17,9 @@ const codeLaunchpadApi = {
_getIDEsVersion: () => ipcRenderer.invoke('codeLaunchpad:getIDEsVersion'), _getIDEsVersion: () => ipcRenderer.invoke('codeLaunchpad:getIDEsVersion'),
_checkIDEsVersion: () => ipcRenderer.invoke('codeLaunchpad:checkIDEsVersion'), _checkIDEsVersion: () => ipcRenderer.invoke('codeLaunchpad:checkIDEsVersion'),
_getVSCodeProjects: () => ipcRenderer.invoke('codeLaunchpad:getVSCodeProjects'), _getVSCodeProjects: () => ipcRenderer.invoke('codeLaunchpad:getVSCodeProjects'),
_getJetBrainsProjects: () => ipcRenderer.invoke('codeLaunchpad:getJetBrainsProjects') _getJetBrainsProjects: () => ipcRenderer.invoke('codeLaunchpad:getJetBrainsProjects'),
_openProject: (ide: string, path: string) =>
ipcRenderer.invoke('codeLaunchpad:openProject', ide, path)
} }
// Use `contextBridge` APIs to expose Electron APIs to // Use `contextBridge` APIs to expose Electron APIs to

View File

@@ -22,6 +22,7 @@ declare module 'vue' {
NCard: typeof import('naive-ui')['NCard'] NCard: typeof import('naive-ui')['NCard']
NCode: typeof import('naive-ui')['NCode'] NCode: typeof import('naive-ui')['NCode']
NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDropdown: typeof import('naive-ui')['NDropdown']
NEllipsis: typeof import('naive-ui')['NEllipsis'] NEllipsis: typeof import('naive-ui')['NEllipsis']
NEmpty: typeof import('naive-ui')['NEmpty'] NEmpty: typeof import('naive-ui')['NEmpty']
NFlex: typeof import('naive-ui')['NFlex'] NFlex: typeof import('naive-ui')['NFlex']

View File

@@ -23,19 +23,21 @@ function handleUpdateValue(key: string): void {
</script> </script>
<template> <template>
<div class="codeLaunchpad-container"> <n-message-provider placement="bottom">
<n-menu <div class="codeLaunchpad-container">
v-model:value="activeKey" <n-menu
class="codeLaunchpad-menu" v-model:value="activeKey"
:options="codeLaunchpadMenuOptions" class="codeLaunchpad-menu"
mode="horizontal" :options="codeLaunchpadMenuOptions"
@update:value="handleUpdateValue" mode="horizontal"
/> @update:value="handleUpdateValue"
<div class="scrollarea"> />
<router-view /> <div class="scrollarea">
<router-view />
</div>
<CodeLaunchpadButton />
</div> </div>
<CodeLaunchpadButton /> </n-message-provider>
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { Close as CloseIcon } from '@vicons/ionicons5' import { Close as CloseIcon } from '@vicons/ionicons5'
import { Settings16Filled as SettingsIcon } from '@vicons/fluent'
function close(): void { function close(): void {
window.api._closeCodeLaunchpad() window.api._closeCodeLaunchpad()
} }
function openSettings(): void {
// TODO
}
</script> </script>
<template> <template>
@@ -13,6 +18,11 @@ function close(): void {
<CloseIcon /> <CloseIcon />
</n-icon> </n-icon>
</n-float-button> </n-float-button>
<n-float-button type="default" @click="openSettings">
<n-icon>
<SettingsIcon />
</n-icon>
</n-float-button>
</n-float-button-group> </n-float-button-group>
</template> </template>

View File

@@ -1,12 +1,46 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue'
import { EllipsisHorizontalSharp as EllipsisIcon } from '@vicons/ionicons5'
import type { IdeProjectDto } from '@my-type/ide-projects' import type { IdeProjectDto } from '@my-type/ide-projects'
import { computed } from 'vue'
import { toProductDisplayName } from '@my-type/jetbrains-state-tools' import { toProductDisplayName } from '@my-type/jetbrains-state-tools'
import { useMessage } from 'naive-ui'
const message = useMessage()
// 用指定 IDE 打开的 Dropdown
const options = [
{
label: 'VS Code',
key: 'VSC'
},
{
label: 'PyCharm',
key: 'PY'
},
{
label: 'IntelliJ IDEA',
key: 'IU'
},
{
label: 'CLion',
key: 'CL'
},
{
label: 'WebStorm',
key: 'WS'
},
{
label: 'PhpStorm',
key: 'PS'
}
]
const props = defineProps<{ const props = defineProps<{
project: IdeProjectDto project: IdeProjectDto
}>() }>()
const showDetail = ref(false)
// 计算属性,返回一个将显示在该卡片上的项目标签列表 // 计算属性,返回一个将显示在该卡片上的项目标签列表
const ideTags = computed(() => { const ideTags = computed(() => {
const tags: string[] = [] const tags: string[] = []
@@ -22,17 +56,52 @@ const ideTags = computed(() => {
if (props.project.path.includes('wsl+') || props.project.path.includes('wsl.')) tags.push('WSL') if (props.project.path.includes('wsl+') || props.project.path.includes('wsl.')) tags.push('WSL')
return tags return tags
}) })
async function openWithIDE(ide: string): Promise<void> {
if ((await window.codeLaunchpad._openProject(ide, props.project.path)) === true) {
message.success('项目已打开。')
} else {
message.error('项目打开失败?')
}
}
</script> </script>
<template> <template>
<n-card> <n-card>
<n-flex justify="left"> <template #default>
<n-h4>{{ project.name }}</n-h4> <div @click="() => (showDetail = true)">
<n-tag v-for="tag in ideTags" :key="tag" round :type="tag === 'WSL' ? 'primary' : 'info'"> <n-flex justify="left">
{{ tag }} <n-h4>{{ project.name }}</n-h4>
</n-tag> <n-tag v-for="tag in ideTags" :key="tag" round :type="tag === 'WSL' ? 'primary' : 'info'">
</n-flex> {{ tag }}
<n-ellipsis>{{ project.path }}</n-ellipsis> </n-tag>
</n-flex>
<n-ellipsis>{{ project.path }}</n-ellipsis>
</div>
</template>
<template v-if="showDetail" #footer>
<n-flex>
<n-button-group>
<n-button
v-for="ide in project.ide"
:key="ide"
round
type="info"
@click="() => openWithIDE(ide)"
>
{{ ide === 'VSC' ? 'VS Code' : toProductDisplayName(ide) }} 打开
</n-button>
<n-dropdown trigger="click" :options @select="(key) => openWithIDE(key as string)">
<n-button type="info" circle>
<n-icon>
<EllipsisIcon />
</n-icon>
</n-button>
</n-dropdown>
</n-button-group>
<n-button round secondary type="primary" @click="() => (showDetail = false)">收起</n-button>
</n-flex>
</template>
</n-card> </n-card>
</template> </template>

View File

@@ -3,14 +3,14 @@ import { checkIDEResultDto, checkIDEVersionDto } from '@my-type/settings'
import { ideIcons } from '@my-type/ide-icons' import { ideIcons } from '@my-type/ide-icons'
defineProps<{ defineProps<{
info: checkIDEResultDto | null info: checkIDEResultDto | null | undefined
version: checkIDEVersionDto | null version: checkIDEVersionDto | null | undefined
name: string name: string
}>() }>()
</script> </script>
<template> <template>
<n-card v-if="info !== null"> <n-card v-if="info !== null && info !== undefined">
<template #header> <template #header>
<n-flex justify="left"> <n-flex justify="left">
<n-icon :component="ideIcons[name]['icon']" size="28"></n-icon> <n-icon :component="ideIcons[name]['icon']" size="28"></n-icon>

View File

@@ -2,7 +2,7 @@
import { checkIDEsResultDto, checkIDEsVersionDto } from '@my-type/settings' import { checkIDEsResultDto, checkIDEsVersionDto } from '@my-type/settings'
import DetectedIDECard from '@renderer/components/DetectedIDECard.vue' import DetectedIDECard from '@renderer/components/DetectedIDECard.vue'
const props = defineProps<{ defineProps<{
ides: checkIDEsResultDto | null ides: checkIDEsResultDto | null
versions: checkIDEsVersionDto versions: checkIDEsVersionDto
}>() }>()
@@ -12,7 +12,7 @@ const props = defineProps<{
<div class="scrollarea detected-ide-card-list"> <div class="scrollarea detected-ide-card-list">
<n-flex v-if="ides !== null" vertical> <n-flex v-if="ides !== null" vertical>
<DetectedIDECard <DetectedIDECard
v-for="(info, name) in props.ides" v-for="(info, name) in ides"
:key="name" :key="name"
:info :info
:name :name

View File

@@ -2,6 +2,7 @@
import ProjectCard from '@renderer/components-code-launchpad/ProjectCard.vue' import ProjectCard from '@renderer/components-code-launchpad/ProjectCard.vue'
import { useProjects } from '@renderer/stores' import { useProjects } from '@renderer/stores'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import { RefreshOutline as RefreshIcon } from '@vicons/ionicons5'
const projects = useProjects() const projects = useProjects()
@@ -29,10 +30,29 @@ onMounted(() => {
</script> </script>
<template> <template>
<n-button-group class="ide-button-group"> <n-flex>
<n-button type="primary" secondary round @click="() => (ide = 'VSCode')">VS Code</n-button> <n-button-group class="ide-button-group">
<n-button type="primary" secondary round @click="() => (ide = 'JetBrains')">JetBrains</n-button> <n-button type="primary" secondary round @click="() => (ide = 'VSCode')">VS Code</n-button>
</n-button-group> <n-button type="primary" secondary round @click="() => (ide = 'JetBrains')"
>JetBrains</n-button
>
</n-button-group>
<n-button
type="primary"
secondary
circle
@click="
() => {
projects.getVSCodeProjects()
projects.getJetBrainsProjects()
}
"
>
<n-icon>
<RefreshIcon />
</n-icon>
</n-button>
</n-flex>
<n-flex size="small" vertical> <n-flex size="small" vertical>
<div v-for="project of reverseProjects" :key="project.path" class="project-card"> <div v-for="project of reverseProjects" :key="project.path" class="project-card">
<ProjectCard :project /> <ProjectCard :project />
@@ -44,7 +64,6 @@ onMounted(() => {
.ide-button-group { .ide-button-group {
margin-bottom: 8px; margin-bottom: 8px;
margin-left: 10px; margin-left: 10px;
margin-right: 10px;
} }
.project-card { .project-card {

View File

@@ -7,9 +7,9 @@ import CodeLaunchpadPageDisplay from '@renderer/pages/CodeLaunchpadPageDisplay.v
const IDEs = useIDEs() const IDEs = useIDEs()
onMounted(() => { onMounted(async () => {
IDEs.getIDEs() await IDEs.getIDEs()
IDEs.getVersions() await IDEs.getVersions()
}) })
</script> </script>

View File

@@ -39,7 +39,7 @@ const IDESearchMethodOptions = [
> >
</template> </template>
<template #default> <template #default>
<DetectedIDECardList :ides="ides" :versions /> <DetectedIDECardList :ides :versions />
</template> </template>
<template #action> <template #action>
<n-p <n-p

View File

@@ -31,14 +31,6 @@ async function openCodeLaunchpad(): Promise<void> {
message.error('啊哦?出问题了,请检查。') message.error('啊哦?出问题了,请检查。')
} }
} }
async function closeCodeLaunchpad(): Promise<void> {
if (await window.api._closeCodeLaunchpad()) {
message.success('如你所愿,代码启动台已关闭。')
} else {
message.error('代码启动台真的打开了吗?')
}
}
</script> </script>
<template> <template>
@@ -51,7 +43,6 @@ async function closeCodeLaunchpad(): Promise<void> {
> >
<n-space> <n-space>
<n-button @click="openCodeLaunchpad">我现在就要打开代码启动台</n-button> <n-button @click="openCodeLaunchpad">我现在就要打开代码启动台</n-button>
<n-button @click="closeCodeLaunchpad">关闭已打开的代码启动台</n-button>
</n-space> </n-space>
</setting-card> </setting-card>
<n-p>使用上面的按钮打开的代码启动台只能通过上面的按钮再将其关闭方便你测试效果</n-p> <n-p>使用上面的按钮打开的代码启动台只能通过上面的按钮再将其关闭方便你测试效果</n-p>