git4refactor
filip mertens 6 months ago
parent 36ec094dd4
commit 353b5670ad
  1. 3
      libs/remix-ui/git/src/components/buttons/commitmessage.tsx
  2. 6
      libs/remix-ui/git/src/components/gitui.tsx
  3. 8
      libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx
  4. 12
      libs/remix-ui/git/src/components/panels/branches.tsx
  5. 53
      libs/remix-ui/git/src/lib/gitactions.ts
  6. 113
      libs/remix-ui/git/src/lib/listeners.ts
  7. 4
      libs/remix-ui/git/src/state/context.tsx
  8. 2
      libs/remix-ui/workspace/src/lib/actions/workspace.ts

@ -33,8 +33,9 @@ export const CommitMessage = () => {
const commit = async() => { const commit = async() => {
if (context.staged.length === 0 && context.allchangesnotstaged.length == 0) return if (context.staged.length === 0 && context.allchangesnotstaged.length == 0) return
if (context.staged.length === 0) if (context.staged.length === 0)
await actions.addall() await actions.addall(context.allchangesnotstaged)
await actions.commit(message.value) await actions.commit(message.value)
setMessage({ value: '' })
} }
const getRemote = () => { const getRemote = () => {

@ -29,6 +29,8 @@ import LogViewer from './panels/log'
import { SourceControlBase } from './buttons/sourceControlBase' import { SourceControlBase } from './buttons/sourceControlBase'
import { BranchHeader } from './branchHeader' import { BranchHeader } from './branchHeader'
import { SourceControl } from './panels/sourcontrol' import { SourceControl } from './panels/sourcontrol'
import { Settings } from './panels/settings'
import { GitHubCredentials } from './panels/githubcredentials'
export const gitPluginContext = React.createContext<gitState>(defaultGitState) export const gitPluginContext = React.createContext<gitState>(defaultGitState)
export const loaderContext = React.createContext<loaderState>(defaultLoaderState) export const loaderContext = React.createContext<loaderState>(defaultLoaderState)
@ -157,7 +159,7 @@ export const GitUI = (props: IGitUi) => {
<BranchesNavigation eventKey="2" activePanel={activePanel} callback={setActivePanel} /> <BranchesNavigation eventKey="2" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="2"> <Accordion.Collapse className='bg-light' eventKey="2">
<> <>
<Branches /></> <Branches isOpen={activePanel === '2'} /></>
</Accordion.Collapse> </Accordion.Collapse>
<hr></hr> <hr></hr>
<RemotesNavigation eventKey="5" activePanel={activePanel} callback={setActivePanel} /> <RemotesNavigation eventKey="5" activePanel={activePanel} callback={setActivePanel} />
@ -177,6 +179,8 @@ export const GitUI = (props: IGitUi) => {
<Accordion.Collapse className='bg-light' eventKey="7"> <Accordion.Collapse className='bg-light' eventKey="7">
<> <>
<GetDeviceCode></GetDeviceCode> <GetDeviceCode></GetDeviceCode>
<hr></hr>
<GitHubCredentials></GitHubCredentials>
</> </>
</Accordion.Collapse> </Accordion.Collapse>
<hr></hr> <hr></hr>

@ -5,6 +5,7 @@ import React, { useContext, useEffect } from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { gitActionsContext, pluginActionsContext } from "../../state/context"; import { gitActionsContext, pluginActionsContext } from "../../state/context";
import { sourceControlGroup } from "../../types"; import { sourceControlGroup } from "../../types";
import { gitPluginContext } from "../gitui";
interface SourceControlGroupNavigationProps { interface SourceControlGroupNavigationProps {
eventKey: string; eventKey: string;
@ -17,6 +18,7 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation
const { eventKey, activePanel, callback, group } = props; const { eventKey, activePanel, callback, group } = props;
const actions = React.useContext(gitActionsContext) const actions = React.useContext(gitActionsContext)
const pluginActions = React.useContext(pluginActionsContext) const pluginActions = React.useContext(pluginActionsContext)
const context = React.useContext(gitPluginContext)
const handleClick = () => { const handleClick = () => {
if (!callback) return if (!callback) return
if (activePanel === eventKey) { if (activePanel === eventKey) {
@ -39,11 +41,7 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation
<span className='d-flex justify-content-end align-items-center w-25'> <span className='d-flex justify-content-end align-items-center w-25'>
{group.name === 'Changes' ? {group.name === 'Changes' ?
<CustomTooltip tooltipText={<FormattedMessage id="git.stageall" />}> <CustomTooltip tooltipText={<FormattedMessage id="git.stageall" />}>
<button onClick={async () => { await actions.addall() }} className='btn btn-sm'><FontAwesomeIcon icon={faPlus} className="" /></button> <button onClick={async () => { await actions.addall(context.allchangesnotstaged) }} className='btn btn-sm'><FontAwesomeIcon icon={faPlus} className="" /></button>
</CustomTooltip>: null}
{group.name === 'Staged' ?
<CustomTooltip tooltipText={<FormattedMessage id="git.unstageall" />}>
<button onClick={async () => { await pluginActions.loadFiles() }} className='btn btn-sm'><FontAwesomeIcon icon={faMinus} className="" /></button>
</CustomTooltip>: null} </CustomTooltip>: null}
</span> : null </span> : null

@ -7,7 +7,11 @@ import { gitPluginContext } from "../gitui";
import { LocalBranchDetails } from "./branches/localbranchdetails"; import { LocalBranchDetails } from "./branches/localbranchdetails";
import { RemoteBranchDetails } from "./branches/remotebranchedetails"; import { RemoteBranchDetails } from "./branches/remotebranchedetails";
export const Branches = () => { interface BranchesProps {
isOpen: boolean;
}
export const Branches = ({isOpen}: BranchesProps) => {
const context = React.useContext(gitPluginContext) const context = React.useContext(gitPluginContext)
const actions = React.useContext(gitActionsContext) const actions = React.useContext(gitActionsContext)
const [newBranch, setNewBranch] = useState({ value: "" }); const [newBranch, setNewBranch] = useState({ value: "" });
@ -24,6 +28,12 @@ export const Branches = () => {
} }
}; };
useEffect(() => {
console.log("open branches", context.branches)
//if(context.branches && context.branches.length) return
//actions.getBranches()
},[isOpen])
useEffect(() => { useEffect(() => {
console.log("branches", context.branches) console.log("branches", context.branches)
},[context.branches]) },[context.branches])

@ -2,7 +2,7 @@ import { ViewPlugin } from "@remixproject/engine-web";
import { ReadBlobResult, ReadCommitResult } from "isomorphic-git"; import { ReadBlobResult, ReadCommitResult } from "isomorphic-git";
import React from "react"; import React from "react";
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog } from "../state/gitpayload"; import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog } from "../state/gitpayload";
import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog } from '../types'; import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog, fileStatusResult } from '../types';
import { removeSlash } from "../utils"; import { removeSlash } from "../utils";
import { disableCallBacks, enableCallBacks } from "./listeners"; import { disableCallBacks, enableCallBacks } from "./listeners";
import { AlertModal, ModalTypes } from "@remix-ui/app"; import { AlertModal, ModalTypes } from "@remix-ui/app";
@ -229,7 +229,11 @@ export const commit = async (message: string = "") => {
}, },
message: message, message: message,
}); });
plugin.call('notification', 'toast', `Commited: ${sha}`)
sendToGitLog({
type:'success',
message: `Commited: ${sha}`
})
} catch (err) { } catch (err) {
plugin.call('notification', 'toast', `${err}`) plugin.call('notification', 'toast', `${err}`)
@ -237,24 +241,19 @@ export const commit = async (message: string = "") => {
} }
export const addall = async () => { export const addall = async (files: fileStatusResult[]) => {
try { try {
await plugin console.log('addall', files.map(f => removeSlash(f.filename)))
.call("dGitProvider", "status", { ref: "HEAD" }) const filesToAdd = files.map(f => removeSlash(f.filename))
.then((status) => try {
Promise.all( await plugin.call("dGitProvider", "add", {
status.map(([filepath, , worktreeStatus]) => filepath: filesToAdd,
worktreeStatus });
? plugin.call("dGitProvider", "add", { } catch (e) { }
filepath: removeSlash(filepath), sendToGitLog({
}) type:'success',
: plugin.call("dGitProvider", "rm", { message: `Added all files to git`
filepath: removeSlash(filepath),
}) })
)
)
);
plugin.call('notification', 'toast', `Added all files to git`)
} catch (e) { } catch (e) {
plugin.call('notification', 'toast', `${e}`) plugin.call('notification', 'toast', `${e}`)
@ -269,7 +268,7 @@ export const add = async (args: string | undefined) => {
filename = removeSlash(filename); filename = removeSlash(filename);
stagingfiles = [filename]; stagingfiles = [filename];
} else { } else {
await addall(); //await addall();
return; return;
} }
try { try {
@ -280,7 +279,10 @@ export const add = async (args: string | undefined) => {
}); });
} catch (e) { } } catch (e) { }
} }
plugin.call('notification', 'toast', `Added ${filename} to git`); sendToGitLog({
type:'success',
message: `Added ${filename} to git`
})
} catch (e) { } catch (e) {
plugin.call('notification', 'toast', `${e}`) plugin.call('notification', 'toast', `${e}`)
} }
@ -302,7 +304,10 @@ export const rm = async (args: any) => {
await plugin.call("dGitProvider", "rm", { await plugin.call("dGitProvider", "rm", {
filepath: removeSlash(filename), filepath: removeSlash(filename),
}); });
plugin.call('notification', 'toast', `Removed ${filename} from git`) sendToGitLog({
type:'success',
message: `Removed ${filename} from git`
})
} }
export const checkoutfile = async (filename: string) => { export const checkoutfile = async (filename: string) => {
@ -364,7 +369,11 @@ export const clone = async (url: string, branch: string, depth: number, singleBr
//} else { //} else {
await plugin.call('dGitProvider' as any, 'clone', { url, branch, token, depth, singleBranch }, repoNameWithTimestamp); await plugin.call('dGitProvider' as any, 'clone', { url, branch, token, depth, singleBranch }, repoNameWithTimestamp);
await enableCallBacks() await enableCallBacks()
plugin.call('notification', 'toast', `Cloned ${url} to ${repoNameWithTimestamp}`)
sendToGitLog({
type:'success',
message: `Cloned ${url} to ${repoNameWithTimestamp}`
})
//} //}
} catch (e: any) { } catch (e: any) {
await parseError(e) await parseError(e)

@ -5,36 +5,65 @@ import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog } from ".
import { gitActionDispatch } from "../types"; import { gitActionDispatch } from "../types";
import { diffFiles, getBranches, getFileStatusMatrix, getGitHubUser, getRemotes, gitlog, setPlugin } from "./gitactions"; import { diffFiles, getBranches, getFileStatusMatrix, getGitHubUser, getRemotes, gitlog, setPlugin } from "./gitactions";
let plugin: ViewPlugin, gitDispatch: React.Dispatch<gitActionDispatch>, loaderDispatch: React.Dispatch<any> let plugin: ViewPlugin, gitDispatch: React.Dispatch<gitActionDispatch>, loaderDispatch: React.Dispatch<any>, loadFileQueue: AsyncDebouncedQueue
let callBackEnabled: boolean = false let callBackEnabled: boolean = false
let syncTimer: NodeJS.Timer = null let syncTimer: NodeJS.Timer = null
type AsyncCallback = () => Promise<void>;
class AsyncDebouncedQueue {
private queues: Map<AsyncCallback, { timer: any, lastCall: number }>;
constructor(private delay: number = 300) {
this.queues = new Map();
}
enqueue(callback: AsyncCallback, customDelay?:number): void {
if (this.queues.has(callback)) {
clearTimeout(this.queues.get(callback)!.timer);
}
let timer = setTimeout(async () => {
await callback(); // Await the asynchronous operation
this.queues.delete(callback);
}, customDelay || this.delay);
this.queues.set(callback, { timer, lastCall: Date.now() });
}
}
export const setCallBacks = (viewPlugin: ViewPlugin, gitDispatcher: React.Dispatch<gitActionDispatch>, loaderDispatcher: React.Dispatch<any>) => { export const setCallBacks = (viewPlugin: ViewPlugin, gitDispatcher: React.Dispatch<gitActionDispatch>, loaderDispatcher: React.Dispatch<any>) => {
plugin = viewPlugin plugin = viewPlugin
gitDispatch = gitDispatcher gitDispatch = gitDispatcher
loaderDispatch = loaderDispatcher loaderDispatch = loaderDispatcher
loadFileQueue = new AsyncDebouncedQueue()
setPlugin(viewPlugin, gitDispatcher) setPlugin(viewPlugin, gitDispatcher)
plugin.on("fileManager", "fileSaved", async (file: string) => { plugin.on("fileManager", "fileSaved", async (file: string) => {
console.log(file) console.log(file)
loadFiles([file]) loadFileQueue.enqueue(async () => {
//await synTimerStart(); loadFiles()
})
}); });
plugin.on('dGitProvider', 'checkout' as any, async () => { plugin.on('dGitProvider', 'checkout' as any, async () => {
await synTimerStart(); //await synTimerStart();
}) })
plugin.on('dGitProvider', 'branch' as any, async () => { plugin.on('dGitProvider', 'branch' as any, async () => {
await synTimerStart(); //await synTimerStart();
}) })
plugin.on("fileManager", "fileAdded", async (e) => { plugin.on("fileManager", "fileAdded", async (e) => {
await synTimerStart(); loadFileQueue.enqueue(async () => {
loadFiles()
})
}); });
plugin.on("fileManager", "fileRemoved", async (e) => { plugin.on("fileManager", "fileRemoved", async (e) => {
await synTimerStart(); //await synTimerStart();
}); });
plugin.on("fileManager", "currentFileChanged", async (e) => { plugin.on("fileManager", "currentFileChanged", async (e) => {
@ -43,53 +72,71 @@ export const setCallBacks = (viewPlugin: ViewPlugin, gitDispatcher: React.Dispat
}); });
plugin.on("fileManager", "fileRenamed", async (oldfile, newfile) => { plugin.on("fileManager", "fileRenamed", async (oldfile, newfile) => {
await synTimerStart(); //await synTimerStart();
}); });
plugin.on("filePanel", "setWorkspace", async (x: any) => { plugin.on("filePanel", "setWorkspace", async (x: any) => {
await synTimerStart(); loadFileQueue.enqueue(async () => {
loadFiles()
})
loadFileQueue.enqueue(async () => {
gitlog()
})
loadFileQueue.enqueue(async () => {
getBranches()
})
loadFileQueue.enqueue(async () => {
getRemotes()
})
}); });
plugin.on("filePanel", "deleteWorkspace" as any, async (x: any) => { plugin.on("filePanel", "deleteWorkspace" as any, async (x: any) => {
await synTimerStart(); //await synTimerStart();
}); });
plugin.on("filePanel", "renameWorkspace" as any, async (x: any) => { plugin.on("filePanel", "renameWorkspace" as any, async (x: any) => {
await synTimerStart(); //await synTimerStart();
}); });
plugin.on('dGitProvider', 'checkout', async () => { plugin.on('dGitProvider', 'checkout', async () => {
await loadFiles();
}) })
plugin.on('dGitProvider', 'init', async () => { plugin.on('dGitProvider', 'init', async () => {
await loadFiles();
}) })
plugin.on('dGitProvider', 'add', async () => { plugin.on('dGitProvider', 'add', async () => {
await loadFiles(); loadFileQueue.enqueue(async () => {
loadFiles()
}, 10)
}) })
plugin.on('dGitProvider', 'rm', async () => { plugin.on('dGitProvider', 'rm', async () => {
await loadFiles(); loadFileQueue.enqueue(async () => {
loadFiles()
}, 10)
}) })
plugin.on('dGitProvider', 'commit', async () => { plugin.on('dGitProvider', 'commit', async () => {
loadFileQueue.enqueue(async () => {
gitlog()
}, 10)
gitDispatch(setLog({ gitDispatch(setLog({
message: 'Committed changes...', message: 'Committed changes...',
type: 'success' type: 'success'
})) }))
await loadFiles();
}) })
plugin.on('dGitProvider', 'branch', async () => { plugin.on('dGitProvider', 'branch', async () => {
gitDispatch(setLog({ gitDispatch(setLog({
message: "Created Branch", message: "Created Branch",
type: "success" type: "success"
})) }))
await loadFiles();
}) })
plugin.on('dGitProvider', 'clone', async () => { plugin.on('dGitProvider', 'clone', async () => {
gitDispatch(setLog({ gitDispatch(setLog({
message: "Cloned Repository", message: "Cloned Repository",
type: "success" type: "success"
})) }))
await loadFiles(); loadFileQueue.enqueue(async () => {
loadFiles()
})
}) })
plugin.on('manager', 'pluginActivated', async (p: Plugin) => { plugin.on('manager', 'pluginActivated', async (p: Plugin) => {
if (p.name === 'dGitProvider') { if (p.name === 'dGitProvider') {
@ -117,7 +164,7 @@ export const getGitConfig = async () => {
return config return config
} }
const syncFromWorkspace = async (isLocalhost = false) => { const syncFromWorkspace = async (callback: Function, isLocalhost = false) => {
//gitDispatch(setLoading(true)); //gitDispatch(setLoading(true));
await disableCallBacks(); await disableCallBacks();
if (isLocalhost) { if (isLocalhost) {
@ -142,35 +189,17 @@ const syncFromWorkspace = async (isLocalhost = false) => {
} catch (e) { } catch (e) {
gitDispatch(setCanUseApp(false)); gitDispatch(setCanUseApp(false));
} }
await loadFiles(); await callback();
await enableCallBacks(); await enableCallBacks();
} }
export const loadFiles = async (filepaths: string[] = null) => { export const loadFiles = async (filepaths: string[] = null) => {
//gitDispatch(setLoading(true));
try { try {
await getFileStatusMatrix(filepaths); await getFileStatusMatrix(filepaths);
} catch (e) { } catch (e) {
// TODO: handle error // TODO: handle error
console.error(e); console.error(e);
} }
try {
await gitlog();
} catch (e) { }
try {
await getBranches();
} catch (e) { }
try {
await getRemotes();
} catch (e) { }
try {
//await getStorageUsed();
} catch (e) { }
try {
//await diffFiles('');
} catch (e) { }
//gitDispatch(setLoading(false));
} }
const getStorageUsed = async () => { const getStorageUsed = async () => {
@ -192,11 +221,3 @@ export const enableCallBacks = async () => {
callBackEnabled = true; callBackEnabled = true;
} }
const synTimerStart = async () => {
//console.trace('synTimerStart')
if (!callBackEnabled) return
clearTimeout(syncTimer)
syncTimer = setTimeout(async () => {
await syncFromWorkspace();
}, 1000)
}

@ -1,6 +1,6 @@
import { ReadCommitResult } from "isomorphic-git" import { ReadCommitResult } from "isomorphic-git"
import React from "react" import React from "react"
import { branch, commitChange, gitLog, gitState, remote } from "../types" import { branch, commitChange, fileStatusResult, gitLog, gitState, remote } from "../types"
export interface gitActions { export interface gitActions {
removeRemote(remote: remote): void removeRemote(remote: remote): void
@ -8,7 +8,7 @@ export interface gitActions {
add(path: string): Promise<void> add(path: string): Promise<void>
rm(path: string): Promise<void> rm(path: string): Promise<void>
commit(message: string): Promise<any> commit(message: string): Promise<any>
addall(): Promise<void> addall(files: fileStatusResult[]): Promise<void>
push(remote?: string, ref?: string, remoteRef?: string, force?: boolean): Promise<void> push(remote?: string, ref?: string, remoteRef?: string, force?: boolean): Promise<void>
pull(remote?: string, ref?: string, remoteRef?: string): Promise<void> pull(remote?: string, ref?: string, remoteRef?: string): Promise<void>
fetch(remote?: string, ref?: string, remoteRef?: string, depth?: number, singleBranch?: boolean, relative?: boolean, quiet?: boolean): Promise<void> fetch(remote?: string, ref?: string, remoteRef?: string, depth?: number, singleBranch?: boolean, relative?: boolean, quiet?: boolean): Promise<void>

@ -754,7 +754,7 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => {
dir: addSlash(workspaceName), dir: addSlash(workspaceName),
} }
const currentBranch: branch = await plugin.call('dGitProvider', 'currentbranch', { ...gitConfig }) const currentBranch: branch = await plugin.call('dGitProvider', 'currentbranch', { ...gitConfig })
return currentBranch.name return currentBranch && currentBranch.name
} }
export const showAllBranches = async () => { export const showAllBranches = async () => {

Loading…
Cancel
Save