From ebd1f3660cc2739805a6546ad4e207f74c8e30e8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 11 Jul 2024 10:06:50 +0200 Subject: [PATCH] disabled panel --- .../src/app/tabs/locales/en/electron.json | 4 +- .../src/app/tabs/locales/en/gitui.json | 3 + .../src/lib/plugins/filePanel-api.ts | 2 +- libs/remix-api/src/lib/plugins/fs-api.ts | 2 + libs/remix-ui/git/src/components/disabled.tsx | 32 +- libs/remix-ui/git/src/components/gitui.tsx | 15 +- libs/remix-ui/git/src/lib/listeners.ts | 23 +- libs/remix-ui/git/src/lib/pluginActions.ts | 7 + libs/remix-ui/git/src/state/actions.ts | 1 + libs/remix-ui/git/src/state/context.tsx | 1 + libs/remix-ui/git/src/state/gitpayload.ts | 7 + libs/remix-ui/git/src/state/gitreducer.tsx | 398 +++++++++--------- libs/remix-ui/git/src/types/index.ts | 13 +- 13 files changed, 291 insertions(+), 217 deletions(-) create mode 100644 apps/remix-ide/src/app/tabs/locales/en/gitui.json diff --git a/apps/remix-ide/src/app/tabs/locales/en/electron.json b/apps/remix-ide/src/app/tabs/locales/en/electron.json index cdf0a75a59..df81245b51 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/electron.json +++ b/apps/remix-ide/src/app/tabs/locales/en/electron.json @@ -1,4 +1,6 @@ { "electron.openFolder": "Open Folder", - "electron.recentFolders": "Recent Folders" + "electron.recentFolders": "Recent Folders", + "electron.gitClone": "Clone a Git Repository", + "electron.openFolderMessage": "In order to use Git features, you can open a folder or clone a repository." } \ No newline at end of file diff --git a/apps/remix-ide/src/app/tabs/locales/en/gitui.json b/apps/remix-ide/src/app/tabs/locales/en/gitui.json new file mode 100644 index 0000000000..eb793ed680 --- /dev/null +++ b/apps/remix-ide/src/app/tabs/locales/en/gitui.json @@ -0,0 +1,3 @@ +{ + "gitui.openFolderMessage": "In order to use Git features, you can open a folder or clone a repository." +} \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/filePanel-api.ts b/libs/remix-api/src/lib/plugins/filePanel-api.ts index 02255c26ba..53b0a7170d 100644 --- a/libs/remix-api/src/lib/plugins/filePanel-api.ts +++ b/libs/remix-api/src/lib/plugins/filePanel-api.ts @@ -7,6 +7,6 @@ export interface IFilePanelApi { switchToWorkspace: (workspace: string) => Promise; } & StatusEvents methods: IFilePanel['methods'] & { - + clone: () => Promise; } } diff --git a/libs/remix-api/src/lib/plugins/fs-api.ts b/libs/remix-api/src/lib/plugins/fs-api.ts index 3cded01b06..2488db988d 100644 --- a/libs/remix-api/src/lib/plugins/fs-api.ts +++ b/libs/remix-api/src/lib/plugins/fs-api.ts @@ -7,5 +7,7 @@ export interface IFs { methods: { selectFolder(path?: string, title?: string, button?: string): Promise openWindow(path?: string): Promise, + getWorkingDir(): Promise, + openFolderInSameWindow(path: string): Promise, } } \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/disabled.tsx b/libs/remix-ui/git/src/components/disabled.tsx index fbd54d6177..7825ee22df 100644 --- a/libs/remix-ui/git/src/components/disabled.tsx +++ b/libs/remix-ui/git/src/components/disabled.tsx @@ -1,12 +1,30 @@ -import React, { useEffect, useState } from 'react' +import { appPlatformTypes, platformContext } from '@remix-ui/app' +import React, { useEffect, useState, useContext } from 'react' +import { FormattedMessage } from "react-intl" +import { pluginActionsContext } from '../state/context' +import { openCloneDialog, openFolderInSameWindow } from '../lib/pluginActions' export const Disabled = () => { + const platform = useContext(platformContext) + + const openFolderElectron = async (path: string) => { + await openFolderInSameWindow(path) + } - return ( -
- Git is currently disabled.

- If you are using RemixD you can use git on the terminal.

-
- ) + const clone = async () => { + openCloneDialog() + } + return ( + (platform === appPlatformTypes.desktop) ? +
+
+
{ await openFolderElectron(null) }} className='btn btn-primary w-100 my-1'>
+
{ await clone() }} className='btn btn-primary w-100'>
+
+ : +
+ Git is currently disabled.

