Compare commits
2 Commits
4a87702694
...
6002ac1418
| Author | SHA1 | Date | |
|---|---|---|---|
| 6002ac1418 | |||
| cabb2f65da |
@@ -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 的项目历史,并综合列出的。
|
||||||
@@ -58,7 +66,7 @@ export async function getJetBrainsProjects(): Promise<IdeProjectsDto> {
|
|||||||
// 创建工具函数
|
// 创建工具函数
|
||||||
const _ = (subDir: string): JetBrainsProductCode | null => {
|
const _ = (subDir: string): JetBrainsProductCode | null => {
|
||||||
// 获取枚举成员的变量名称
|
// 获取枚举成员的变量名称
|
||||||
for (const ide in Object.keys(JetBrainsIDEDisplayNameEnum)) {
|
for (const ide in JetBrainsIDEDisplayNameEnum) {
|
||||||
if (subDir.toLowerCase().includes(ide)) {
|
if (subDir.toLowerCase().includes(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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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')
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/my-type/settings.d.ts
vendored
10
src/my-type/settings.d.ts
vendored
@@ -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>>
|
||||||
|
|||||||
1
src/preload/index.d.ts
vendored
1
src/preload/index.d.ts
vendored
@@ -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>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
1
src/renderer/components.d.ts
vendored
1
src/renderer/components.d.ts
vendored
@@ -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']
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user