当前位置: 首页 > news >正文

【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)

源代码仓库:
Github仓库【electron_git】

Commit :
bb40040

Github Desktop 页面分析

本节目标:
1、实现类似Github Desktop的「空仓库」提示页
2、添加本地仓库逻辑编写

在这里插入图片描述

从 Github Desktop 我们看到 他的 主要页面分为三个区域

  • Head头部区域 (操作分支)
  • Side侧边栏区域 (查看更新的文件)
  • Main主区域 (查看 文件 Diff内容)

在这里插入图片描述

Tip:其实初始化的时候只有一个类似main的界面,这里因为我已经添加过store了,所以有head和side部分。

一、目录搭建及依赖安装

  • Ant Design 官网
  • Redux 官网
  • react-router 官网
  • localforage官网
# 安装依赖
pnpm install antd --save
pnpm install @reduxjs/toolkit react-redux
pnpm add -D sass-embedded
pnpm install react-router-dom

# 简化持久化存储 根据 IndexedDB 和 WebSQL 支持进行降级策略
pnpm install localforage

主要文件

在这里插入图片描述

二、IPC 通信模块设计与实现

渲染进程 预处理脚本 主进程 操作系统 调用 window.api.chooseFolder() ipcRenderer.invoke('chooseFolder') 显示文件选择对话框 返回选择的路径 返回路径结果 返回 Promise 结果 更新 Redux 状态 渲染进程 预处理脚本 主进程 操作系统

核心实现流程

1. IPC 模块注册机制

// ipc/index.js
import setupGitIPC from './git'
import setupChooseFileIPC from './operateTheFile'

/**
 * 聚合所有 IPC 通信模块
 * 新增 IPC 模块需在此处引入并调用
 */
export async function setupIPC() {
  setupGitIPC()
  setupChooseFileIPC()
}
// main/index.js
import { setupIPC } from '../ipc'

app.whenReady().then(() => {
  setupIPC() // 注册所有 IPC 通信
  createWindow()
  // ...其他初始化逻辑
})

2. 文件选择器实现

// operateTheFile/index.js

/**
 * 系统级文件夹选择对话框
 * @returns {Promise<string|null>} 选择的文件夹路径
 */
const chooseFolder = async () => {
  const result = await dialog.showOpenDialog(mainWindow, {
    properties: ['openDirectory']
  })
  if (result.filePaths.length > 0) {
    return result.filePaths[0]
  }
}
const setupChooseFileIPC = () => {
  ipcMain.handle('chooseFolder', () => {
    return chooseFolder()
  })
}
3.预处理层暴露 API
import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'

// Custom APIs for renderer
const api = {
    /**
     * 打开文件夹选择对话框
     * @returns {Promise<string|null>}
     */
  chooseFolder: () => {
    return ipcRenderer.invoke('chooseFolder')
  }
}

4. 渲染进程调用示例

app.jsx中我们点击button按钮时会调用window.api.chooseFolder唤起原生文件选择器操作文件

function App() {
  const gitStroe = useSelector((state) => state.gitStore)
  const dispatch = useDispatch()
  const outlet = useRoutes(router)

  // 定义一个异步函数 setRepoPath,用于选择文件夹并设置仓库路径
  const setRepoPath = async () => {
    // 调用 window.api.chooseFolder() 弹出文件夹选择对话框,并等待用户选择文件夹
    const repoPath = await window.api.chooseFolder()
    // 检查 gitStroe.repoPaths 中是否已经包含选择的文件夹路径
    if (!gitStroe.repoPaths.some((item) => item.path === repoPath)) {
      // 如果不包含,则将选择的文件夹路径添加到 gitStroe.repoPaths 中,并更新仓库名称
      dispatch(
        setRepoPaths([...gitStroe.repoPaths, { path: repoPath, name: repoPath.split('/').pop() }])
      )
      // 设置当前仓库为选择的文件夹名称
      dispatch(setCurrentRepo(repoPath.split('/').pop()))
    }
  }


  return (
    <div className="app-container">
             ...
             ...
             // 点击按钮触发 setRepoPath 函数
            <Button
              icon={<DatabaseOutlined />}
              size="large"
              style={{ marginLeft: 20 }}
              onClick={setRepoPath}
            >
              Add Local Repository
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}

export default App

相关文章:

  • 安全测试数据的分析、报告及业务应用
  • LLM预训练过程-简明版本
  • 400. 第 N 位数字
  • ajax组件是什么
  • zerotier搭建免费moon服务器
  • 2.5 Spring Boot异常处理全局化:@ControllerAdvice实战
  • 刷leetcode hot100--动态规划3.12
  • RHCE大纲
  • std::ranges::views::reverse, std::ranges::reverse_view
  • 什么是 Java 的 SPI(Service Provider Interface)机制?
  • doris:外表统计信息
  • mock的定义和使用场景
  • LORA中 软提示是什么
  • LoRA,DoRA,RSLoRA,LoRA+ 是什么
  • STM32外部中断
  • 复现 MoGe
  • 计算机网络:Socket编程 Tcp协议 第二弹
  • 传智杯-省赛-第二场(B组)题解
  • 限制数据库字段长度的公用写法:length和like和rlike对于限制字段长度的原理与区别
  • 【技海登峰】Kafka漫谈系列(九)SpringBoot整合Kafka多数据源配置
  • 广东韶关一镇干部冲进交通事故火海救人,获授“见义勇为”奖励万元
  • 牧原股份子公司与养殖户种猪买卖纠纷案一审胜诉
  • 《审判》|“被告”的魅力:K在等什么?
  • 全国层面首次!《防震减灾基本知识与技能大纲》发布
  • 法院就“行人相撞案”道歉:执法公正,普法莫拉开“距离”
  • 卢正已任上海市司法局党委委员、副局长