+ If you are using RemixD you can use git on the terminal.

+
) } \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/gitui.tsx b/libs/remix-ui/git/src/components/gitui.tsx index 7bfbc661cf..d3b3f5dd5c 100644 --- a/libs/remix-ui/git/src/components/gitui.tsx +++ b/libs/remix-ui/git/src/components/gitui.tsx @@ -1,7 +1,7 @@ -import React, { useEffect, useReducer, useState } from 'react' +import React, { useEffect, useReducer, useState, useContext } from 'react' import { add, addall, checkout, checkoutfile, clone, commit, createBranch, remoteBranches, repositories, rm, getCommitChanges, diff, resolveRef, getBranchCommits, setUpstreamRemote, loadGitHubUserFromToken, getBranches, getRemotes, remoteCommits, saveGitHubCredentials, getGitHubCredentialsFromLocalStorage, fetch, pull, push, setDefaultRemote, addRemote, removeRemote, sendToGitLog, clearGitLog, getBranchDifferences, getFileStatusMatrix, init, showAlert, gitlog } from '../lib/gitactions' import { loadFiles, setCallBacks } from '../lib/listeners' -import { openDiff, openFile, saveToken, setModifiedDecorator, setPlugin, setUntrackedDecorator, statusChanged } from '../lib/pluginActions' +import { openDiff, openFile, openFolderInSameWindow, saveToken, setModifiedDecorator, setPlugin, setUntrackedDecorator, statusChanged } from '../lib/pluginActions' import { gitActionsContext, pluginActionsContext } from '../state/context' import { gitReducer } from '../state/gitreducer' import { defaultGitState, defaultLoaderState, gitState, loaderState } from '../types' @@ -34,6 +34,7 @@ import { Init } from './panels/init' import { CustomRemixApi } from "@remix-api"; import { Plugin } from "@remixproject/engine"; import { Disabled } from './disabled' +import { platformContext } from '@remix-ui/app' export const gitPluginContext = React.createContext(defaultGitState) export const loaderContext = React.createContext(defaultLoaderState) @@ -51,6 +52,8 @@ export const GitUI = (props: IGitUi) => { const [needsInit, setNeedsInit] = useState(true) const [appLoaded, setAppLoaded] = useState(false) + const platform = useContext(platformContext) + useEffect(() => { plugin.emit('statusChanged', { key: 'loading', @@ -64,7 +67,7 @@ export const GitUI = (props: IGitUi) => { useEffect(() => { if (!appLoaded) return - setCallBacks(plugin, gitDispatch, loaderDispatch, setActivePanel) + setCallBacks(plugin, gitDispatch, loaderDispatch, setActivePanel, platform) setPlugin(plugin, gitDispatch, loaderDispatch) loaderDispatch({ type: 'plugin', payload: true }) @@ -159,11 +162,13 @@ export const GitUI = (props: IGitUi) => { saveToken, saveGitHubCredentials, getGitHubCredentialsFromLocalStorage, - showAlert + showAlert, + openFolderInSameWindow } return ( - <>{(!gitState.canUseApp) ? : + <>{(!gitState.canUseApp) ? + :
diff --git a/libs/remix-ui/git/src/lib/listeners.ts b/libs/remix-ui/git/src/lib/listeners.ts index 871458c8fb..682674e6f5 100644 --- a/libs/remix-ui/git/src/lib/listeners.ts +++ b/libs/remix-ui/git/src/lib/listeners.ts @@ -1,12 +1,13 @@ import React from "react"; -import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog, setGitHubUser, setUserEmails } from "../state/gitpayload"; +import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog, setGitHubUser, setUserEmails, setDesktopWorkingDir } from "../state/gitpayload"; import { gitActionDispatch } from "../types"; import { Plugin } from "@remixproject/engine"; import { getBranches, getFileStatusMatrix, loadGitHubUserFromToken, getRemotes, gitlog, setPlugin } from "./gitactions"; import { Profile } from "@remixproject/plugin-utils"; import { CustomRemixApi } from "@remix-api"; import { statusChanged } from "./pluginActions"; +import { appPlatformTypes } from "@remix-ui/app"; let plugin: Plugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch, loadFileQueue: AsyncDebouncedQueue let callBackEnabled: boolean = false @@ -20,7 +21,7 @@ class AsyncDebouncedQueue { this.queues = new Map(); } - enqueue(callback: AsyncCallback, customDelay?:number): void { + enqueue(callback: AsyncCallback, customDelay?: number): void { if (this.queues.has(callback)) { clearTimeout(this.queues.get(callback)!.timer); } @@ -34,7 +35,7 @@ class AsyncDebouncedQueue { } } -export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch, setAtivePanel: React.Dispatch>) => { +export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch, setAtivePanel: React.Dispatch>, platform: appPlatformTypes) => { plugin = viewPlugin gitDispatch = gitDispatcher loaderDispatch = loaderDispatcher @@ -65,7 +66,11 @@ export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch { + console.log('workingDirChanged', path) + gitDispatcher(setDesktopWorkingDir(path)) + gitDispatch(setCanUseApp(path ? true : false)) loadFileQueue.enqueue(async () => { loadFiles() }) @@ -79,8 +84,17 @@ export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch { - gitDispatch(setCanUseApp(x && !x.isLocalhost && x.name)) + console.log('setWorkspace', x) + + if(platform == appPlatformTypes.desktop) { + const workingDir = await plugin.call('fs', 'getWorkingDir') + gitDispatch(setCanUseApp(workingDir? true : false)) + }else{ + gitDispatch(setCanUseApp(x && !x.isLocalhost && x.name)) + } + loadFileQueue.enqueue(async () => { loadFiles() }) @@ -95,6 +109,7 @@ export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch { loadFileQueue.enqueue(async () => { gitlog() diff --git a/libs/remix-ui/git/src/lib/pluginActions.ts b/libs/remix-ui/git/src/lib/pluginActions.ts index 94d9d6bcf5..a13f1cca93 100644 --- a/libs/remix-ui/git/src/lib/pluginActions.ts +++ b/libs/remix-ui/git/src/lib/pluginActions.ts @@ -98,3 +98,10 @@ export const clearFileDecorator = async(path: string) => { await plugin.call('fileDecorator', 'clearFileDecorators', path) } +export const openFolderInSameWindow = async (path: string) => { + await plugin.call('fs', 'openFolderInSameWindow', path) +} + +export const openCloneDialog = async () => { + plugin.call('filePanel', 'clone') +} diff --git a/libs/remix-ui/git/src/state/actions.ts b/libs/remix-ui/git/src/state/actions.ts index 3c2049771d..ce1134a388 100644 --- a/libs/remix-ui/git/src/state/actions.ts +++ b/libs/remix-ui/git/src/state/actions.ts @@ -42,6 +42,7 @@ export interface ActionPayloadTypes { SET_LOG: gitLog CLEAR_LOG: void SET_USER_EMAILS: userEmails + DESKTOP_SET_WORKING_DIR: string } export interface Action { diff --git a/libs/remix-ui/git/src/state/context.tsx b/libs/remix-ui/git/src/state/context.tsx index ed58ac1a3f..f46ae5b7d7 100644 --- a/libs/remix-ui/git/src/state/context.tsx +++ b/libs/remix-ui/git/src/state/context.tsx @@ -55,6 +55,7 @@ export interface pluginActions { token: string }> showAlert({ title, message }:{title: string, message: string}): Promise + openFolderInSameWindow(path: string): Promise } export const pluginActionsContext = React.createContext(null) \ No newline at end of file diff --git a/libs/remix-ui/git/src/state/gitpayload.ts b/libs/remix-ui/git/src/state/gitpayload.ts index 338dbd017a..b07b5350aa 100644 --- a/libs/remix-ui/git/src/state/gitpayload.ts +++ b/libs/remix-ui/git/src/state/gitpayload.ts @@ -218,3 +218,10 @@ export const clearLog = () => { type: 'CLEAR_LOG' } } + +export const setDesktopWorkingDir = (dir: string) => { + return { + type: 'DESKTOP_SET_WORKING_DIR', + payload: dir + } +} diff --git a/libs/remix-ui/git/src/state/gitreducer.tsx b/libs/remix-ui/git/src/state/gitreducer.tsx index 1b41ffd43c..f9654e4a96 100644 --- a/libs/remix-ui/git/src/state/gitreducer.tsx +++ b/libs/remix-ui/git/src/state/gitreducer.tsx @@ -6,203 +6,209 @@ import { Actions } from "./actions" export const gitReducer = (state: gitState = defaultGitState, action: Actions): gitState => { switch (action.type) { - case 'FILE_STATUS': - return { - ...state, - fileStatusResult: action.payload, - staged: getFilesByStatus("staged", action.payload), - modified: getFilesByStatus("modified", action.payload), - untracked: getFilesByStatus("untracked", action.payload), - deleted: getFilesByStatus("deleted", action.payload), - allchangesnotstaged: allChangedButNotStagedFiles(action.payload) - } - - case 'FILE_STATUS_MERGE': - action.payload.map((fileStatusResult: fileStatusResult) => { - const file = state.fileStatusResult.find(stateFile => { - return stateFile.filename === fileStatusResult.filename + case 'FILE_STATUS': + return { + ...state, + fileStatusResult: action.payload, + staged: getFilesByStatus("staged", action.payload), + modified: getFilesByStatus("modified", action.payload), + untracked: getFilesByStatus("untracked", action.payload), + deleted: getFilesByStatus("deleted", action.payload), + allchangesnotstaged: allChangedButNotStagedFiles(action.payload) + } + + case 'FILE_STATUS_MERGE': + action.payload.map((fileStatusResult: fileStatusResult) => { + const file = state.fileStatusResult.find(stateFile => { + return stateFile.filename === fileStatusResult.filename + }) + if (file) { + file.status = fileStatusResult.status + file.statusNames = fileStatusResult.statusNames + } + }) + + return { + ...state, + staged: getFilesByStatus("staged", state.fileStatusResult), + modified: getFilesByStatus("modified", state.fileStatusResult), + untracked: getFilesByStatus("untracked", state.fileStatusResult), + deleted: getFilesByStatus("deleted", state.fileStatusResult), + allchangesnotstaged: allChangedButNotStagedFiles(state.fileStatusResult) + } + + case 'SET_COMMITS': + return { + ...state, + commits: action.payload, + localCommitCount: action.payload.length + } + + case 'SET_BRANCHES': + return { + ...state, + branches: action.payload + } + + case 'SET_CURRENT_BRANCH': + return { + ...state, + currentBranch: action.payload + } + + case 'SET_CURRENT_HEAD': + return { + ...state, + currentHead: action.payload + } + + case 'SET_CAN_USE_APP': + return { + ...state, + canUseApp: action.payload + } + case 'SET_REPO_NAME': + return { + ...state, + reponame: action.payload + } + case 'SET_LOADING': + return { + ...state, + loading: action.payload + } + + case 'SET_REPOS': + return { + ...state, + repositories: action.payload + } + + case 'SET_REMOTE_BRANCHES': + return { + ...state, + remoteBranches: action.payload + } + + case 'SET_CAN_COMMIT': + return { + ...state, + canCommit: action.payload + } + + case 'SET_REMOTES': + return { + ...state, + remotes: action.payload + } + + case 'SET_UPSTREAM': + return { + ...state, + upstream: action.payload + } + + case 'SET_COMMIT_CHANGES': + + action.payload.forEach((change: commitChange) => { + state.commitChanges.find((c) => c.hashModified === change.hashModified && c.hashOriginal === change.hashOriginal && c.path === change.path) ? null : state.commitChanges.push(change) }) - if (file) { - file.status = fileStatusResult.status - file.statusNames = fileStatusResult.statusNames - } - }) - - return { - ...state, - staged: getFilesByStatus("staged", state.fileStatusResult), - modified: getFilesByStatus("modified", state.fileStatusResult), - untracked: getFilesByStatus("untracked", state.fileStatusResult), - deleted: getFilesByStatus("deleted", state.fileStatusResult), - allchangesnotstaged: allChangedButNotStagedFiles(state.fileStatusResult) - } - - case 'SET_COMMITS': - return { - ...state, - commits: action.payload, - localCommitCount: action.payload.length - } - - case 'SET_BRANCHES': - return { - ...state, - branches: action.payload - } - - case 'SET_CURRENT_BRANCH': - return { - ...state, - currentBranch: action.payload - } - - case 'SET_CURRENT_HEAD': - return { - ...state, - currentHead: action.payload - } - - case 'SET_CAN_USE_APP': - return { - ...state, - canUseApp: action.payload - } - case 'SET_REPO_NAME': - return { - ...state, - reponame: action.payload - } - case 'SET_LOADING': - return { - ...state, - loading: action.payload - } - - case 'SET_REPOS': - return { - ...state, - repositories: action.payload - } - - case 'SET_REMOTE_BRANCHES': - return { - ...state, - remoteBranches: action.payload - } - - case 'SET_CAN_COMMIT': - return { - ...state, - canCommit: action.payload - } - - case 'SET_REMOTES': - return { - ...state, - remotes: action.payload - } - - case 'SET_UPSTREAM': - return { - ...state, - upstream: action.payload - } - - case 'SET_COMMIT_CHANGES': - - action.payload.forEach((change: commitChange) => { - state.commitChanges.find((c) => c.hashModified === change.hashModified && c.hashOriginal === change.hashOriginal && c.path === change.path) ? null : state.commitChanges.push(change) - }) - - return { - ...state, - commitChanges: [...state.commitChanges] - } - - case 'RESET_REMOTE_BRANCH_COMMITS': - if (state.remoteBranchCommits[action.payload.branch.name]) { - delete state.remoteBranchCommits[action.payload.branch.name] - } - return { - ...state, - remoteBranchCommits: { ...state.remoteBranchCommits } - } - - case 'SET_REMOTE_BRANCH_COMMITS': - if (state.remoteBranchCommits[action.payload.branch.name]) { - state.remoteBranchCommits[action.payload.branch.name].push(...action.payload.commits) - } else { - state.remoteBranchCommits[action.payload.branch.name] = action.payload.commits - } - return { - ...state, - remoteBranchCommits: { ...state.remoteBranchCommits } - } - - case 'SET_LOCAL_BRANCH_COMMITS': - - state.localBranchCommits[action.payload.branch.name] = action.payload.commits - return { - ...state, - localBranchCommits: { ...state.localBranchCommits } - } - - case 'SET_BRANCH_DIFFERENCES': - - state.branchDifferences[`${action.payload.remote.name}/${action.payload.branch.name}`] = action.payload.branchDifference - - return { - ...state, - branchDifferences: { ...state.branchDifferences } - } - - case 'SET_GITHUB_USER': - return { - ...state, - gitHubUser: action.payload - } - - case 'SET_GITHUB_ACCESS_TOKEN': - return { - ...state, - gitHubAccessToken: action.payload - } - - case 'SET_SCOPES': - return { - ...state, - gitHubScopes: action.payload - } - - case 'SET_USER_EMAILS': - return { - ...state, - userEmails: action.payload - } - - case 'SET_DEFAULT_REMOTE': - return { - ...state, - defaultRemote: action.payload - } - - case 'SET_LOG': - if (state.log.length > 0 && state.log[[...state.log].length - 1].message === action.payload.message) { - return { - ...state, - log: [...state.log] - } - } - return { - ...state, - log: [...state.log, action.payload] - } - - case 'CLEAR_LOG': - return { - ...state, - log: [] - } + return { + ...state, + commitChanges: [...state.commitChanges] + } + + case 'RESET_REMOTE_BRANCH_COMMITS': + if (state.remoteBranchCommits[action.payload.branch.name]) { + delete state.remoteBranchCommits[action.payload.branch.name] + } + return { + ...state, + remoteBranchCommits: { ...state.remoteBranchCommits } + } + + case 'SET_REMOTE_BRANCH_COMMITS': + if (state.remoteBranchCommits[action.payload.branch.name]) { + state.remoteBranchCommits[action.payload.branch.name].push(...action.payload.commits) + } else { + state.remoteBranchCommits[action.payload.branch.name] = action.payload.commits + } + return { + ...state, + remoteBranchCommits: { ...state.remoteBranchCommits } + } + + case 'SET_LOCAL_BRANCH_COMMITS': + + state.localBranchCommits[action.payload.branch.name] = action.payload.commits + return { + ...state, + localBranchCommits: { ...state.localBranchCommits } + } + + case 'SET_BRANCH_DIFFERENCES': + + state.branchDifferences[`${action.payload.remote.name}/${action.payload.branch.name}`] = action.payload.branchDifference + + return { + ...state, + branchDifferences: { ...state.branchDifferences } + } + + case 'SET_GITHUB_USER': + return { + ...state, + gitHubUser: action.payload + } + + case 'SET_GITHUB_ACCESS_TOKEN': + return { + ...state, + gitHubAccessToken: action.payload + } + + case 'SET_SCOPES': + return { + ...state, + gitHubScopes: action.payload + } + + case 'SET_USER_EMAILS': + return { + ...state, + userEmails: action.payload + } + + case 'SET_DEFAULT_REMOTE': + return { + ...state, + defaultRemote: action.payload + } + + case 'SET_LOG': + if (state.log.length > 0 && state.log[[...state.log].length - 1].message === action.payload.message) { + return { + ...state, + log: [...state.log] + } + } + return { + ...state, + log: [...state.log, action.payload] + } + + case 'CLEAR_LOG': + return { + ...state, + log: [] + } + + + case 'DESKTOP_SET_WORKING_DIR': + return { + ...state, + desktopWorkingDir: action.payload + } } } \ No newline at end of file diff --git a/libs/remix-ui/git/src/types/index.ts b/libs/remix-ui/git/src/types/index.ts index efe0553066..b3b4de928d 100644 --- a/libs/remix-ui/git/src/types/index.ts +++ b/libs/remix-ui/git/src/types/index.ts @@ -38,6 +38,7 @@ export type gitState = { gitHubScopes: string[] gitHubAccessToken: string log: gitLog[] + desktopWorkingDir?: string } export type gitLog = { type: 'error' | 'warning' | 'info' | 'success', @@ -69,7 +70,7 @@ export const defaultGitState: gitState = { deleted: [], modified: [], allchangesnotstaged: [], - canUseApp: true, + canUseApp: false, loading: false, storageUsed: {}, reponame: "", @@ -87,7 +88,8 @@ export const defaultGitState: gitState = { userEmails: [] as userEmails, gitHubScopes: [], gitHubAccessToken: "", - log: [] + log: [], + desktopWorkingDir: null } export const defaultLoaderState: loaderState = { @@ -222,4 +224,9 @@ export interface clearLogAction { type: string } -export type gitActionDispatch = setCurrentHeadAction | clearLogAction | setLogAction | setDefaultRemoteAction | setTokenAction | setUpstreamAction | setRemoteBranchCommitsAction | setLocalBranchCommitsAction | setBranchDifferencesAction | setRemotesAction | setCurrentBranchAction | fileStatusAction | setLoadingAction | setCanUseAppAction | setRepoNameAction | setCommitsAction | setBranchesAction | setReposAction | setRemoteBranchesAction \ No newline at end of file +export interface setDesktopWorkingDirAction { + type: string, + payload: string +} + +export type gitActionDispatch = setDesktopWorkingDirAction | setCurrentHeadAction | clearLogAction | setLogAction | setDefaultRemoteAction | setTokenAction | setUpstreamAction | setRemoteBranchCommitsAction | setLocalBranchCommitsAction | setBranchDifferencesAction | setRemotesAction | setCurrentBranchAction | fileStatusAction | setLoadingAction | setCanUseAppAction | setRepoNameAction | setCommitsAction | setBranchesAction | setReposAction | setRemoteBranchesAction \ No newline at end of file